@growth-operations/ui-shared 1.37.2 → 1.37.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/home/AppHome.jsx +23 -14
- package/src/home/HealthHero.jsx +21 -0
- package/src/lib/creditDisplay.js +5 -4
package/package.json
CHANGED
package/src/home/AppHome.jsx
CHANGED
|
@@ -91,6 +91,13 @@ export function AppHome({ state, onNavigate, appName, onRetry, helpfulLinks, usa
|
|
|
91
91
|
|
|
92
92
|
const onboardingComplete = state.onboarding?.complete === true;
|
|
93
93
|
|
|
94
|
+
// Legacy (Anvil-billed) installs: hide the period chart entirely. The
|
|
95
|
+
// periods-mode usage endpoint returns an EMPTY series for legacy by design
|
|
96
|
+
// (no Anvil stripe_usage reconstruction in usage_periods.py), so the
|
|
97
|
+
// explorer would render a misleading "No usage in this window" while the
|
|
98
|
+
// Usage tab's days mode shows real activity (USLS, 2026-11-12).
|
|
99
|
+
const isLegacy = state.entitlement?.mode === "legacy";
|
|
100
|
+
|
|
94
101
|
// FeatureUsage gate: render once every NON-BILLING onboarding step is done.
|
|
95
102
|
// Every registry app marks its Choose-a-plan step paid-gated (key "plan",
|
|
96
103
|
// routing to /billing, done only once the subscription is ACTIVE), so gating
|
|
@@ -137,20 +144,22 @@ export function AppHome({ state, onNavigate, appName, onRetry, helpfulLinks, usa
|
|
|
137
144
|
state ("No usage in this window") is the right thing to show there,
|
|
138
145
|
not nothing. The paid-step trap this gate grew out of (Andrew
|
|
139
146
|
2026-11-11) is moot once there's no gate. FeatureUsage below keeps
|
|
140
|
-
the setupStepsComplete gate.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
147
|
+
the setupStepsComplete gate. ONE exception: legacy installs skip
|
|
148
|
+
the chart (see isLegacy above). */}
|
|
149
|
+
{!isLegacy &&
|
|
150
|
+
(usageExplorer ? (
|
|
151
|
+
<BillingPeriodUsage
|
|
152
|
+
context={usageExplorer.context}
|
|
153
|
+
basePath={usageExplorer.basePath}
|
|
154
|
+
portalId={usageExplorer.portalId}
|
|
155
|
+
appName={appName}
|
|
156
|
+
title="Usage over time"
|
|
157
|
+
titleAs="text"
|
|
158
|
+
showStats={false}
|
|
159
|
+
/>
|
|
160
|
+
) : (
|
|
161
|
+
<PeriodComparison state={state} />
|
|
162
|
+
))}
|
|
154
163
|
|
|
155
164
|
{/* Most used / recommended-to-explore (state.feature_usage) — renders
|
|
156
165
|
nothing on backends without the block or for legacy installs. Gated
|
package/src/home/HealthHero.jsx
CHANGED
|
@@ -112,6 +112,27 @@ export function HealthHero({ appName, state }) {
|
|
|
112
112
|
);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
// Legacy (Anvil-billed) install — the calm hero matching BillingTab's
|
|
116
|
+
// LegacyBilling panel. MUST come before the status fallback below:
|
|
117
|
+
// "legacy" is not in STATUS_LABELS/STATUS_VARIANT, so it would render the
|
|
118
|
+
// literal word "legacy" as the banner title (USLS portal 4064313,
|
|
119
|
+
// 2026-11-12 — reads like a debug string to a paying customer).
|
|
120
|
+
if (ent.mode === "legacy") {
|
|
121
|
+
return (
|
|
122
|
+
<Flex direction="column" gap="small">
|
|
123
|
+
{name && <Heading>{name}</Heading>}
|
|
124
|
+
<Alert title="Managed through your existing subscription" variant="info">
|
|
125
|
+
<Box flex="auto">
|
|
126
|
+
<Text>
|
|
127
|
+
Your plan and payment method are billed through your existing
|
|
128
|
+
subscription. There's nothing to set up here.
|
|
129
|
+
</Text>
|
|
130
|
+
</Box>
|
|
131
|
+
</Alert>
|
|
132
|
+
</Flex>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
115
136
|
// trial_subscription (and any other status-bearing arm).
|
|
116
137
|
return (
|
|
117
138
|
<Flex direction="column" gap="small">
|
package/src/lib/creditDisplay.js
CHANGED
|
@@ -383,7 +383,7 @@ function trialStateOf(ent, { appName } = {}) {
|
|
|
383
383
|
// clockless free accounts keep the generic pre-top-up line.
|
|
384
384
|
liveClock: daysLeft != null,
|
|
385
385
|
title: "You're out of credits",
|
|
386
|
-
body: `You have used ${used}/${granted} free credits. Select
|
|
386
|
+
body: `You have used ${used}/${granted} free credits. Select a paid plan to continue use of ${name}.`,
|
|
387
387
|
};
|
|
388
388
|
}
|
|
389
389
|
if (daysLeft != null) {
|
|
@@ -397,9 +397,10 @@ function trialStateOf(ent, { appName } = {}) {
|
|
|
397
397
|
}
|
|
398
398
|
|
|
399
399
|
// Trial states map onto the banner shape with the shared support footer and a
|
|
400
|
-
// Billing-tab CTA (the copy asks for a plan
|
|
401
|
-
//
|
|
402
|
-
// are RED (they stop the app), trial-active is
|
|
400
|
+
// Billing-tab CTA (the copy asks for "a paid plan" — never "below": on Home
|
|
401
|
+
// there are no plans below the banner — so the button routes to the picker).
|
|
402
|
+
// out-of-credits/trial-ended are RED (they stop the app), trial-active is
|
|
403
|
+
// YELLOW — Andrew 2026-10-13.
|
|
403
404
|
const TRIAL_STATE_VARIANT = {
|
|
404
405
|
out_of_credits: "error",
|
|
405
406
|
trial_ended: "error",
|