@hanzo/ui 8.27.31 → 8.27.35
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/consent/Consent.cjs +76 -0
- package/dist/consent/Consent.d.ts +13 -0
- package/dist/consent/Consent.d.ts.map +1 -0
- package/dist/consent/Consent.js +72 -0
- package/dist/consent/Consent.js.map +1 -0
- package/dist/consent/index.cjs +7 -0
- package/dist/consent/index.d.ts +2 -0
- package/dist/consent/index.d.ts.map +1 -0
- package/dist/consent/index.js +2 -0
- package/dist/consent/index.js.map +1 -0
- package/dist/gallery.cjs +11 -0
- package/dist/gallery.d.ts.map +1 -1
- package/dist/gallery.html +5 -5
- package/dist/gallery.js +11 -0
- 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/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/Plans.cjs +14 -8
- package/dist/marketing/Plans.d.ts +5 -3
- package/dist/marketing/Plans.d.ts.map +1 -1
- package/dist/marketing/Plans.js +15 -9
- package/dist/marketing/Plans.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/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 +18 -8
- package/dist/onboarding/Onboarding.d.ts +5 -1
- package/dist/onboarding/Onboarding.d.ts.map +1 -1
- package/dist/onboarding/Onboarding.js +19 -9
- package/dist/onboarding/Onboarding.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 +2 -3
- package/dist/onboarding/frame.d.ts +3 -2
- package/dist/onboarding/frame.d.ts.map +1 -1
- package/dist/onboarding/frame.js +2 -3
- package/dist/onboarding/frame.js.map +1 -1
- package/dist/onboarding/index.cjs +7 -3
- package/dist/onboarding/index.d.ts +2 -1
- package/dist/onboarding/index.d.ts.map +1 -1
- package/dist/onboarding/index.js +2 -1
- 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 +8 -7
- package/dist/onboarding/screens.d.ts +2 -1
- package/dist/onboarding/screens.d.ts.map +1 -1
- package/dist/onboarding/screens.js +9 -8
- package/dist/onboarding/screens.js.map +1 -1
- package/package.json +12 -1
|
@@ -6,10 +6,12 @@ import { Checkout } from './Checkout.js';
|
|
|
6
6
|
import { Page } from './frame.js';
|
|
7
7
|
import { Enterprise, Plans, Seats, TeamName, UseCards } from './screens.js';
|
|
8
8
|
import { useSession } from './hooks.js';
|
|
9
|
-
import {
|
|
9
|
+
import { useCatalog } from './catalog.js';
|
|
10
|
+
import { ENTERPRISE_FROM, MIN_SEATS, OFFERS, offer, item } from './plans.js';
|
|
10
11
|
import { step as nextStep } from './state.js';
|
|
11
|
-
export function Onboarding({ site = 'Hanzo', api = API, track, onDone, onAsk, termsPath = '/terms', upgrade = null, onTeam }) {
|
|
12
|
+
export function Onboarding({ site = 'Hanzo', api = API, track, onDone, onAsk, termsPath = '/terms', upgrade = null, open, from, onClose, onTeam }) {
|
|
12
13
|
const session = useSession(api);
|
|
14
|
+
const catalog = useCatalog(api);
|
|
13
15
|
const [view, setView] = useState(null);
|
|
14
16
|
const [interval, setInterval] = useState(upgrade?.interval ?? 'monthly');
|
|
15
17
|
const [buy, setBuy] = useState(upgrade ? { plan: upgrade.plan, seats: upgrade.seats ?? 1 } : null);
|
|
@@ -17,13 +19,19 @@ export function Onboarding({ site = 'Hanzo', api = API, track, onDone, onAsk, te
|
|
|
17
19
|
const decided = useRef(false);
|
|
18
20
|
// The first screen is the first step not yet finished. An upgrade opens the checkout.
|
|
19
21
|
useEffect(() => {
|
|
20
|
-
if (session.loading || decided.current)
|
|
22
|
+
if (session.loading || catalog === null || decided.current)
|
|
21
23
|
return;
|
|
22
24
|
decided.current = true;
|
|
25
|
+
if (upgrade || open === 'plans')
|
|
26
|
+
track?.('upgrade_clicked', { from: from ?? 'app' });
|
|
23
27
|
if (upgrade) {
|
|
24
28
|
setView('checkout');
|
|
25
29
|
return;
|
|
26
30
|
}
|
|
31
|
+
if (open) {
|
|
32
|
+
setView(open);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
27
35
|
const s = nextStep(session.progress);
|
|
28
36
|
if (s === 'done')
|
|
29
37
|
onDone({ use: session.progress.use, plan: session.progress.plan, org: session.progress.team });
|
|
@@ -31,13 +39,15 @@ export function Onboarding({ site = 'Hanzo', api = API, track, onDone, onAsk, te
|
|
|
31
39
|
setView(s);
|
|
32
40
|
// Once, when the answer arrives.
|
|
33
41
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34
|
-
}, [session.loading]);
|
|
42
|
+
}, [session.loading, catalog]);
|
|
35
43
|
useEffect(() => {
|
|
36
44
|
if (view === 'plans' || view === 'seats')
|
|
37
|
-
track?.('pricing_viewed', { from: 'onboarding', items: Object.values(OFFERS).filter((o) => (view === 'plans' ? o.category === 'individual' : o.category === 'team')).map((o) => item(o.id, interval)) });
|
|
45
|
+
track?.('pricing_viewed', { from: 'onboarding', items: Object.values(OFFERS).filter((o) => o !== undefined).filter((o) => (view === 'plans' ? o.category === 'individual' : o.category === 'team')).map((o) => item(o.id, interval)) });
|
|
38
46
|
// A screen is viewed once.
|
|
39
47
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
48
|
}, [view]);
|
|
49
|
+
if (catalog === false)
|
|
50
|
+
return _jsx(Page, { site: site, title: "Plans could not be loaded just now", lede: "That is ours to fix. Reload to try again.", center: true });
|
|
41
51
|
if (!view)
|
|
42
52
|
return _jsx(Page, { site: site, title: "", busy: true });
|
|
43
53
|
const org = team ?? session.progress.team;
|
|
@@ -54,7 +64,7 @@ export function Onboarding({ site = 'Hanzo', api = API, track, onDone, onAsk, te
|
|
|
54
64
|
}, onAsk: onAsk }) }));
|
|
55
65
|
}
|
|
56
66
|
if (view === 'plans') {
|
|
57
|
-
return (_jsx(Page, { site: site, title: "Plans that grow with you", width: 1140, children: _jsx(Plans, { interval: interval, setInterval: (i) => {
|
|
67
|
+
return (_jsx(Page, { site: site, title: "Plans that grow with you", width: 1140, back: open === 'plans' ? onClose : undefined, children: _jsx(Plans, { interval: interval, setInterval: (i) => {
|
|
58
68
|
track?.('plan_changed', { from: interval, to: i, field: 'interval' });
|
|
59
69
|
setInterval(i);
|
|
60
70
|
}, onFree: () => {
|
|
@@ -68,7 +78,7 @@ export function Onboarding({ site = 'Hanzo', api = API, track, onDone, onAsk, te
|
|
|
68
78
|
} }) }));
|
|
69
79
|
}
|
|
70
80
|
if (view === 'team') {
|
|
71
|
-
return (_jsx(Page, { site: site, title: "Let\u2019s create your team", start: true, back: () => setView('use'), lede: "Team plans are best for groups up to 150 people. Choose a team name that invited members will easily recognize.", children: _jsx(TeamName, { api: api, onCreated: async (handle) => {
|
|
81
|
+
return (_jsx(Page, { site: site, title: "Let\u2019s create your team", start: true, back: open === 'team' && onClose ? onClose : () => setView('use'), lede: "Team plans are best for groups up to 150 people. Choose a team name that invited members will easily recognize.", children: _jsx(TeamName, { api: api, onCreated: async (handle) => {
|
|
72
82
|
await onTeam?.(handle);
|
|
73
83
|
track?.('team_created', {});
|
|
74
84
|
setTeam(handle);
|
|
@@ -99,9 +109,9 @@ export function Onboarding({ site = 'Hanzo', api = API, track, onDone, onAsk, te
|
|
|
99
109
|
} }) }));
|
|
100
110
|
}
|
|
101
111
|
const b = buy ?? { plan: 'dev', seats: 1 };
|
|
102
|
-
return (_jsx(Checkout, { site: site, api: api, org:
|
|
112
|
+
return (_jsx(Checkout, { site: site, api: api, org: offer(b.plan).category === 'team' ? org : undefined, plan: b.plan, seats: b.seats, interval: interval, setInterval: setInterval, setPlan: (plan) => setBuy({ plan, seats: 1 }), track: track, termsPath: termsPath, back: () => setView(offer(b.plan).category === 'team' ? 'seats' : 'plans'), onPaid: () => {
|
|
103
113
|
void session.save({ plan: b.plan });
|
|
104
|
-
onDone({ use:
|
|
114
|
+
onDone({ use: offer(b.plan).category === 'team' ? 'team' : 'personal', plan: b.plan, org });
|
|
105
115
|
} }));
|
|
106
116
|
}
|
|
107
117
|
//# sourceMappingURL=Onboarding.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Onboarding.js","sourceRoot":"","sources":["../../src/onboarding/Onboarding.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAC3B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC9B,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACxE,OAAO,EAAE,UAAU,EAAc,MAAM,SAAS,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAA8B,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"Onboarding.js","sourceRoot":"","sources":["../../src/onboarding/Onboarding.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadCatalog = loadCatalog;
|
|
4
|
+
exports.useCatalog = useCatalog;
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const api_1 = require("./api.cjs");
|
|
7
|
+
const plans_1 = require("./plans.cjs");
|
|
8
|
+
const loads = new Map();
|
|
9
|
+
/** Read the live catalog once per origin; a failed read is tried again next time. */
|
|
10
|
+
function loadCatalog(api) {
|
|
11
|
+
let p = loads.get(api);
|
|
12
|
+
if (!p) {
|
|
13
|
+
p = (0, api_1.call)(api, '/v1/billing/plans').then((r) => (0, plans_1.adopt)(Array.isArray(r) ? r : r.plans));
|
|
14
|
+
p.catch(() => loads.delete(api));
|
|
15
|
+
loads.set(api, p);
|
|
16
|
+
}
|
|
17
|
+
return p;
|
|
18
|
+
}
|
|
19
|
+
/** Whether the catalog has loaded (`null` while it is being read), so no screen prices from nothing. */
|
|
20
|
+
function useCatalog(api) {
|
|
21
|
+
const [ok, setOk] = (0, react_1.useState)(null);
|
|
22
|
+
(0, react_1.useEffect)(() => {
|
|
23
|
+
let live = true;
|
|
24
|
+
loadCatalog(api).then(() => live && setOk(true), () => live && setOk(false));
|
|
25
|
+
return () => {
|
|
26
|
+
live = false;
|
|
27
|
+
};
|
|
28
|
+
}, [api]);
|
|
29
|
+
return ok;
|
|
30
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Read the live catalog once per origin; a failed read is tried again next time. */
|
|
2
|
+
export declare function loadCatalog(api: string): Promise<void>;
|
|
3
|
+
/** Whether the catalog has loaded (`null` while it is being read), so no screen prices from nothing. */
|
|
4
|
+
export declare function useCatalog(api: string): boolean | null;
|
|
5
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/onboarding/catalog.ts"],"names":[],"mappings":"AAMA,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQtD;AAED,wGAAwG;AACxG,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAatD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { call } from './api.js';
|
|
3
|
+
import { adopt } from './plans.js';
|
|
4
|
+
const loads = new Map();
|
|
5
|
+
/** Read the live catalog once per origin; a failed read is tried again next time. */
|
|
6
|
+
export function loadCatalog(api) {
|
|
7
|
+
let p = loads.get(api);
|
|
8
|
+
if (!p) {
|
|
9
|
+
p = call(api, '/v1/billing/plans').then((r) => adopt(Array.isArray(r) ? r : r.plans));
|
|
10
|
+
p.catch(() => loads.delete(api));
|
|
11
|
+
loads.set(api, p);
|
|
12
|
+
}
|
|
13
|
+
return p;
|
|
14
|
+
}
|
|
15
|
+
/** Whether the catalog has loaded (`null` while it is being read), so no screen prices from nothing. */
|
|
16
|
+
export function useCatalog(api) {
|
|
17
|
+
const [ok, setOk] = useState(null);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
let live = true;
|
|
20
|
+
loadCatalog(api).then(() => live && setOk(true), () => live && setOk(false));
|
|
21
|
+
return () => {
|
|
22
|
+
live = false;
|
|
23
|
+
};
|
|
24
|
+
}, [api]);
|
|
25
|
+
return ok;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/onboarding/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAY,MAAM,SAAS,CAAA;AAEzC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAA;AAE9C,qFAAqF;AACrF,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACtB,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,CAAC,GAAG,IAAI,CAA2B,GAAG,EAAE,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QAC/G,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QAChC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IACnB,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC,CAAA;IAClD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,GAAG,IAAI,CAAA;QACf,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CACnB,GAAG,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,EACzB,GAAG,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,CAC3B,CAAA;QACD,OAAO,GAAG,EAAE;YACV,IAAI,GAAG,KAAK,CAAA;QACd,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IACT,OAAO,EAAE,CAAA;AACX,CAAC"}
|
|
@@ -13,7 +13,6 @@ const card_1 = require("../backends/gui/card.cjs");
|
|
|
13
13
|
const layout_1 = require("../backends/gui/layout.cjs");
|
|
14
14
|
const spinner_1 = require("../backends/gui/spinner.cjs");
|
|
15
15
|
const toggle_group_1 = require("../backends/gui/toggle-group.cjs");
|
|
16
|
-
const plans_1 = require("./plans.cjs");
|
|
17
16
|
/**
|
|
18
17
|
* One page of onboarding: the product's mark, a title, a line under it, and the
|
|
19
18
|
* screen. No progress bar and no step counter. `width` sets how much room the
|
|
@@ -27,8 +26,8 @@ function Panel({ children, label }) {
|
|
|
27
26
|
return ((0, jsx_runtime_1.jsx)(card_1.Card, { "aria-label": label, bg: "$panel", width: "100%", children: (0, jsx_runtime_1.jsx)(card_1.CardContent, { gap: "$3", children: children }) }));
|
|
28
27
|
}
|
|
29
28
|
/** Monthly or Yearly, with what a year saves. `name` says which plan it changes, for screen readers. */
|
|
30
|
-
function IntervalToggle({ interval, onChange, name }) {
|
|
31
|
-
return ((0, jsx_runtime_1.jsxs)(toggle_group_1.ToggleGroup, { type: "single", size: "sm", value: interval, disableDeactivation: true, "aria-label": `Billing interval for ${name}`, onValueChange: (v) => onChange(v), children: [(0, jsx_runtime_1.jsx)(toggle_group_1.ToggleGroupItem, { value: "monthly", children: "Monthly" }), (0, jsx_runtime_1.jsx)(toggle_group_1.ToggleGroupItem, { value: "annual", children: `Yearly · Save ${
|
|
29
|
+
function IntervalToggle({ interval, onChange, name, save }) {
|
|
30
|
+
return ((0, jsx_runtime_1.jsxs)(toggle_group_1.ToggleGroup, { type: "single", size: "sm", value: interval, disableDeactivation: true, "aria-label": `Billing interval for ${name}`, onValueChange: (v) => onChange(v), children: [(0, jsx_runtime_1.jsx)(toggle_group_1.ToggleGroupItem, { value: "monthly", children: "Monthly" }), (0, jsx_runtime_1.jsx)(toggle_group_1.ToggleGroupItem, { value: "annual", children: `Yearly · Save ${save}%` })] }));
|
|
32
31
|
}
|
|
33
32
|
/** A line of an order: what, and how much. `muted` for the lines that are not the total. */
|
|
34
33
|
function Line({ label, note, value, muted, strong }) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import type { Interval } from './plans.js';
|
|
3
3
|
/**
|
|
4
4
|
* One page of onboarding: the product's mark, a title, a line under it, and the
|
|
5
5
|
* screen. No progress bar and no step counter. `width` sets how much room the
|
|
@@ -23,10 +23,11 @@ export declare function Panel({ children, label }: {
|
|
|
23
23
|
label?: string;
|
|
24
24
|
}): import("react").JSX.Element;
|
|
25
25
|
/** Monthly or Yearly, with what a year saves. `name` says which plan it changes, for screen readers. */
|
|
26
|
-
export declare function IntervalToggle({ interval, onChange, name }: {
|
|
26
|
+
export declare function IntervalToggle({ interval, onChange, name, save }: {
|
|
27
27
|
interval: Interval;
|
|
28
28
|
onChange: (i: Interval) => void;
|
|
29
29
|
name: string;
|
|
30
|
+
save: number;
|
|
30
31
|
}): import("react").JSX.Element;
|
|
31
32
|
/** A line of an order: what, and how much. `muted` for the lines that are not the total. */
|
|
32
33
|
export declare function Line({ label, note, value, muted, strong }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../../src/onboarding/frame.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAQtC,OAAO,
|
|
1
|
+
{"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../../src/onboarding/frame.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAQtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,KAAW,EACX,KAAK,EACL,IAAI,GACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,IAAI,CAAA;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kFAAkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,+BAoCA;AAED,uFAAuF;AACvF,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,+BAMjF;AAED,wGAAwG;AACxG,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,+BAOrJ;AAED,4FAA4F;AAC5F,wBAAgB,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,+BAoBtJ"}
|
package/dist/onboarding/frame.js
CHANGED
|
@@ -7,7 +7,6 @@ import { Card, CardContent } from '../backends/gui/card.js';
|
|
|
7
7
|
import { Heading, Paragraph, SizableText, XStack, YStack } from '../backends/gui/layout.js';
|
|
8
8
|
import { Spinner } from '../backends/gui/spinner.js';
|
|
9
9
|
import { ToggleGroup, ToggleGroupItem } from '../backends/gui/toggle-group.js';
|
|
10
|
-
import { saving } from './plans.js';
|
|
11
10
|
/**
|
|
12
11
|
* One page of onboarding: the product's mark, a title, a line under it, and the
|
|
13
12
|
* screen. No progress bar and no step counter. `width` sets how much room the
|
|
@@ -21,8 +20,8 @@ export function Panel({ children, label }) {
|
|
|
21
20
|
return (_jsx(Card, { "aria-label": label, bg: "$panel", width: "100%", children: _jsx(CardContent, { gap: "$3", children: children }) }));
|
|
22
21
|
}
|
|
23
22
|
/** 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 ${
|
|
23
|
+
export function IntervalToggle({ interval, onChange, name, save }) {
|
|
24
|
+
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
25
|
}
|
|
27
26
|
/** A line of an order: what, and how much. `muted` for the lines that are not the total. */
|
|
28
27
|
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;;AAGZ,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAC/C,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;
|
|
1
|
+
{"version":3,"file":"frame.js","sourceRoot":"","sources":["../../src/onboarding/frame.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
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.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.chatStep = exports.useSession = exports.useOnboarded = 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
|
|
@@ -23,18 +23,22 @@ var state_1 = require("./state.cjs");
|
|
|
23
23
|
Object.defineProperty(exports, "chatStep", { enumerable: true, get: function () { return state_1.chatStep; } });
|
|
24
24
|
Object.defineProperty(exports, "step", { enumerable: true, get: function () { return state_1.step; } });
|
|
25
25
|
var plans_1 = require("./plans.cjs");
|
|
26
|
-
Object.defineProperty(exports, "
|
|
26
|
+
Object.defineProperty(exports, "adopt", { enumerable: true, get: function () { return plans_1.adopt; } });
|
|
27
27
|
Object.defineProperty(exports, "ENTERPRISE_FROM", { enumerable: true, get: function () { return plans_1.ENTERPRISE_FROM; } });
|
|
28
|
+
Object.defineProperty(exports, "has", { enumerable: true, get: function () { return plans_1.has; } });
|
|
28
29
|
Object.defineProperty(exports, "item", { enumerable: true, get: function () { return plans_1.item; } });
|
|
29
30
|
Object.defineProperty(exports, "lines", { enumerable: true, get: function () { return plans_1.lines; } });
|
|
30
31
|
Object.defineProperty(exports, "MAX_SEATS", { enumerable: true, get: function () { return plans_1.MAX_SEATS; } });
|
|
31
32
|
Object.defineProperty(exports, "MIN_SEATS", { enumerable: true, get: function () { return plans_1.MIN_SEATS; } });
|
|
33
|
+
Object.defineProperty(exports, "offer", { enumerable: true, get: function () { return plans_1.offer; } });
|
|
32
34
|
Object.defineProperty(exports, "OFFERS", { enumerable: true, get: function () { return plans_1.OFFERS; } });
|
|
33
35
|
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
36
|
Object.defineProperty(exports, "saving", { enumerable: true, get: function () { return plans_1.saving; } });
|
|
36
37
|
Object.defineProperty(exports, "SLUG", { enumerable: true, get: function () { return plans_1.SLUG; } });
|
|
37
38
|
Object.defineProperty(exports, "unit", { enumerable: true, get: function () { return plans_1.unit; } });
|
|
39
|
+
var catalog_1 = require("./catalog.cjs");
|
|
40
|
+
Object.defineProperty(exports, "loadCatalog", { enumerable: true, get: function () { return catalog_1.loadCatalog; } });
|
|
41
|
+
Object.defineProperty(exports, "useCatalog", { enumerable: true, get: function () { return catalog_1.useCatalog; } });
|
|
38
42
|
var roles_1 = require("./roles.cjs");
|
|
39
43
|
Object.defineProperty(exports, "OWN_TOPIC", { enumerable: true, get: function () { return roles_1.OWN_TOPIC; } });
|
|
40
44
|
Object.defineProperty(exports, "ROLES", { enumerable: true, get: function () { return roles_1.ROLES; } });
|
|
@@ -12,7 +12,8 @@ export { ChatOnboarding, type ChatOnboardingProps } from './ChatOnboarding.js';
|
|
|
12
12
|
export { Checkout, type CheckoutProps } from './Checkout.js';
|
|
13
13
|
export { useOnboarded, useSession, type Session, type Track } from './hooks.js';
|
|
14
14
|
export { chatStep, step, type ChatStep, type Progress, type Step, type Use } from './state.js';
|
|
15
|
-
export {
|
|
15
|
+
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';
|
|
16
|
+
export { loadCatalog, useCatalog } from './catalog.js';
|
|
16
17
|
export { OWN_TOPIC, ROLES, type Role, type Starter } from './roles.js';
|
|
17
18
|
export { API, preferences } from './api.js';
|
|
18
19
|
//# 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;AAC5E,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,GAAG,EAAE,MAAM,SAAS,CAAA;AAC3F,OAAO,EAAE,
|
|
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;AAC5E,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,GAAG,EAAE,MAAM,SAAS,CAAA;AAC3F,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,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA"}
|
package/dist/onboarding/index.js
CHANGED
|
@@ -12,7 +12,8 @@ export { ChatOnboarding } from './ChatOnboarding.js';
|
|
|
12
12
|
export { Checkout } from './Checkout.js';
|
|
13
13
|
export { useOnboarded, useSession } from './hooks.js';
|
|
14
14
|
export { chatStep, step } from './state.js';
|
|
15
|
-
export {
|
|
15
|
+
export { adopt, ENTERPRISE_FROM, has, item, lines, MAX_SEATS, MIN_SEATS, offer, OFFERS, period, saving, SLUG, unit } from './plans.js';
|
|
16
|
+
export { loadCatalog, useCatalog } from './catalog.js';
|
|
16
17
|
export { OWN_TOPIC, ROLES } from './roles.js';
|
|
17
18
|
export { API, preferences } from './api.js';
|
|
18
19
|
//# 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;AAC5E,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAqD,MAAM,SAAS,CAAA;AAC3F,OAAO,EAAE,
|
|
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;AAC5E,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAqD,MAAM,SAAS,CAAA;AAC3F,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,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' };
|