@hanzo/ui 8.27.32 → 8.27.38
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/dist/auth/SignIn.cjs +180 -17
- package/dist/auth/SignIn.d.ts +25 -1
- package/dist/auth/SignIn.d.ts.map +1 -1
- package/dist/auth/SignIn.js +146 -18
- package/dist/auth/SignIn.js.map +1 -1
- package/dist/consent/Consent.cjs +35 -14
- package/dist/consent/Consent.d.ts +1 -1
- package/dist/consent/Consent.d.ts.map +1 -1
- package/dist/consent/Consent.js +36 -15
- package/dist/consent/Consent.js.map +1 -1
- package/dist/gallery.cjs +13 -1
- package/dist/gallery.d.ts.map +1 -1
- package/dist/gallery.html +10 -6
- package/dist/gallery.js +14 -2
- package/dist/gallery.js.map +1 -1
- package/dist/marketing/ClosingCta.cjs +4 -4
- package/dist/marketing/ClosingCta.d.ts +5 -3
- package/dist/marketing/ClosingCta.d.ts.map +1 -1
- package/dist/marketing/ClosingCta.js +4 -4
- package/dist/marketing/ClosingCta.js.map +1 -1
- package/dist/marketing/Faq.cjs +1 -1
- package/dist/marketing/Faq.js +1 -1
- package/dist/marketing/Faq.js.map +1 -1
- package/dist/marketing/Footer.cjs +27 -0
- package/dist/marketing/Footer.d.ts +25 -0
- package/dist/marketing/Footer.d.ts.map +1 -0
- package/dist/marketing/Footer.js +25 -0
- package/dist/marketing/Footer.js.map +1 -0
- package/dist/marketing/Hero.cjs +2 -2
- package/dist/marketing/Hero.js +2 -2
- package/dist/marketing/Hero.js.map +1 -1
- package/dist/marketing/Plans.cjs +15 -9
- package/dist/marketing/Plans.d.ts +5 -3
- package/dist/marketing/Plans.d.ts.map +1 -1
- package/dist/marketing/Plans.js +16 -10
- package/dist/marketing/Plans.js.map +1 -1
- package/dist/marketing/blocks.cjs +3 -3
- package/dist/marketing/blocks.js +3 -3
- package/dist/marketing/blocks.js.map +1 -1
- package/dist/marketing/index.cjs +4 -1
- package/dist/marketing/index.d.ts +2 -1
- package/dist/marketing/index.d.ts.map +1 -1
- package/dist/marketing/index.js +2 -1
- package/dist/marketing/index.js.map +1 -1
- package/dist/marketing/rows.cjs +26 -0
- package/dist/marketing/rows.d.ts +10 -0
- package/dist/marketing/rows.d.ts.map +1 -1
- package/dist/marketing/rows.js +25 -0
- package/dist/marketing/rows.js.map +1 -1
- package/dist/onboarding/ChatOnboarding.cjs +1 -1
- package/dist/onboarding/ChatOnboarding.js +2 -2
- package/dist/onboarding/ChatOnboarding.js.map +1 -1
- package/dist/onboarding/Checkout.cjs +19 -5
- package/dist/onboarding/Checkout.d.ts +3 -1
- package/dist/onboarding/Checkout.d.ts.map +1 -1
- package/dist/onboarding/Checkout.js +20 -6
- package/dist/onboarding/Checkout.js.map +1 -1
- package/dist/onboarding/Onboarding.cjs +99 -21
- package/dist/onboarding/Onboarding.d.ts +32 -4
- package/dist/onboarding/Onboarding.d.ts.map +1 -1
- package/dist/onboarding/Onboarding.js +102 -24
- package/dist/onboarding/Onboarding.js.map +1 -1
- package/dist/onboarding/account.cjs +16 -0
- package/dist/onboarding/account.d.ts +21 -0
- package/dist/onboarding/account.d.ts.map +1 -0
- package/dist/onboarding/account.js +14 -0
- package/dist/onboarding/account.js.map +1 -0
- package/dist/onboarding/api.cjs +4 -1
- package/dist/onboarding/api.d.ts +5 -1
- package/dist/onboarding/api.d.ts.map +1 -1
- package/dist/onboarding/api.js +2 -0
- package/dist/onboarding/api.js.map +1 -1
- package/dist/onboarding/catalog.cjs +30 -0
- package/dist/onboarding/catalog.d.ts +5 -0
- package/dist/onboarding/catalog.d.ts.map +1 -0
- package/dist/onboarding/catalog.js +27 -0
- package/dist/onboarding/catalog.js.map +1 -0
- package/dist/onboarding/frame.cjs +15 -5
- package/dist/onboarding/frame.d.ts +14 -4
- package/dist/onboarding/frame.d.ts.map +1 -1
- package/dist/onboarding/frame.js +14 -5
- package/dist/onboarding/frame.js.map +1 -1
- package/dist/onboarding/hooks.cjs +25 -7
- package/dist/onboarding/hooks.d.ts +15 -4
- package/dist/onboarding/hooks.d.ts.map +1 -1
- package/dist/onboarding/hooks.js +26 -9
- package/dist/onboarding/hooks.js.map +1 -1
- package/dist/onboarding/index.cjs +16 -4
- package/dist/onboarding/index.d.ts +8 -5
- package/dist/onboarding/index.d.ts.map +1 -1
- package/dist/onboarding/index.js +8 -5
- package/dist/onboarding/index.js.map +1 -1
- package/dist/onboarding/plans.cjs +75 -68
- package/dist/onboarding/plans.d.ts +41 -22
- package/dist/onboarding/plans.d.ts.map +1 -1
- package/dist/onboarding/plans.js +66 -64
- package/dist/onboarding/plans.js.map +1 -1
- package/dist/onboarding/screens.cjs +20 -8
- package/dist/onboarding/screens.d.ts +12 -2
- package/dist/onboarding/screens.d.ts.map +1 -1
- package/dist/onboarding/screens.js +20 -9
- package/dist/onboarding/screens.js.map +1 -1
- package/dist/onboarding/state.cjs +17 -2
- package/dist/onboarding/state.d.ts +22 -3
- package/dist/onboarding/state.d.ts.map +1 -1
- package/dist/onboarding/state.js +15 -2
- package/dist/onboarding/state.js.map +1 -1
- package/dist/styles.css +3 -0
- package/package.json +3 -3
package/dist/onboarding/frame.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext } from 'react';
|
|
3
4
|
import { HanzoMark } from '@hanzogui/shell';
|
|
4
5
|
import { ArrowLeft } from '@hanzogui/lucide-icons-2';
|
|
5
6
|
import { Button } from '../backends/gui/button.js';
|
|
@@ -7,22 +8,30 @@ import { Card, CardContent } from '../backends/gui/card.js';
|
|
|
7
8
|
import { Heading, Paragraph, SizableText, XStack, YStack } from '../backends/gui/layout.js';
|
|
8
9
|
import { Spinner } from '../backends/gui/spinner.js';
|
|
9
10
|
import { ToggleGroup, ToggleGroupItem } from '../backends/gui/toggle-group.js';
|
|
10
|
-
|
|
11
|
+
const Brand = createContext(true);
|
|
12
|
+
/**
|
|
13
|
+
* Wrap onboarding in a host whose own shell already draws the logo and the page's
|
|
14
|
+
* `main` (a bare masthead), so the pages draw neither a second logo nor a second `main`.
|
|
15
|
+
*/
|
|
16
|
+
export function Bare({ children }) {
|
|
17
|
+
return _jsx(Brand.Provider, { value: false, children: children });
|
|
18
|
+
}
|
|
11
19
|
/**
|
|
12
20
|
* One page of onboarding: the product's mark, a title, a line under it, and the
|
|
13
21
|
* screen. No progress bar and no step counter. `width` sets how much room the
|
|
14
22
|
* screen has: a column for a form, the full row for three plans.
|
|
15
23
|
*/
|
|
16
|
-
export function Page({ site, title, lede, back, children, center, width = 480, start, busy, }) {
|
|
17
|
-
|
|
24
|
+
export function Page({ site, title, lede, back, children, center, width = 480, start, busy, foot, }) {
|
|
25
|
+
const brand = useContext(Brand);
|
|
26
|
+
return (_jsxs(YStack, { render: brand ? 'main' : 'div', "aria-busy": busy || undefined, bg: "$background", minH: "100vh", items: "center", justify: center ? 'center' : 'flex-start', gap: "$4", pt: center ? 96 : 28, pb: 96, px: "$4", children: [back ? (_jsx(Button, { type: "button", variant: "ghost", size: "icon-lg", "aria-label": "Back", position: "absolute", t: 20, l: 20, rounded: "$10", onClick: back, children: _jsx(ArrowLeft, { size: 18 }) })) : null, brand ? (_jsxs(XStack, { items: "center", gap: "$2.5", mb: "$5", children: [_jsx(HanzoMark, { size: 20 }), _jsx(SizableText, { size: "$5", fontWeight: "500", color: "$ink", children: site })] })) : null, title || lede ? (_jsxs(YStack, { width: "100%", maxW: start ? width : 720, items: start ? 'flex-start' : 'center', gap: "$3", children: [title ? (_jsx(Heading, { render: "h1", size: "$9", fontWeight: "500", color: "$ink", text: start ? 'left' : 'center', m: 0, children: title })) : null, lede ? (_jsx(Paragraph, { size: "$3", color: "$quiet", text: start ? 'left' : 'center', maxW: 520, m: 0, children: lede })) : null] })) : null, busy ? _jsx(Spinner, { size: 20 }) : null, children ? (_jsx(YStack, { width: "100%", maxW: width, items: "stretch", gap: "$4", mt: "$2", children: children })) : null, foot ? (_jsx(YStack, { position: "absolute", b: 32, l: 0, r: 0, items: "center", gap: "$1", px: "$4", children: foot })) : null] }));
|
|
18
27
|
}
|
|
19
28
|
/** A bordered panel with room inside, the surface for an order, a notice or a plan. */
|
|
20
29
|
export function Panel({ children, label }) {
|
|
21
30
|
return (_jsx(Card, { "aria-label": label, bg: "$panel", width: "100%", children: _jsx(CardContent, { gap: "$3", children: children }) }));
|
|
22
31
|
}
|
|
23
32
|
/** Monthly or Yearly, with what a year saves. `name` says which plan it changes, for screen readers. */
|
|
24
|
-
export function IntervalToggle({ interval, onChange, name }) {
|
|
25
|
-
return (_jsxs(ToggleGroup, { type: "single", size: "sm", value: interval, disableDeactivation: true, "aria-label": `Billing interval for ${name}`, onValueChange: (v) => onChange(v), children: [_jsx(ToggleGroupItem, { value: "monthly", children: "Monthly" }), _jsx(ToggleGroupItem, { value: "annual", children: `Yearly · Save ${
|
|
33
|
+
export function IntervalToggle({ interval, onChange, name, save }) {
|
|
34
|
+
return (_jsxs(ToggleGroup, { type: "single", size: "sm", value: interval, disableDeactivation: true, "aria-label": `Billing interval for ${name}`, onValueChange: (v) => onChange(v), children: [_jsx(ToggleGroupItem, { value: "monthly", children: "Monthly" }), _jsx(ToggleGroupItem, { value: "annual", children: `Yearly · Save ${save}%` })] }));
|
|
26
35
|
}
|
|
27
36
|
/** A line of an order: what, and how much. `muted` for the lines that are not the total. */
|
|
28
37
|
export function Line({ label, note, value, muted, strong }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame.js","sourceRoot":"","sources":["../../src/onboarding/frame.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;
|
|
1
|
+
{"version":3,"file":"frame.js","sourceRoot":"","sources":["../../src/onboarding/frame.tsx"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
'use client';
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.useSession = useSession;
|
|
5
|
+
exports.firstRun = firstRun;
|
|
5
6
|
exports.useOnboarded = useOnboarded;
|
|
6
7
|
const react_1 = require("react");
|
|
7
8
|
const api_1 = require("./api.cjs");
|
|
@@ -14,6 +15,7 @@ function useSession(api = api_1.API) {
|
|
|
14
15
|
const [loading, setLoading] = (0, react_1.useState)(true);
|
|
15
16
|
const [stored, setStored] = (0, react_1.useState)({});
|
|
16
17
|
const [name, setNameState] = (0, react_1.useState)('');
|
|
18
|
+
const [me, setMe] = (0, react_1.useState)({ email: '' });
|
|
17
19
|
const [error, setError] = (0, react_1.useState)(null);
|
|
18
20
|
(0, react_1.useEffect)(() => {
|
|
19
21
|
let live = true;
|
|
@@ -23,6 +25,7 @@ function useSession(api = api_1.API) {
|
|
|
23
25
|
setStored(prefs ?? {});
|
|
24
26
|
const a = me;
|
|
25
27
|
setNameState(a?.displayName?.trim() ?? '');
|
|
28
|
+
setMe({ email: a?.email ?? '', createdTime: a?.createdTime });
|
|
26
29
|
setLoading(false);
|
|
27
30
|
});
|
|
28
31
|
return () => {
|
|
@@ -48,20 +51,35 @@ function useSession(api = api_1.API) {
|
|
|
48
51
|
setStored((s) => ({ ...s, train_opt_in: on }));
|
|
49
52
|
await (0, api_1.preferences)(api, { train_opt_in: on });
|
|
50
53
|
}, [api]);
|
|
51
|
-
|
|
54
|
+
const accept = (0, react_1.useCallback)(async (policy) => {
|
|
55
|
+
const done = await (0, api_1.acceptTerms)(api, policy);
|
|
56
|
+
setStored((s) => ({ ...s, terms: done }));
|
|
57
|
+
return done;
|
|
58
|
+
}, [api]);
|
|
59
|
+
return { loading, progress: stored.onboarding ?? {}, trainOptIn: stored.train_opt_in, name, email: me.email, owesTerms: (0, state_1.owesTerms)(stored.terms, me.createdTime), accept, save, setName, setTrain, error };
|
|
52
60
|
}
|
|
53
61
|
/**
|
|
54
|
-
* Whether this person still has
|
|
55
|
-
*
|
|
56
|
-
*
|
|
62
|
+
* Whether this person still has a first-run step to do, from the terms page to
|
|
63
|
+
* the role. A failed read answers `pending: false`, because a broken read must
|
|
64
|
+
* not lock anyone out.
|
|
57
65
|
*/
|
|
66
|
+
async function firstRun(api = api_1.API) {
|
|
67
|
+
try {
|
|
68
|
+
const [s, me] = await Promise.all([(0, api_1.preferences)(api), (0, api_1.account)(api)]);
|
|
69
|
+
const p = s?.onboarding ?? {};
|
|
70
|
+
const pending = (0, state_1.owesTerms)(s?.terms, me?.createdTime) || (0, state_1.step)(p) !== 'done' || (0, state_1.chatStep)(p, Boolean(me?.displayName?.trim())) !== 'done';
|
|
71
|
+
return { pending, plan: p.plan };
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return { pending: false, plan: undefined };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** `firstRun` as a hook: `pending` is `null` while IAM has not answered, so a gate never flashes the wrong screen. */
|
|
58
78
|
function useOnboarded(api = api_1.API) {
|
|
59
79
|
const [state, setState] = (0, react_1.useState)({ pending: null, plan: undefined });
|
|
60
80
|
(0, react_1.useEffect)(() => {
|
|
61
81
|
let live = true;
|
|
62
|
-
(
|
|
63
|
-
.then((s) => live && setState({ pending: (0, state_1.step)(s?.onboarding ?? {}) !== 'done', plan: s?.onboarding?.plan }))
|
|
64
|
-
.catch(() => live && setState({ pending: false, plan: undefined }));
|
|
82
|
+
void firstRun(api).then((r) => live && setState(r));
|
|
65
83
|
return () => {
|
|
66
84
|
live = false;
|
|
67
85
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Progress } from './state.js';
|
|
1
|
+
import { type Accepted, type Policy, type Progress } from './state.js';
|
|
2
2
|
export type Track = (name: string, props?: Record<string, unknown>) => void;
|
|
3
3
|
export interface Session {
|
|
4
4
|
/** Nothing has answered yet. */
|
|
@@ -7,6 +7,12 @@ export interface Session {
|
|
|
7
7
|
trainOptIn: boolean | undefined;
|
|
8
8
|
/** The display name IAM holds, if any. */
|
|
9
9
|
name: string;
|
|
10
|
+
/** The verified address of the account. */
|
|
11
|
+
email: string;
|
|
12
|
+
/** The "Let's create your account" page is owed (see `owesTerms`). */
|
|
13
|
+
owesTerms: boolean;
|
|
14
|
+
/** Record the acceptance on the IAM user. */
|
|
15
|
+
accept: (policy: Policy) => Promise<Accepted>;
|
|
10
16
|
/** Merge a step into the stored progress (and the screen). */
|
|
11
17
|
save: (patch: Progress) => Promise<void>;
|
|
12
18
|
setName: (name: string) => Promise<void>;
|
|
@@ -19,10 +25,15 @@ export interface Session {
|
|
|
19
25
|
*/
|
|
20
26
|
export declare function useSession(api?: string): Session;
|
|
21
27
|
/**
|
|
22
|
-
* Whether this person still has
|
|
23
|
-
*
|
|
24
|
-
*
|
|
28
|
+
* Whether this person still has a first-run step to do, from the terms page to
|
|
29
|
+
* the role. A failed read answers `pending: false`, because a broken read must
|
|
30
|
+
* not lock anyone out.
|
|
25
31
|
*/
|
|
32
|
+
export declare function firstRun(api?: string): Promise<{
|
|
33
|
+
pending: boolean;
|
|
34
|
+
plan: string | undefined;
|
|
35
|
+
}>;
|
|
36
|
+
/** `firstRun` as a hook: `pending` is `null` while IAM has not answered, so a gate never flashes the wrong screen. */
|
|
26
37
|
export declare function useOnboarded(api?: string): {
|
|
27
38
|
pending: boolean | null;
|
|
28
39
|
plan: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/onboarding/hooks.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/onboarding/hooks.ts"],"names":[],"mappings":"AAIA,OAAO,EAA6B,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAe,MAAM,SAAS,CAAA;AAE3G,MAAM,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;AAE3E,MAAM,WAAW,OAAO;IACtB,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,QAAQ,CAAA;IAClB,UAAU,EAAE,OAAO,GAAG,SAAS,CAAA;IAC/B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,SAAS,EAAE,OAAO,CAAA;IAClB,6CAA6C;IAC7C,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC7C,8DAA8D;IAC9D,IAAI,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,QAAQ,EAAE,CAAC,EAAE,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAY,GAAG,OAAO,CA8DrD;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,GAAG,GAAE,MAAY,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC,CASzG;AAED,sHAAsH;AACtH,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAY,GAAG;IAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAUrG"}
|
package/dist/onboarding/hooks.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useCallback, useEffect, useState } from 'react';
|
|
3
|
-
import { account, API, preferences, rename, saveProgress } from './api.js';
|
|
4
|
-
import { step } from './state.js';
|
|
3
|
+
import { account, acceptTerms, API, preferences, rename, saveProgress } from './api.js';
|
|
4
|
+
import { chatStep, owesTerms, step } from './state.js';
|
|
5
5
|
/**
|
|
6
6
|
* The person's onboarding, read from IAM once and written through as each step
|
|
7
7
|
* finishes. A failed read leaves the flow at the start rather than blocking it.
|
|
@@ -10,6 +10,7 @@ export function useSession(api = API) {
|
|
|
10
10
|
const [loading, setLoading] = useState(true);
|
|
11
11
|
const [stored, setStored] = useState({});
|
|
12
12
|
const [name, setNameState] = useState('');
|
|
13
|
+
const [me, setMe] = useState({ email: '' });
|
|
13
14
|
const [error, setError] = useState(null);
|
|
14
15
|
useEffect(() => {
|
|
15
16
|
let live = true;
|
|
@@ -19,6 +20,7 @@ export function useSession(api = API) {
|
|
|
19
20
|
setStored(prefs ?? {});
|
|
20
21
|
const a = me;
|
|
21
22
|
setNameState(a?.displayName?.trim() ?? '');
|
|
23
|
+
setMe({ email: a?.email ?? '', createdTime: a?.createdTime });
|
|
22
24
|
setLoading(false);
|
|
23
25
|
});
|
|
24
26
|
return () => {
|
|
@@ -44,20 +46,35 @@ export function useSession(api = API) {
|
|
|
44
46
|
setStored((s) => ({ ...s, train_opt_in: on }));
|
|
45
47
|
await preferences(api, { train_opt_in: on });
|
|
46
48
|
}, [api]);
|
|
47
|
-
|
|
49
|
+
const accept = useCallback(async (policy) => {
|
|
50
|
+
const done = await acceptTerms(api, policy);
|
|
51
|
+
setStored((s) => ({ ...s, terms: done }));
|
|
52
|
+
return done;
|
|
53
|
+
}, [api]);
|
|
54
|
+
return { loading, progress: stored.onboarding ?? {}, trainOptIn: stored.train_opt_in, name, email: me.email, owesTerms: owesTerms(stored.terms, me.createdTime), accept, save, setName, setTrain, error };
|
|
48
55
|
}
|
|
49
56
|
/**
|
|
50
|
-
* Whether this person still has
|
|
51
|
-
*
|
|
52
|
-
*
|
|
57
|
+
* Whether this person still has a first-run step to do, from the terms page to
|
|
58
|
+
* the role. A failed read answers `pending: false`, because a broken read must
|
|
59
|
+
* not lock anyone out.
|
|
53
60
|
*/
|
|
61
|
+
export async function firstRun(api = API) {
|
|
62
|
+
try {
|
|
63
|
+
const [s, me] = await Promise.all([preferences(api), account(api)]);
|
|
64
|
+
const p = s?.onboarding ?? {};
|
|
65
|
+
const pending = owesTerms(s?.terms, me?.createdTime) || step(p) !== 'done' || chatStep(p, Boolean(me?.displayName?.trim())) !== 'done';
|
|
66
|
+
return { pending, plan: p.plan };
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return { pending: false, plan: undefined };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** `firstRun` as a hook: `pending` is `null` while IAM has not answered, so a gate never flashes the wrong screen. */
|
|
54
73
|
export function useOnboarded(api = API) {
|
|
55
74
|
const [state, setState] = useState({ pending: null, plan: undefined });
|
|
56
75
|
useEffect(() => {
|
|
57
76
|
let live = true;
|
|
58
|
-
|
|
59
|
-
.then((s) => live && setState({ pending: step(s?.onboarding ?? {}) !== 'done', plan: s?.onboarding?.plan }))
|
|
60
|
-
.catch(() => live && setState({ pending: false, plan: undefined }));
|
|
77
|
+
void firstRun(api).then((r) => live && setState(r));
|
|
61
78
|
return () => {
|
|
62
79
|
live = false;
|
|
63
80
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/onboarding/hooks.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/onboarding/hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.preferences = exports.API = exports.ROLES = exports.OWN_TOPIC = exports.unit = exports.SLUG = exports.saving = exports.
|
|
3
|
+
exports.preferences = exports.API = exports.acceptTerms = exports.ROLES = exports.OWN_TOPIC = exports.useCatalog = exports.loadCatalog = exports.unit = exports.SLUG = exports.saving = exports.period = exports.OFFERS = exports.offer = exports.MIN_SEATS = exports.MAX_SEATS = exports.lines = exports.item = exports.has = exports.ENTERPRISE_FROM = exports.adopt = exports.step = exports.owesTerms = exports.NEW_WITHIN = exports.chatStep = exports.useSession = exports.useOnboarded = exports.firstRun = exports.CreateAccount = exports.Bare = exports.Checkout = exports.ChatOnboarding = exports.Onboarding = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* The onboarding every Hanzo surface shares. IAM holds each person's progress
|
|
6
6
|
* (POST /v1/iam/preferences), commerce takes the payment (/v1/billing), and
|
|
7
7
|
|
|
8
8
|
*
|
|
9
|
-
* <Onboarding/>
|
|
9
|
+
* <Onboarding/> the terms (new accounts) → Hanzo Pro → all plans | team → seats → checkout
|
|
10
10
|
* <ChatOnboarding/> before your first chat → name → role and starter prompts
|
|
11
11
|
* <Checkout/> the one checkout, also behind every Upgrade entry
|
|
12
12
|
*/
|
|
@@ -16,28 +16,40 @@ var ChatOnboarding_1 = require("./ChatOnboarding.cjs");
|
|
|
16
16
|
Object.defineProperty(exports, "ChatOnboarding", { enumerable: true, get: function () { return ChatOnboarding_1.ChatOnboarding; } });
|
|
17
17
|
var Checkout_1 = require("./Checkout.cjs");
|
|
18
18
|
Object.defineProperty(exports, "Checkout", { enumerable: true, get: function () { return Checkout_1.Checkout; } });
|
|
19
|
+
var frame_1 = require("./frame.cjs");
|
|
20
|
+
Object.defineProperty(exports, "Bare", { enumerable: true, get: function () { return frame_1.Bare; } });
|
|
21
|
+
var account_1 = require("./account.cjs");
|
|
22
|
+
Object.defineProperty(exports, "CreateAccount", { enumerable: true, get: function () { return account_1.CreateAccount; } });
|
|
19
23
|
var hooks_1 = require("./hooks.cjs");
|
|
24
|
+
Object.defineProperty(exports, "firstRun", { enumerable: true, get: function () { return hooks_1.firstRun; } });
|
|
20
25
|
Object.defineProperty(exports, "useOnboarded", { enumerable: true, get: function () { return hooks_1.useOnboarded; } });
|
|
21
26
|
Object.defineProperty(exports, "useSession", { enumerable: true, get: function () { return hooks_1.useSession; } });
|
|
22
27
|
var state_1 = require("./state.cjs");
|
|
23
28
|
Object.defineProperty(exports, "chatStep", { enumerable: true, get: function () { return state_1.chatStep; } });
|
|
29
|
+
Object.defineProperty(exports, "NEW_WITHIN", { enumerable: true, get: function () { return state_1.NEW_WITHIN; } });
|
|
30
|
+
Object.defineProperty(exports, "owesTerms", { enumerable: true, get: function () { return state_1.owesTerms; } });
|
|
24
31
|
Object.defineProperty(exports, "step", { enumerable: true, get: function () { return state_1.step; } });
|
|
25
32
|
var plans_1 = require("./plans.cjs");
|
|
26
|
-
Object.defineProperty(exports, "
|
|
33
|
+
Object.defineProperty(exports, "adopt", { enumerable: true, get: function () { return plans_1.adopt; } });
|
|
27
34
|
Object.defineProperty(exports, "ENTERPRISE_FROM", { enumerable: true, get: function () { return plans_1.ENTERPRISE_FROM; } });
|
|
35
|
+
Object.defineProperty(exports, "has", { enumerable: true, get: function () { return plans_1.has; } });
|
|
28
36
|
Object.defineProperty(exports, "item", { enumerable: true, get: function () { return plans_1.item; } });
|
|
29
37
|
Object.defineProperty(exports, "lines", { enumerable: true, get: function () { return plans_1.lines; } });
|
|
30
38
|
Object.defineProperty(exports, "MAX_SEATS", { enumerable: true, get: function () { return plans_1.MAX_SEATS; } });
|
|
31
39
|
Object.defineProperty(exports, "MIN_SEATS", { enumerable: true, get: function () { return plans_1.MIN_SEATS; } });
|
|
40
|
+
Object.defineProperty(exports, "offer", { enumerable: true, get: function () { return plans_1.offer; } });
|
|
32
41
|
Object.defineProperty(exports, "OFFERS", { enumerable: true, get: function () { return plans_1.OFFERS; } });
|
|
33
42
|
Object.defineProperty(exports, "period", { enumerable: true, get: function () { return plans_1.period; } });
|
|
34
|
-
Object.defineProperty(exports, "SEAT_ADDON", { enumerable: true, get: function () { return plans_1.SEAT_ADDON; } });
|
|
35
43
|
Object.defineProperty(exports, "saving", { enumerable: true, get: function () { return plans_1.saving; } });
|
|
36
44
|
Object.defineProperty(exports, "SLUG", { enumerable: true, get: function () { return plans_1.SLUG; } });
|
|
37
45
|
Object.defineProperty(exports, "unit", { enumerable: true, get: function () { return plans_1.unit; } });
|
|
46
|
+
var catalog_1 = require("./catalog.cjs");
|
|
47
|
+
Object.defineProperty(exports, "loadCatalog", { enumerable: true, get: function () { return catalog_1.loadCatalog; } });
|
|
48
|
+
Object.defineProperty(exports, "useCatalog", { enumerable: true, get: function () { return catalog_1.useCatalog; } });
|
|
38
49
|
var roles_1 = require("./roles.cjs");
|
|
39
50
|
Object.defineProperty(exports, "OWN_TOPIC", { enumerable: true, get: function () { return roles_1.OWN_TOPIC; } });
|
|
40
51
|
Object.defineProperty(exports, "ROLES", { enumerable: true, get: function () { return roles_1.ROLES; } });
|
|
41
52
|
var api_1 = require("./api.cjs");
|
|
53
|
+
Object.defineProperty(exports, "acceptTerms", { enumerable: true, get: function () { return api_1.acceptTerms; } });
|
|
42
54
|
Object.defineProperty(exports, "API", { enumerable: true, get: function () { return api_1.API; } });
|
|
43
55
|
Object.defineProperty(exports, "preferences", { enumerable: true, get: function () { return api_1.preferences; } });
|
|
@@ -3,16 +3,19 @@
|
|
|
3
3
|
* (POST /v1/iam/preferences), commerce takes the payment (/v1/billing), and
|
|
4
4
|
|
|
5
5
|
*
|
|
6
|
-
* <Onboarding/>
|
|
6
|
+
* <Onboarding/> the terms (new accounts) → Hanzo Pro → all plans | team → seats → checkout
|
|
7
7
|
* <ChatOnboarding/> before your first chat → name → role and starter prompts
|
|
8
8
|
* <Checkout/> the one checkout, also behind every Upgrade entry
|
|
9
9
|
*/
|
|
10
10
|
export { Onboarding, type OnboardingProps } from './Onboarding.js';
|
|
11
11
|
export { ChatOnboarding, type ChatOnboardingProps } from './ChatOnboarding.js';
|
|
12
12
|
export { Checkout, type CheckoutProps } from './Checkout.js';
|
|
13
|
-
export {
|
|
14
|
-
export {
|
|
15
|
-
export {
|
|
13
|
+
export { Bare } from './frame.js';
|
|
14
|
+
export { CreateAccount, type CreateAccountProps } from './account.js';
|
|
15
|
+
export { firstRun, useOnboarded, useSession, type Session, type Track } from './hooks.js';
|
|
16
|
+
export { chatStep, NEW_WITHIN, owesTerms, step, type Accepted, type ChatStep, type Policy, type Progress, type Step, type Use } from './state.js';
|
|
17
|
+
export { adopt, ENTERPRISE_FROM, has, item, lines, MAX_SEATS, MIN_SEATS, offer, OFFERS, period, saving, SLUG, unit, type Interval, type Lines, type Offer, type PlanId, type Row } from './plans.js';
|
|
18
|
+
export { loadCatalog, useCatalog } from './catalog.js';
|
|
16
19
|
export { OWN_TOPIC, ROLES, type Role, type Starter } from './roles.js';
|
|
17
|
-
export { API, preferences } from './api.js';
|
|
20
|
+
export { acceptTerms, API, preferences } from './api.js';
|
|
18
21
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/onboarding/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC3E,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/onboarding/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC3E,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC9B,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAClE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAA;AACtF,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,GAAG,EAAE,MAAM,SAAS,CAAA;AAC9I,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,MAAM,EAAE,KAAK,GAAG,EAAE,MAAM,SAAS,CAAA;AACjM,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAA;AACnE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA"}
|
package/dist/onboarding/index.js
CHANGED
|
@@ -3,16 +3,19 @@
|
|
|
3
3
|
* (POST /v1/iam/preferences), commerce takes the payment (/v1/billing), and
|
|
4
4
|
|
|
5
5
|
*
|
|
6
|
-
* <Onboarding/>
|
|
6
|
+
* <Onboarding/> the terms (new accounts) → Hanzo Pro → all plans | team → seats → checkout
|
|
7
7
|
* <ChatOnboarding/> before your first chat → name → role and starter prompts
|
|
8
8
|
* <Checkout/> the one checkout, also behind every Upgrade entry
|
|
9
9
|
*/
|
|
10
10
|
export { Onboarding } from './Onboarding.js';
|
|
11
11
|
export { ChatOnboarding } from './ChatOnboarding.js';
|
|
12
12
|
export { Checkout } from './Checkout.js';
|
|
13
|
-
export {
|
|
14
|
-
export {
|
|
15
|
-
export {
|
|
13
|
+
export { Bare } from './frame.js';
|
|
14
|
+
export { CreateAccount } from './account.js';
|
|
15
|
+
export { firstRun, useOnboarded, useSession } from './hooks.js';
|
|
16
|
+
export { chatStep, NEW_WITHIN, owesTerms, step } from './state.js';
|
|
17
|
+
export { adopt, ENTERPRISE_FROM, has, item, lines, MAX_SEATS, MIN_SEATS, offer, OFFERS, period, saving, SLUG, unit } from './plans.js';
|
|
18
|
+
export { loadCatalog, useCatalog } from './catalog.js';
|
|
16
19
|
export { OWN_TOPIC, ROLES } from './roles.js';
|
|
17
|
-
export { API, preferences } from './api.js';
|
|
20
|
+
export { acceptTerms, API, preferences } from './api.js';
|
|
18
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/onboarding/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAwB,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,cAAc,EAA4B,MAAM,kBAAkB,CAAA;AAC3E,OAAO,EAAE,QAAQ,EAAsB,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,UAAU,EAA4B,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/onboarding/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,UAAU,EAAwB,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,cAAc,EAA4B,MAAM,kBAAkB,CAAA;AAC3E,OAAO,EAAE,QAAQ,EAAsB,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC9B,OAAO,EAAE,aAAa,EAA2B,MAAM,WAAW,CAAA;AAClE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAA4B,MAAM,SAAS,CAAA;AACtF,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAiF,MAAM,SAAS,CAAA;AAC9I,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAgE,MAAM,SAAS,CAAA;AACjM,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,KAAK,EAA2B,MAAM,SAAS,CAAA;AACnE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA"}
|
|
@@ -1,87 +1,94 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* What Hanzo sells, priced from commerce's live catalog (GET /v1/billing/plans)
|
|
4
|
+
* and nothing else: no price is typed in this package. `adopt` takes the rows,
|
|
5
|
+
* after which every function here answers from them.
|
|
6
|
+
*
|
|
7
|
+
* free chat only; offered on the personal path alone
|
|
8
|
+
* dev Pro, the personal plan
|
|
9
|
+
* max_5x, max_20x one Max card; the tier is picked at checkout
|
|
10
|
+
* team_standard the catalog's per-seat Team plan, two seats at least
|
|
11
|
+
* team_premium a heavier seat, offered only while the catalog lists one
|
|
12
|
+
*/
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
14
|
+
exports.money = exports.usd = exports.yearly = exports.has = exports.OFFERS = exports.SLUG = exports.ENTERPRISE_FROM = exports.MAX_SEATS = exports.MIN_SEATS = void 0;
|
|
15
|
+
exports.adopt = adopt;
|
|
16
|
+
exports.offer = offer;
|
|
17
|
+
exports.unit = unit;
|
|
18
|
+
exports.period = period;
|
|
19
|
+
exports.saving = saving;
|
|
4
20
|
exports.lines = lines;
|
|
5
21
|
exports.item = item;
|
|
6
|
-
const plans_1 = require("@hanzo/plans");
|
|
7
|
-
/** Annual price is the monthly price times this. */
|
|
8
|
-
exports.ANNUAL = 0.82;
|
|
9
|
-
/** What a team seat adds to the personal plan it is built on, per month. */
|
|
10
|
-
exports.SEAT_ADDON = 5;
|
|
11
22
|
exports.MIN_SEATS = 2;
|
|
12
23
|
exports.MAX_SEATS = 150;
|
|
13
24
|
/** From 20 people the team plan becomes a conversation. */
|
|
14
25
|
exports.ENTERPRISE_FROM = 20;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (!p || p.priceMonthly == null)
|
|
18
|
-
throw new Error(`@hanzo/plans has no monthly price for ${slug}`);
|
|
19
|
-
return p.priceMonthly;
|
|
20
|
-
};
|
|
26
|
+
/** The commerce catalog's slug for each plan. */
|
|
27
|
+
exports.SLUG = { free: 'free', dev: 'dev', max_5x: 'max-5x', max_20x: 'max-20x', team_standard: 'team', team_premium: 'team-premium' };
|
|
21
28
|
const cents = (n) => Math.round(n * 100) / 100;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
/** One unit's price per month at this interval (a year, spread over its twelve months). */
|
|
65
|
-
const unit = (id, interval) => cents(interval === 'annual' ? exports.OFFERS[id].monthly * exports.ANNUAL : exports.OFFERS[id].monthly);
|
|
66
|
-
exports.unit = unit;
|
|
29
|
+
const offers = {};
|
|
30
|
+
/** The offers as loaded: a plan the catalog does not list is absent. */
|
|
31
|
+
exports.OFFERS = offers;
|
|
32
|
+
/** Take the catalog's rows as what is sold. */
|
|
33
|
+
function adopt(rows) {
|
|
34
|
+
for (const k of Object.keys(offers))
|
|
35
|
+
delete offers[k];
|
|
36
|
+
for (const id of Object.keys(exports.SLUG)) {
|
|
37
|
+
const r = rows.find((x) => x.slug === exports.SLUG[id]);
|
|
38
|
+
if (!r)
|
|
39
|
+
continue;
|
|
40
|
+
const team = id.startsWith('team');
|
|
41
|
+
offers[id] = {
|
|
42
|
+
id,
|
|
43
|
+
slug: r.slug,
|
|
44
|
+
name: team ? (id === 'team_standard' ? 'Standard seat' : 'Premium seat') : r.name,
|
|
45
|
+
category: team ? 'team' : 'individual',
|
|
46
|
+
monthly: cents(r.price / 100),
|
|
47
|
+
yearly: r.annualTotal ? cents(r.annualTotal / 100) : null,
|
|
48
|
+
blurb: r.description ?? '',
|
|
49
|
+
features: r.features ?? [],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** The offer for a plan; throws while the catalog has not loaded or does not list it. */
|
|
54
|
+
function offer(id) {
|
|
55
|
+
const o = offers[id];
|
|
56
|
+
if (!o)
|
|
57
|
+
throw new Error(`the catalog lists no ${id} plan`);
|
|
58
|
+
return o;
|
|
59
|
+
}
|
|
60
|
+
/** Whether the catalog lists this plan. */
|
|
61
|
+
const has = (id) => offers[id] !== undefined;
|
|
62
|
+
exports.has = has;
|
|
63
|
+
/** Whether this plan is sold by the year. */
|
|
64
|
+
const yearly = (id) => offer(id).yearly !== null;
|
|
65
|
+
exports.yearly = yearly;
|
|
66
|
+
/** One unit's price per month at this interval (a year spread over its twelve months). */
|
|
67
|
+
function unit(id, interval) {
|
|
68
|
+
const o = offer(id);
|
|
69
|
+
return interval === 'annual' && o.yearly !== null ? cents(o.yearly / 12) : o.monthly;
|
|
70
|
+
}
|
|
67
71
|
/** What one unit costs per billing period: the month, or the year at once. */
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
function period(id, interval) {
|
|
73
|
+
const o = offer(id);
|
|
74
|
+
return interval === 'annual' && o.yearly !== null ? o.yearly : o.monthly;
|
|
75
|
+
}
|
|
70
76
|
/** What a year saves over twelve months, as a whole percent. */
|
|
71
|
-
|
|
77
|
+
function saving(id) {
|
|
78
|
+
const o = offer(id);
|
|
79
|
+
return o.yearly !== null && o.monthly > 0 ? Math.round((1 - o.yearly / (12 * o.monthly)) * 100) : 0;
|
|
80
|
+
}
|
|
72
81
|
function lines(id, interval, seats = 1) {
|
|
73
|
-
const n =
|
|
74
|
-
return { seats: n, subtotal: cents(
|
|
82
|
+
const n = offer(id).category === 'team' ? Math.max(exports.MIN_SEATS, Math.min(exports.MAX_SEATS, Math.floor(seats))) : 1;
|
|
83
|
+
return { seats: n, subtotal: cents(period(id, interval) * n), perMonth: cents(unit(id, interval) * n) };
|
|
75
84
|
}
|
|
76
|
-
/** GA4-shaped item for a commerce event: price is per unit, quantity is seats. */
|
|
85
|
+
/** GA4-shaped item for a commerce event: price is per unit, quantity is seats. Both Max tiers are item `max`. */
|
|
77
86
|
function item(id, interval, seats = 1) {
|
|
78
|
-
const o =
|
|
79
|
-
return { item_id: id, item_name: o.name, item_category: o.category, item_variant: interval, price:
|
|
87
|
+
const o = offer(id);
|
|
88
|
+
return { item_id: id.startsWith('max') ? 'max' : id, item_name: o.name, item_category: o.category, item_variant: interval, price: period(id, interval), quantity: lines(id, interval, seats).seats };
|
|
80
89
|
}
|
|
81
90
|
const usd = (n) => `$${n.toFixed(2)}`;
|
|
82
91
|
exports.usd = usd;
|
|
83
|
-
/** `$
|
|
92
|
+
/** `$20` when whole, `$16.67` when not. */
|
|
84
93
|
const money = (n) => (Number.isInteger(n) ? `$${n}` : (0, exports.usd)(n));
|
|
85
94
|
exports.money = money;
|
|
86
|
-
/** The commerce catalog's slug for a plan, and the quantity it is bought at. */
|
|
87
|
-
exports.SLUG = { free: 'free', dev: 'dev', max: 'max', team_standard: 'team-standard', team_premium: 'team-premium' };
|