@connextar/house 0.3.0 → 0.5.0
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/README.md +242 -6
- package/dist/setup-guide/bits.d.ts +89 -0
- package/dist/setup-guide/bits.d.ts.map +1 -0
- package/dist/setup-guide/bits.js +134 -0
- package/dist/setup-guide/bits.js.map +1 -0
- package/dist/setup-guide/card.d.ts +33 -0
- package/dist/setup-guide/card.d.ts.map +1 -0
- package/dist/setup-guide/card.js +56 -0
- package/dist/setup-guide/card.js.map +1 -0
- package/dist/setup-guide/class-names.d.ts +68 -0
- package/dist/setup-guide/class-names.d.ts.map +1 -0
- package/dist/setup-guide/class-names.js +63 -0
- package/dist/setup-guide/class-names.js.map +1 -0
- package/dist/setup-guide/context.d.ts +89 -0
- package/dist/setup-guide/context.d.ts.map +1 -0
- package/dist/setup-guide/context.js +124 -0
- package/dist/setup-guide/context.js.map +1 -0
- package/dist/setup-guide/guide.d.ts +159 -0
- package/dist/setup-guide/guide.d.ts.map +1 -0
- package/dist/setup-guide/guide.js +128 -0
- package/dist/setup-guide/guide.js.map +1 -0
- package/dist/setup-guide/index.d.ts +27 -0
- package/dist/setup-guide/index.d.ts.map +1 -0
- package/dist/setup-guide/index.js +27 -0
- package/dist/setup-guide/index.js.map +1 -0
- package/dist/setup-guide/launcher.d.ts +38 -0
- package/dist/setup-guide/launcher.d.ts.map +1 -0
- package/dist/setup-guide/launcher.js +60 -0
- package/dist/setup-guide/launcher.js.map +1 -0
- package/dist/setup-guide/strip.d.ts +21 -0
- package/dist/setup-guide/strip.d.ts.map +1 -0
- package/dist/setup-guide/strip.js +42 -0
- package/dist/setup-guide/strip.js.map +1 -0
- package/dist/wizard/index.d.ts +26 -0
- package/dist/wizard/index.d.ts.map +1 -0
- package/dist/wizard/index.js +26 -0
- package/dist/wizard/index.js.map +1 -0
- package/dist/wizard/invalid.d.ts +91 -0
- package/dist/wizard/invalid.d.ts.map +1 -0
- package/dist/wizard/invalid.js +121 -0
- package/dist/wizard/invalid.js.map +1 -0
- package/dist/wizard/react-hook-form-index.d.ts +12 -0
- package/dist/wizard/react-hook-form-index.d.ts.map +1 -0
- package/dist/wizard/react-hook-form-index.js +12 -0
- package/dist/wizard/react-hook-form-index.js.map +1 -0
- package/dist/wizard/rhf-adapter.d.ts +32 -0
- package/dist/wizard/rhf-adapter.d.ts.map +1 -0
- package/dist/wizard/rhf-adapter.js +58 -0
- package/dist/wizard/rhf-adapter.js.map +1 -0
- package/dist/wizard/rules.d.ts +92 -0
- package/dist/wizard/rules.d.ts.map +1 -0
- package/dist/wizard/rules.js +105 -0
- package/dist/wizard/rules.js.map +1 -0
- package/dist/wizard/wizard.d.ts +127 -0
- package/dist/wizard/wizard.d.ts.map +1 -0
- package/dist/wizard/wizard.js +195 -0
- package/dist/wizard/wizard.js.map +1 -0
- package/package.json +19 -2
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ArrowRight, Sparkles, Trophy } from "lucide-react";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { cx } from "../internal/cx.js";
|
|
6
|
+
import { GuideIconLink, HowToButton, ItemHelp, MiniProgress, RewardChip, RewardRing, Segments, StepCircle, useClassNames, } from "./bits.js";
|
|
7
|
+
import { SETUP_BAND_STYLE } from "./class-names.js";
|
|
8
|
+
import { rewardWord, useSetupGuide } from "./context.js";
|
|
9
|
+
export function SetupCard({ variant, title, lead, aside, actions = {}, inlineItemKey, fallback = null, completeAction, timeNote, rewardNote, bandStyle = SETUP_BAND_STYLE, className, classNames, }) {
|
|
10
|
+
const setup = useSetupGuide();
|
|
11
|
+
const c = useClassNames(classNames);
|
|
12
|
+
const guide = setup?.guide;
|
|
13
|
+
if (!setup || !guide || guide.hidden)
|
|
14
|
+
return _jsx(_Fragment, { children: fallback });
|
|
15
|
+
const words = setup.words;
|
|
16
|
+
if (guide.complete) {
|
|
17
|
+
return (_jsxs("section", { className: cx("flex flex-col items-start gap-4 rounded-2xl p-5 text-white sm:flex-row sm:items-center sm:p-6", className), style: bandStyle, children: [_jsx("span", { className: "flex size-12 shrink-0 items-center justify-center rounded-2xl bg-white/10 text-emerald-300", children: _jsx(Trophy, { className: "size-6", "aria-hidden": true }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-lg font-bold tracking-tight", children: "You're all set up" }), _jsxs("p", { className: "mt-1 text-sm text-slate-300", children: ["All ", guide.totalReward, " ", rewardWord(guide.totalReward, words), " are in your account."] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [completeAction, _jsx(HideButton, { setup: setup, className: c.bandQuietButton, label: "Hide this" })] })] }));
|
|
18
|
+
}
|
|
19
|
+
const left = guide.totalReward - guide.earnedReward;
|
|
20
|
+
const next = guide.items.find((item) => item.key === guide.nextKey) ?? null;
|
|
21
|
+
if (variant === "compact") {
|
|
22
|
+
return (_jsx("section", { "aria-label": "Get started", className: cx("@container rounded-2xl p-4 text-white sm:p-5", className), style: bandStyle, children: _jsxs("div", { className: "flex flex-col gap-4 @4xl:flex-row @4xl:items-center @4xl:gap-5", children: [_jsxs("div", { className: "flex items-center gap-4 @4xl:contents", children: [_jsx(RewardRing, { earned: guide.earnedReward, total: guide.totalReward, size: 64, words: words }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5 @4xl:w-60 @4xl:flex-none", children: [_jsxs("p", { className: "text-[15px] font-semibold", children: ["Get started \u00B7 ", guide.doneItems, " of ", guide.items.length, " steps done"] }), _jsxs("p", { className: "text-[13px] text-slate-300", children: [left, " more ", rewardWord(left, words), " to earn"] }), _jsx(Segments, { done: guide.doneItems, total: guide.items.length, classNames: classNames })] })] }), _jsx("span", { className: "hidden w-px self-stretch bg-white/10 @4xl:block", "aria-hidden": true }), next ? (_jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [_jsx("p", { className: "text-[11px] font-bold tracking-[0.14em] text-slate-400 uppercase", children: "Next up" }), _jsxs("p", { className: "flex flex-wrap items-center gap-2.5 text-[15px] font-semibold", children: [next.title, _jsx(RewardChip, { reward: next.reward - next.earnedReward, tone: "dark", words: words, classNames: classNames })] }), _jsxs("p", { className: "text-[13px] text-slate-300", children: [next.steps.length > 1 ? `${next.doneCount} of ${next.steps.length} done. ` : "", next.description] })] })) : (_jsx("p", { className: "flex-1 text-sm text-slate-300", children: "Every step you can do now is done \u2014 the rest follow on." })), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [next ? (actions[next.key] ?? _jsx(ItemLink, { item: next, variant: "primary", classNames: classNames })) : null, _jsx("button", { type: "button", onClick: () => setup.setPanelOpen(true), className: cx(c.button, c.bandQuietButton), children: "All steps" })] })] }) }));
|
|
23
|
+
}
|
|
24
|
+
return (_jsx("section", { "aria-label": "Get started", className: cx(c.card, "@container", className), children: _jsxs("div", { className: "flex flex-col @3xl:flex-row", children: [_jsxs("div", { className: cx(c.band, "@3xl:w-[340px] @3xl:shrink-0 @5xl:w-[380px]"), style: bandStyle, children: [_jsx("p", { className: c.bandEyebrow, children: "Get started" }), _jsx("h2", { className: c.bandTitle, children: title }), _jsx("p", { className: c.bandLead, children: lead }), _jsxs("div", { className: "mt-7 flex items-center gap-4", children: [_jsx(RewardRing, { earned: guide.earnedReward, total: guide.totalReward, words: words }), _jsxs("div", { className: "min-w-0", children: [_jsxs("p", { className: "flex items-center gap-1.5 text-sm font-semibold", children: [_jsx(Sparkles, { className: "size-4", "aria-hidden": true }), rewardWord(2, words), " earned"] }), rewardNote ? _jsx("p", { className: cx("mt-1 text-[12.5px] leading-normal", c.bandMuted), children: rewardNote }) : null] })] }), _jsxs("div", { className: "mt-6 flex flex-col gap-2", children: [_jsxs("div", { className: "flex justify-between gap-2 text-xs text-slate-300", children: [_jsxs("span", { children: [guide.doneItems, " of ", guide.items.length, " steps done"] }), timeNote ? _jsx("span", { className: c.bandMuted, children: timeNote }) : null] }), _jsx(Segments, { done: guide.doneItems, total: guide.items.length, classNames: classNames })] }), aside, _jsx("div", { className: "mt-auto flex flex-wrap items-center gap-x-5 gap-y-2 pt-7 text-sm", children: _jsx(HideButton, { setup: setup, className: c.bandQuietButton, label: "Hide for now" }) })] }), _jsxs("div", { className: cx(c.panel, "@container/steps"), children: [_jsxs("div", { className: "flex items-baseline justify-between gap-2 px-3 pb-2 sm:px-4", children: [_jsx("h3", { className: c.panelHeading, children: "Your setup steps" }), _jsxs("p", { className: c.panelNote, children: [left, " ", rewardWord(left, words), " to earn"] })] }), _jsx("ol", { children: guide.items.map((item, index) => (_jsx(ItemRow, { item: item, index: index, isNext: item.key === guide.nextKey, action: actions[item.key], inline: item.key === inlineItemKey, actions: actions, classNames: classNames }, item.key))) })] })] }) }));
|
|
25
|
+
}
|
|
26
|
+
function HideButton({ setup, className, label }) {
|
|
27
|
+
if (setup.readOnly)
|
|
28
|
+
return null;
|
|
29
|
+
return (_jsx("button", { type: "button", onClick: () => void setup.setHidden(true), className: className, children: label }));
|
|
30
|
+
}
|
|
31
|
+
function ItemLink({ item, variant, classNames, }) {
|
|
32
|
+
const c = useClassNames(classNames);
|
|
33
|
+
const setup = useSetupGuide();
|
|
34
|
+
const Link = setup?.Link ?? (({ children, ...rest }) => _jsx("a", { ...rest, children: children }));
|
|
35
|
+
return (_jsxs(Link, { href: item.href, className: cx(c.button, variant === "primary" ? c.buttonPrimary : c.buttonOutline), children: [item.actionLabel, variant === "primary" ? _jsx(ArrowRight, { className: "size-4", "aria-hidden": true }) : null] }));
|
|
36
|
+
}
|
|
37
|
+
function ItemRow({ item, index, isNext, action, inline, actions, classNames, }) {
|
|
38
|
+
const c = useClassNames(classNames);
|
|
39
|
+
const setup = useSetupGuide();
|
|
40
|
+
const words = setup?.words ?? { one: "credit", many: "credits" };
|
|
41
|
+
const state = item.done ? "done" : isNext ? "next" : "todo";
|
|
42
|
+
const paid = item.steps.length > 0 && item.steps.every((step) => step.earned);
|
|
43
|
+
const button = item.done ? null : item.blocked ? (_jsx("span", { className: c.blocked, children: item.blocked })) : isNext ? ((action ?? _jsx(ItemLink, { item: item, variant: "primary", classNames: classNames }))) : inline ? null : ((action ?? _jsx(ItemLink, { item: item, variant: "outline", classNames: classNames })));
|
|
44
|
+
return (_jsxs("li", { className: cx(c.row, isNext && c.rowNext, "@xl/steps:grid-cols-[auto_minmax(0,1fr)_auto]"), children: [_jsx(StepCircle, { state: state, n: index + 1, className: "mt-0.5 @xl/steps:row-span-2", classNames: classNames }), _jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-x-2.5 gap-y-1", children: [_jsxs("p", { className: cx(c.rowTitle, item.done && c.rowTitleDone), children: [item.title, _jsx("span", { className: c.srOnly, children: item.done ? " (done)" : " (to do)" })] }), item.steps.length > 1 ? _jsx(MiniProgress, { done: item.doneCount, total: item.steps.length }) : null] }), item.description ? _jsx("p", { className: c.rowDescription, children: item.description }) : null, inline && item.steps.length > 1 ? (_jsx("ul", { className: "mt-2", children: item.steps.map((step) => (_jsx(SubStepRow, { step: step, action: actions[step.key] ?? _jsx(StepLink, { step: step, href: item.href, classNames: classNames }), classNames: classNames }, step.key))) })) : null, isNext && button ? _jsx("div", { className: "mt-3 flex flex-wrap items-center gap-3", children: button }) : null] }), _jsxs("div", { className: "col-start-2 flex flex-wrap items-center gap-1 @xl/steps:col-start-3 @xl/steps:row-start-1 @xl/steps:justify-end", children: [item.reward > 0 ? (_jsx(RewardChip, { reward: item.reward, state: paid ? "earned" : "todo", words: words, classNames: classNames })) : null, item.done ? null : _jsx(ItemHelp, { item: item, classNames: classNames }), !isNext && button ? _jsx("span", { className: "ml-2 flex", children: button }) : null] })] }));
|
|
45
|
+
}
|
|
46
|
+
function StepLink({ step, href, classNames }) {
|
|
47
|
+
const c = useClassNames(classNames);
|
|
48
|
+
const setup = useSetupGuide();
|
|
49
|
+
const Link = setup?.Link ?? (({ children, ...rest }) => _jsx("a", { ...rest, children: children }));
|
|
50
|
+
return (_jsx(Link, { href: href, className: cx(c.button, step.done ? c.buttonQuiet : c.buttonOutline), children: step.done ? "Edit" : "Add" }));
|
|
51
|
+
}
|
|
52
|
+
function SubStepRow({ step, action, classNames, }) {
|
|
53
|
+
const c = useClassNames(classNames);
|
|
54
|
+
return (_jsxs("li", { className: c.subRow, children: [_jsx(StepCircle, { state: step.done ? "done" : "todo", size: "sm", classNames: classNames }), _jsxs("p", { className: cx("min-w-0 flex-1 text-sm font-medium", step.done && c.rowTitleDone), children: [step.title, _jsx("span", { className: c.srOnly, children: step.done ? " (done)" : " (to do)" })] }), step.reward > 0 ? (_jsx(RewardChip, { reward: step.reward, state: step.earned ? "earned" : "todo", classNames: classNames })) : null, step.done ? null : (_jsxs("span", { className: "inline-flex items-center", children: [step.how ? _jsx(HowToButton, { how: step.how, guide: step.guide, classNames: classNames }) : null, _jsx(GuideIconLink, { guide: step.guide, classNames: classNames })] })), _jsx("span", { className: "flex min-w-16 justify-end", children: action })] }));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.js","sourceRoot":"","sources":["../../src/setup-guide/card.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The house look, on the shared theme tokens. Every part an app might want to
|
|
3
|
+
* say differently is a key here, and `classNames` replaces the ones it names —
|
|
4
|
+
* the same bargain the wizard and the guide renderer offer.
|
|
5
|
+
*
|
|
6
|
+
* The one part that is not a class is the dark band behind the progress: it is
|
|
7
|
+
* a gradient over a token, so it is a style object (`bandStyle`) an app can
|
|
8
|
+
* replace outright. AltEd lights its evergreen ink from two corners; an app
|
|
9
|
+
* with no ink colour can pass `{}` and get the card's own background.
|
|
10
|
+
*/
|
|
11
|
+
export interface SetupGuideClassNames {
|
|
12
|
+
card: string;
|
|
13
|
+
band: string;
|
|
14
|
+
bandEyebrow: string;
|
|
15
|
+
bandTitle: string;
|
|
16
|
+
bandLead: string;
|
|
17
|
+
bandMuted: string;
|
|
18
|
+
bandLink: string;
|
|
19
|
+
bandQuietButton: string;
|
|
20
|
+
panel: string;
|
|
21
|
+
panelHeading: string;
|
|
22
|
+
panelNote: string;
|
|
23
|
+
row: string;
|
|
24
|
+
rowNext: string;
|
|
25
|
+
rowTitle: string;
|
|
26
|
+
rowTitleDone: string;
|
|
27
|
+
rowDescription: string;
|
|
28
|
+
subRow: string;
|
|
29
|
+
circle: string;
|
|
30
|
+
circleDone: string;
|
|
31
|
+
circleNext: string;
|
|
32
|
+
circleReady: string;
|
|
33
|
+
circleTodo: string;
|
|
34
|
+
chip: string;
|
|
35
|
+
chipEarned: string;
|
|
36
|
+
chipOnComplete: string;
|
|
37
|
+
chipDark: string;
|
|
38
|
+
bar: string;
|
|
39
|
+
barFill: string;
|
|
40
|
+
segment: string;
|
|
41
|
+
segmentDone: string;
|
|
42
|
+
segmentDoneDark: string;
|
|
43
|
+
segmentTodo: string;
|
|
44
|
+
segmentTodoDark: string;
|
|
45
|
+
button: string;
|
|
46
|
+
buttonPrimary: string;
|
|
47
|
+
buttonOutline: string;
|
|
48
|
+
buttonQuiet: string;
|
|
49
|
+
iconButton: string;
|
|
50
|
+
popover: string;
|
|
51
|
+
popoverTitle: string;
|
|
52
|
+
popoverStep: string;
|
|
53
|
+
popoverNumber: string;
|
|
54
|
+
popoverFooter: string;
|
|
55
|
+
strip: string;
|
|
56
|
+
stripTitle: string;
|
|
57
|
+
stripSummary: string;
|
|
58
|
+
stripTile: string;
|
|
59
|
+
stripTileNext: string;
|
|
60
|
+
launcher: string;
|
|
61
|
+
launcherBadge: string;
|
|
62
|
+
blocked: string;
|
|
63
|
+
srOnly: string;
|
|
64
|
+
}
|
|
65
|
+
export declare const SETUP_GUIDE_CLASS_NAMES: SetupGuideClassNames;
|
|
66
|
+
/** The dark band's background. Replaceable outright; `{}` falls back to the card. */
|
|
67
|
+
export declare const SETUP_BAND_STYLE: Record<string, string>;
|
|
68
|
+
//# sourceMappingURL=class-names.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class-names.d.ts","sourceRoot":"","sources":["../../src/setup-guide/class-names.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,uBAAuB,EAAE,oBA6DrC,CAAC;AAEF,qFAAqF;AACrF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMnD,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export const SETUP_GUIDE_CLASS_NAMES = {
|
|
2
|
+
card: "overflow-hidden rounded-2xl border border-border bg-card shadow-sm",
|
|
3
|
+
band: "flex flex-col p-6 text-white sm:p-8",
|
|
4
|
+
bandEyebrow: "text-xs font-bold tracking-[0.14em] text-emerald-300 uppercase",
|
|
5
|
+
bandTitle: "mt-3.5 text-2xl leading-tight font-bold tracking-tight text-balance",
|
|
6
|
+
bandLead: "mt-3 text-sm leading-relaxed text-slate-300",
|
|
7
|
+
bandMuted: "text-slate-400",
|
|
8
|
+
bandLink: "font-medium text-emerald-300 underline-offset-4 hover:underline",
|
|
9
|
+
bandQuietButton: "text-slate-400 hover:text-white focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none",
|
|
10
|
+
panel: "min-w-0 flex-1 p-3 sm:p-5",
|
|
11
|
+
panelHeading: "text-sm font-semibold",
|
|
12
|
+
panelNote: "text-xs text-muted-foreground",
|
|
13
|
+
row: "grid grid-cols-[auto_minmax(0,1fr)] gap-x-3.5 gap-y-2 border-b border-border px-3 py-3.5 last:border-b-0 sm:px-4",
|
|
14
|
+
rowNext: "my-1 rounded-xl border border-primary/25 bg-primary/5 px-3 py-4 sm:px-4",
|
|
15
|
+
rowTitle: "text-[15px] font-semibold",
|
|
16
|
+
rowTitleDone: "text-muted-foreground",
|
|
17
|
+
rowDescription: "mt-1 max-w-xl text-[13px] leading-normal text-muted-foreground",
|
|
18
|
+
subRow: "flex flex-wrap items-center gap-x-3 gap-y-1 border-t border-border py-2.5",
|
|
19
|
+
circle: "flex shrink-0 items-center justify-center rounded-full text-xs font-semibold tabular-nums",
|
|
20
|
+
circleDone: "bg-primary text-primary-foreground",
|
|
21
|
+
circleNext: "bg-primary text-primary-foreground ring-4 ring-primary/15",
|
|
22
|
+
circleReady: "border-[1.5px] border-primary bg-background text-primary",
|
|
23
|
+
circleTodo: "border-[1.5px] border-muted-foreground/40 bg-background text-muted-foreground",
|
|
24
|
+
chip: "inline-flex h-6 shrink-0 items-center gap-1 rounded-full border border-primary/30 bg-primary/10 px-2 text-xs font-semibold whitespace-nowrap tabular-nums text-primary",
|
|
25
|
+
chipEarned: "inline-flex h-6 shrink-0 items-center gap-1 px-0.5 text-xs font-semibold whitespace-nowrap tabular-nums text-primary",
|
|
26
|
+
chipOnComplete: "border-dashed border-primary/50 bg-background",
|
|
27
|
+
chipDark: "border-white/35 bg-white/10 text-white",
|
|
28
|
+
bar: "h-2 w-full overflow-hidden rounded-full bg-secondary",
|
|
29
|
+
barFill: "h-full rounded-full bg-primary transition-[width]",
|
|
30
|
+
segment: "h-1.5 flex-1 rounded-full",
|
|
31
|
+
segmentDone: "bg-primary",
|
|
32
|
+
segmentDoneDark: "bg-emerald-300",
|
|
33
|
+
segmentTodo: "bg-secondary",
|
|
34
|
+
segmentTodoDark: "bg-white/15",
|
|
35
|
+
button: "inline-flex items-center gap-1.5 rounded-md px-3 py-2 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none disabled:pointer-events-none disabled:opacity-60",
|
|
36
|
+
buttonPrimary: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
37
|
+
buttonOutline: "border border-border hover:bg-muted",
|
|
38
|
+
buttonQuiet: "text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
39
|
+
iconButton: "inline-flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none",
|
|
40
|
+
popover: "absolute right-0 z-50 mt-1 w-80 rounded-lg border border-border bg-popover p-4 text-popover-foreground shadow-lg",
|
|
41
|
+
popoverTitle: "text-sm font-semibold",
|
|
42
|
+
popoverStep: "flex gap-2.5 text-[13px] leading-normal",
|
|
43
|
+
popoverNumber: "mt-px flex size-5 shrink-0 items-center justify-center rounded-full bg-secondary text-[11px] font-bold text-secondary-foreground",
|
|
44
|
+
popoverFooter: "mt-3.5 flex items-center justify-between gap-2 border-t border-border pt-3",
|
|
45
|
+
strip: "rounded-2xl border border-border bg-card px-4 py-4 shadow-sm sm:px-5",
|
|
46
|
+
stripTitle: "text-[15px] font-semibold",
|
|
47
|
+
stripSummary: "text-[13px] text-muted-foreground",
|
|
48
|
+
stripTile: "flex min-h-[6.5rem] flex-col gap-2 rounded-xl border border-border bg-background p-3",
|
|
49
|
+
stripTileNext: "border-primary/35 bg-primary/5",
|
|
50
|
+
launcher: "relative inline-flex h-9 shrink-0 items-center gap-2 rounded-full border border-border bg-background py-0 pr-2.5 pl-1.5 text-[13px] font-semibold shadow-sm transition-colors hover:border-primary/40 hover:bg-accent focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none",
|
|
51
|
+
launcherBadge: "absolute -top-3 -right-2 rounded-full bg-primary px-1.5 py-0.5 text-xs leading-none font-semibold text-primary-foreground shadow-md",
|
|
52
|
+
blocked: "px-1.5 text-xs text-muted-foreground",
|
|
53
|
+
srOnly: "sr-only",
|
|
54
|
+
};
|
|
55
|
+
/** The dark band's background. Replaceable outright; `{}` falls back to the card. */
|
|
56
|
+
export const SETUP_BAND_STYLE = {
|
|
57
|
+
background: [
|
|
58
|
+
"radial-gradient(120% 70% at 0% 0%, color-mix(in oklab, var(--primary) 22%, transparent), transparent 55%)",
|
|
59
|
+
"radial-gradient(90% 60% at 100% 100%, color-mix(in oklab, var(--primary) 12%, transparent), transparent 60%)",
|
|
60
|
+
"#0e2f27",
|
|
61
|
+
].join(", "),
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=class-names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class-names.js","sourceRoot":"","sources":["../../src/setup-guide/class-names.ts"],"names":[],"mappings":"AAiEA,MAAM,CAAC,MAAM,uBAAuB,GAAyB;IAC3D,IAAI,EAAE,oEAAoE;IAC1E,IAAI,EAAE,qCAAqC;IAC3C,WAAW,EAAE,gEAAgE;IAC7E,SAAS,EAAE,qEAAqE;IAChF,QAAQ,EAAE,6CAA6C;IACvD,SAAS,EAAE,gBAAgB;IAC3B,QAAQ,EAAE,iEAAiE;IAC3E,eAAe,EACb,yGAAyG;IAC3G,KAAK,EAAE,2BAA2B;IAClC,YAAY,EAAE,uBAAuB;IACrC,SAAS,EAAE,+BAA+B;IAC1C,GAAG,EAAE,kHAAkH;IACvH,OAAO,EAAE,yEAAyE;IAClF,QAAQ,EAAE,2BAA2B;IACrC,YAAY,EAAE,uBAAuB;IACrC,cAAc,EAAE,gEAAgE;IAChF,MAAM,EAAE,2EAA2E;IACnF,MAAM,EAAE,2FAA2F;IACnG,UAAU,EAAE,oCAAoC;IAChD,UAAU,EAAE,2DAA2D;IACvE,WAAW,EAAE,0DAA0D;IACvE,UAAU,EAAE,+EAA+E;IAC3F,IAAI,EAAE,wKAAwK;IAC9K,UAAU,EACR,sHAAsH;IACxH,cAAc,EAAE,+CAA+C;IAC/D,QAAQ,EAAE,wCAAwC;IAClD,GAAG,EAAE,sDAAsD;IAC3D,OAAO,EAAE,mDAAmD;IAC5D,OAAO,EAAE,2BAA2B;IACpC,WAAW,EAAE,YAAY;IACzB,eAAe,EAAE,gBAAgB;IACjC,WAAW,EAAE,cAAc;IAC3B,eAAe,EAAE,aAAa;IAC9B,MAAM,EACJ,sNAAsN;IACxN,aAAa,EAAE,wDAAwD;IACvE,aAAa,EAAE,qCAAqC;IACpD,WAAW,EAAE,4DAA4D;IACzE,UAAU,EACR,gNAAgN;IAClN,OAAO,EACL,kHAAkH;IACpH,YAAY,EAAE,uBAAuB;IACrC,WAAW,EAAE,yCAAyC;IACtD,aAAa,EACX,kIAAkI;IACpI,aAAa,EAAE,4EAA4E;IAC3F,KAAK,EAAE,sEAAsE;IAC7E,UAAU,EAAE,2BAA2B;IACvC,YAAY,EAAE,mCAAmC;IACjD,SAAS,EAAE,sFAAsF;IACjG,aAAa,EAAE,gCAAgC;IAC/C,QAAQ,EACN,+RAA+R;IACjS,aAAa,EACX,qIAAqI;IACvI,OAAO,EAAE,sCAAsC;IAC/C,MAAM,EAAE,SAAS;CAClB,CAAC;AAEF,qFAAqF;AACrF,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACtD,UAAU,EAAE;QACV,2GAA2G;QAC3G,8GAA8G;QAC9G,SAAS;KACV,CAAC,IAAI,CAAC,IAAI,CAAC;CACb,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { SetupGuide, SetupReward } from "./guide.js";
|
|
3
|
+
/**
|
|
4
|
+
* The guide, shared by everything that draws it: a launcher in the header, a
|
|
5
|
+
* card on the home page, a strip on each screen where steps are done.
|
|
6
|
+
*
|
|
7
|
+
* The host reads the guide on the server and hands it in. What is *done* is
|
|
8
|
+
* always the server's answer — this never decides that. Paying for it is a
|
|
9
|
+
* separate request, made when the server's answer shows something done and
|
|
10
|
+
* unpaid, or shortly after any save, so the reward lands while the person is
|
|
11
|
+
* still looking at what earned it.
|
|
12
|
+
*
|
|
13
|
+
* Two things are deliberately the host's: the transport (this package makes no
|
|
14
|
+
* HTTP requests and knows no routes) and what a reward is called. MAS has no
|
|
15
|
+
* credits; an app that gives nothing at all passes steps with no reward and
|
|
16
|
+
* gets a checklist that still works.
|
|
17
|
+
*/
|
|
18
|
+
export interface SetupSyncResult {
|
|
19
|
+
guide: SetupGuide;
|
|
20
|
+
rewards: SetupReward[];
|
|
21
|
+
}
|
|
22
|
+
export interface SetupGuideTransport {
|
|
23
|
+
/**
|
|
24
|
+
* Pay for everything done and unpaid, and answer with the guide as it now
|
|
25
|
+
* stands. `null` means the request did not succeed — the provider keeps what
|
|
26
|
+
* it has and says nothing, because a failed sync is not the person's problem
|
|
27
|
+
* and will be retried by the next save.
|
|
28
|
+
*/
|
|
29
|
+
sync: (pathway: string) => Promise<SetupSyncResult | null>;
|
|
30
|
+
/** Hide the guide, or bring it back. `false` means it did not take. */
|
|
31
|
+
setHidden: (pathway: string, hidden: boolean) => Promise<boolean>;
|
|
32
|
+
}
|
|
33
|
+
/** What one of these is called, singular and plural. */
|
|
34
|
+
export interface RewardWords {
|
|
35
|
+
one: string;
|
|
36
|
+
many: string;
|
|
37
|
+
}
|
|
38
|
+
export declare const DEFAULT_REWARD_WORDS: RewardWords;
|
|
39
|
+
export declare function rewardWord(count: number, words: RewardWords): string;
|
|
40
|
+
export interface SetupLinkProps {
|
|
41
|
+
href: string;
|
|
42
|
+
children: React.ReactNode;
|
|
43
|
+
className?: string;
|
|
44
|
+
onClick?: () => void;
|
|
45
|
+
target?: string;
|
|
46
|
+
rel?: string;
|
|
47
|
+
title?: string;
|
|
48
|
+
"aria-label"?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* How a link is drawn. The default is a plain `<a>`, which works everywhere and
|
|
52
|
+
* costs a full page load; an app with a router passes its own so the guide
|
|
53
|
+
* navigates the way the rest of the app does.
|
|
54
|
+
*/
|
|
55
|
+
export type SetupLinkComponent = (props: SetupLinkProps) => React.ReactNode;
|
|
56
|
+
export interface SetupGuideState {
|
|
57
|
+
guide: SetupGuide | null;
|
|
58
|
+
/** Somebody viewing this account rather than living in it: shown, never paid or changed. */
|
|
59
|
+
readOnly: boolean;
|
|
60
|
+
words: RewardWords;
|
|
61
|
+
Link: SetupLinkComponent;
|
|
62
|
+
panelOpen: boolean;
|
|
63
|
+
setPanelOpen: (open: boolean) => void;
|
|
64
|
+
setHidden: (hidden: boolean) => Promise<void>;
|
|
65
|
+
/** Paid a moment ago, for the launcher to flash. */
|
|
66
|
+
justEarned: number | null;
|
|
67
|
+
}
|
|
68
|
+
/** Null outside the provider, and for accounts with no guide — every part checks. */
|
|
69
|
+
export declare function useSetupGuide(): SetupGuideState | null;
|
|
70
|
+
export interface SetupGuideProviderProps {
|
|
71
|
+
initial: SetupGuide | null;
|
|
72
|
+
transport: SetupGuideTransport;
|
|
73
|
+
readOnly?: boolean;
|
|
74
|
+
words?: RewardWords;
|
|
75
|
+
/**
|
|
76
|
+
* A window event the app fires after a successful write. Without one the
|
|
77
|
+
* guide only catches up when the page is read again, which is correct but
|
|
78
|
+
* slower — the reward lands on the next navigation rather than in front of
|
|
79
|
+
* the person who earned it.
|
|
80
|
+
*/
|
|
81
|
+
changeEvent?: string;
|
|
82
|
+
settleMs?: number;
|
|
83
|
+
/** Called when bringing a hidden guide back, which needs a fresh read. */
|
|
84
|
+
onRefresh?: () => void;
|
|
85
|
+
link?: SetupLinkComponent;
|
|
86
|
+
children: React.ReactNode;
|
|
87
|
+
}
|
|
88
|
+
export declare function SetupGuideProvider({ initial, transport, readOnly, words, changeEvent, settleMs, onRefresh, link, children, }: SetupGuideProviderProps): React.JSX.Element;
|
|
89
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/setup-guide/context.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAC3D,uEAAuE;IACvE,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACnE;AAED,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,oBAAoB,EAAE,WAAgD,CAAC;AAEpF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CAEpE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,KAAK,CAAC,SAAS,CAAC;AAI5E,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,4FAA4F;IAC5F,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,oDAAoD;IACpD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAID,qFAAqF;AACrF,wBAAgB,aAAa,IAAI,eAAe,GAAG,IAAI,CAEtD;AAOD,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,mBAAmB,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,SAAS,EACT,QAAgB,EAChB,KAA4B,EAC5B,WAAW,EACX,QAAoB,EACpB,SAAS,EACT,IAAgB,EAChB,QAAQ,GACT,EAAE,uBAAuB,qBAgHzB"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { useActionReporter } from "../ux/feedback.js";
|
|
5
|
+
export const DEFAULT_REWARD_WORDS = { one: "credit", many: "credits" };
|
|
6
|
+
export function rewardWord(count, words) {
|
|
7
|
+
return count === 1 ? words.one : words.many;
|
|
8
|
+
}
|
|
9
|
+
const PlainLink = ({ children, ...rest }) => _jsx("a", { ...rest, children: children });
|
|
10
|
+
const SetupGuideContext = React.createContext(null);
|
|
11
|
+
/** Null outside the provider, and for accounts with no guide — every part checks. */
|
|
12
|
+
export function useSetupGuide() {
|
|
13
|
+
return React.useContext(SetupGuideContext);
|
|
14
|
+
}
|
|
15
|
+
/** Long enough that a burst of saves asks one question rather than five. */
|
|
16
|
+
const SETTLE_MS = 1200;
|
|
17
|
+
/** How long the launcher keeps showing what just landed. */
|
|
18
|
+
const FLASH_MS = 4000;
|
|
19
|
+
export function SetupGuideProvider({ initial, transport, readOnly = false, words = DEFAULT_REWARD_WORDS, changeEvent, settleMs = SETTLE_MS, onRefresh, link = PlainLink, children, }) {
|
|
20
|
+
const report = useActionReporter();
|
|
21
|
+
const [guide, setGuide] = React.useState(initial);
|
|
22
|
+
// A fresh reading from the server replaces ours: it knows things we cannot,
|
|
23
|
+
// like a learner added in another tab.
|
|
24
|
+
const [seen, setSeen] = React.useState(initial);
|
|
25
|
+
if (initial !== seen) {
|
|
26
|
+
setSeen(initial);
|
|
27
|
+
setGuide(initial);
|
|
28
|
+
}
|
|
29
|
+
const [panelOpen, setPanelOpen] = React.useState(false);
|
|
30
|
+
const [justEarned, setJustEarned] = React.useState(null);
|
|
31
|
+
const inFlight = React.useRef(false);
|
|
32
|
+
const pathway = guide?.pathway ?? null;
|
|
33
|
+
const listening = Boolean(guide && !guide.hidden && !guide.complete && !readOnly && changeEvent);
|
|
34
|
+
// Read through a ref so the sync function's identity never changes, and the
|
|
35
|
+
// listeners below are not torn down and rebuilt on every render.
|
|
36
|
+
const latest = React.useRef({ transport, words, report });
|
|
37
|
+
React.useEffect(() => {
|
|
38
|
+
latest.current = { transport, words, report };
|
|
39
|
+
});
|
|
40
|
+
const sync = React.useCallback(async () => {
|
|
41
|
+
if (!pathway || inFlight.current)
|
|
42
|
+
return;
|
|
43
|
+
inFlight.current = true;
|
|
44
|
+
const { transport: post, words: said, report: tell } = latest.current;
|
|
45
|
+
let result = null;
|
|
46
|
+
try {
|
|
47
|
+
result = await post.sync(pathway);
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
inFlight.current = false;
|
|
51
|
+
}
|
|
52
|
+
if (!result)
|
|
53
|
+
return;
|
|
54
|
+
setGuide(result.guide);
|
|
55
|
+
const earned = result.rewards.reduce((total, reward) => total + reward.reward, 0);
|
|
56
|
+
if (result.rewards.length === 0 || earned === 0)
|
|
57
|
+
return;
|
|
58
|
+
setJustEarned(earned);
|
|
59
|
+
const left = result.guide.totalReward - result.guide.earnedReward;
|
|
60
|
+
const what = result.rewards.length === 1
|
|
61
|
+
? (result.rewards[0]?.title ?? "A setup step")
|
|
62
|
+
: `${result.rewards.length} steps done`;
|
|
63
|
+
tell({
|
|
64
|
+
tone: "success",
|
|
65
|
+
title: `+${earned} ${rewardWord(earned, said)} — ${what}`,
|
|
66
|
+
description: left > 0
|
|
67
|
+
? `${result.guide.earnedReward} of ${result.guide.totalReward} earned so far — ${left} more to earn.`
|
|
68
|
+
: `All ${result.guide.totalReward} earned, and they are yours to keep.`,
|
|
69
|
+
});
|
|
70
|
+
}, [pathway]);
|
|
71
|
+
// Something done and not yet paid, as the server reads it: pay for it now.
|
|
72
|
+
// Deferred rather than called straight from the effect, which would be
|
|
73
|
+
// setting state during an effect's own render pass.
|
|
74
|
+
const pending = guide && !guide.hidden && !readOnly ? guide.pendingKeys.join(",") : "";
|
|
75
|
+
React.useEffect(() => {
|
|
76
|
+
if (!pending)
|
|
77
|
+
return;
|
|
78
|
+
const timer = setTimeout(() => void sync(), 0);
|
|
79
|
+
return () => clearTimeout(timer);
|
|
80
|
+
}, [pending, sync]);
|
|
81
|
+
// Most saves never refresh the page, so ask once the saving has settled.
|
|
82
|
+
React.useEffect(() => {
|
|
83
|
+
if (!listening || !changeEvent)
|
|
84
|
+
return;
|
|
85
|
+
let timer;
|
|
86
|
+
const onChange = () => {
|
|
87
|
+
clearTimeout(timer);
|
|
88
|
+
timer = setTimeout(() => void sync(), settleMs);
|
|
89
|
+
};
|
|
90
|
+
window.addEventListener(changeEvent, onChange);
|
|
91
|
+
return () => {
|
|
92
|
+
clearTimeout(timer);
|
|
93
|
+
window.removeEventListener(changeEvent, onChange);
|
|
94
|
+
};
|
|
95
|
+
}, [listening, changeEvent, settleMs, sync]);
|
|
96
|
+
React.useEffect(() => {
|
|
97
|
+
if (justEarned === null)
|
|
98
|
+
return;
|
|
99
|
+
const timer = setTimeout(() => setJustEarned(null), FLASH_MS);
|
|
100
|
+
return () => clearTimeout(timer);
|
|
101
|
+
}, [justEarned]);
|
|
102
|
+
const setHidden = React.useCallback(async (hidden) => {
|
|
103
|
+
if (!pathway || readOnly)
|
|
104
|
+
return;
|
|
105
|
+
// Optimistic: hiding something should feel like closing it, not like
|
|
106
|
+
// asking permission to close it.
|
|
107
|
+
setGuide((current) => (current ? { ...current, hidden } : current));
|
|
108
|
+
const ok = await latest.current.transport.setHidden(pathway, hidden);
|
|
109
|
+
if (!ok) {
|
|
110
|
+
setGuide((current) => (current ? { ...current, hidden: !hidden } : current));
|
|
111
|
+
latest.current.report({ tone: "error", title: "Could not change the setup guide" });
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (hidden)
|
|
115
|
+
setPanelOpen(false);
|
|
116
|
+
// A hidden guide skipped working out what was done, so bringing it back
|
|
117
|
+
// needs the server asked again.
|
|
118
|
+
else
|
|
119
|
+
onRefresh?.();
|
|
120
|
+
}, [pathway, readOnly, onRefresh]);
|
|
121
|
+
const value = React.useMemo(() => ({ guide, readOnly, words, Link: link, panelOpen, setPanelOpen, setHidden, justEarned }), [guide, readOnly, words, link, panelOpen, setHidden, justEarned]);
|
|
122
|
+
return _jsx(SetupGuideContext.Provider, { value: value, children: children });
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/setup-guide/context.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a new account is asked to do, how far through it is, and what that has
|
|
3
|
+
* earned. No React and no DOM, so the rules are tested without a browser and
|
|
4
|
+
* hold whatever draws them.
|
|
5
|
+
*
|
|
6
|
+
* **Nothing about progress is stored.** A step is *done* when the account holds
|
|
7
|
+
* what it asks for — a learner, a price, a published course — however it got
|
|
8
|
+
* there; the host reads that fresh each time. What *is* stored is the reward:
|
|
9
|
+
* one entry per step per account, keyed on the step, so a step pays once
|
|
10
|
+
* however many times its thing is made, deleted and made again. That split is
|
|
11
|
+
* the whole design, and it is why `done` and `earned` arrive here as two
|
|
12
|
+
* separate sets rather than one status per step.
|
|
13
|
+
*
|
|
14
|
+
* A step key is permanent. Rewards are keyed on it, so renaming one pays
|
|
15
|
+
* everybody a second time.
|
|
16
|
+
*/
|
|
17
|
+
import type { ReactNode } from "react";
|
|
18
|
+
/** Short numbered instructions. `**bold**` marks the app's own labels, `_italic_` an example. */
|
|
19
|
+
export interface SetupHowTo {
|
|
20
|
+
title: string;
|
|
21
|
+
steps: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
/** Where to read more. Rendered as a link, so the host decides what the href means. */
|
|
24
|
+
export interface SetupGuideLink {
|
|
25
|
+
href: string;
|
|
26
|
+
title: string;
|
|
27
|
+
}
|
|
28
|
+
export interface SetupStepDef {
|
|
29
|
+
/** Stable forever: rewards are keyed on it. */
|
|
30
|
+
key: string;
|
|
31
|
+
title: string;
|
|
32
|
+
/** What finishing it pays. Omit, or 0, for a step that is progress only. */
|
|
33
|
+
reward?: number;
|
|
34
|
+
how?: SetupHowTo;
|
|
35
|
+
guide?: SetupGuideLink;
|
|
36
|
+
}
|
|
37
|
+
export interface SetupItemDef {
|
|
38
|
+
key: string;
|
|
39
|
+
title: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
/** Drawn beside the title. The host's own icon element, so this package needs no icon set of its own. */
|
|
42
|
+
icon?: ReactNode;
|
|
43
|
+
/** Where the item is done. */
|
|
44
|
+
href: string;
|
|
45
|
+
actionLabel: string;
|
|
46
|
+
/**
|
|
47
|
+
* The screen that shows this item's steps, when it has several. Everywhere
|
|
48
|
+
* else shows the item's progress and a way here.
|
|
49
|
+
*/
|
|
50
|
+
screen?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Step keys that must be done before this item can be started. An item nobody
|
|
53
|
+
* can start yet says so instead of offering a button that leads nowhere useful.
|
|
54
|
+
*/
|
|
55
|
+
requires?: readonly string[];
|
|
56
|
+
/** What to say while it is blocked, e.g. "After your first learner". */
|
|
57
|
+
blockedLabel?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Its rewards land only once the whole thing is built — for a flow that saves
|
|
60
|
+
* nothing before its last step, so the steps tick as choices are made and pay
|
|
61
|
+
* at the end.
|
|
62
|
+
*/
|
|
63
|
+
paysOnComplete?: boolean;
|
|
64
|
+
steps: readonly SetupStepDef[];
|
|
65
|
+
}
|
|
66
|
+
export interface GuideStep extends SetupStepDef {
|
|
67
|
+
/** The account holds what the step asks for. */
|
|
68
|
+
done: boolean;
|
|
69
|
+
/** Its reward has been paid. */
|
|
70
|
+
earned: boolean;
|
|
71
|
+
/** Always a number here, whatever the definition left out. */
|
|
72
|
+
reward: number;
|
|
73
|
+
}
|
|
74
|
+
export interface GuideItem extends Omit<SetupItemDef, "steps"> {
|
|
75
|
+
steps: GuideStep[];
|
|
76
|
+
reward: number;
|
|
77
|
+
earnedReward: number;
|
|
78
|
+
doneCount: number;
|
|
79
|
+
done: boolean;
|
|
80
|
+
/** Why it cannot be started yet, when it cannot. */
|
|
81
|
+
blocked: string | null;
|
|
82
|
+
}
|
|
83
|
+
export interface SetupGuide {
|
|
84
|
+
/** Which set of steps this is — the host's own name for it. */
|
|
85
|
+
pathway: string;
|
|
86
|
+
items: GuideItem[];
|
|
87
|
+
totalReward: number;
|
|
88
|
+
earnedReward: number;
|
|
89
|
+
doneItems: number;
|
|
90
|
+
/** The first item not done and not blocked — what the guide leads with. */
|
|
91
|
+
nextKey: string | null;
|
|
92
|
+
/** Every step done and paid. */
|
|
93
|
+
complete: boolean;
|
|
94
|
+
/** Done but not yet paid. A sync would pay exactly these. */
|
|
95
|
+
pendingKeys: string[];
|
|
96
|
+
hidden: boolean;
|
|
97
|
+
}
|
|
98
|
+
/** What one step paid, for announcing it. */
|
|
99
|
+
export interface SetupReward {
|
|
100
|
+
key: string;
|
|
101
|
+
title: string;
|
|
102
|
+
reward: number;
|
|
103
|
+
}
|
|
104
|
+
export interface BuildGuideInput {
|
|
105
|
+
pathway: string;
|
|
106
|
+
items: readonly SetupItemDef[];
|
|
107
|
+
/** Step keys the account's own records satisfy. */
|
|
108
|
+
done: ReadonlySet<string>;
|
|
109
|
+
/** Step keys already paid for. */
|
|
110
|
+
earned: ReadonlySet<string>;
|
|
111
|
+
hidden?: boolean;
|
|
112
|
+
}
|
|
113
|
+
/** Every step of every item, in order. */
|
|
114
|
+
export declare function stepsOf(items: readonly SetupItemDef[]): SetupStepDef[];
|
|
115
|
+
/** Every step key, for checking what a request names before trusting it. */
|
|
116
|
+
export declare function stepKeysOf(items: readonly SetupItemDef[]): Set<string>;
|
|
117
|
+
/** The guide as it stands for one account. Pure: the same inputs always give the same answer. */
|
|
118
|
+
export declare function buildGuide({ pathway, items, done, earned, hidden }: BuildGuideInput): SetupGuide;
|
|
119
|
+
export declare function findItem(guide: SetupGuide | null | undefined, key: string): GuideItem | null;
|
|
120
|
+
/**
|
|
121
|
+
* What counts as done: what the records show now, plus everything already paid
|
|
122
|
+
* for.
|
|
123
|
+
*
|
|
124
|
+
* A reward, once earned, is not taken back — so a step whose thing has since
|
|
125
|
+
* been deleted stays ticked rather than reopening and asking to be paid a
|
|
126
|
+
* second time. Hosts pass the result of this as `done`.
|
|
127
|
+
*/
|
|
128
|
+
export declare function doneSteps(facts: ReadonlySet<string>, earned: ReadonlySet<string>): Set<string>;
|
|
129
|
+
/**
|
|
130
|
+
* The steps this account has done and not been paid for — what a sync owes it.
|
|
131
|
+
*
|
|
132
|
+
* Kept here, away from the database, because *which* steps are owed is a rule
|
|
133
|
+
* and writing the entries is a transaction. The host loops over this and writes
|
|
134
|
+
* one row each, letting its unique index refuse a second payment: two tabs
|
|
135
|
+
* asking at the same moment both get this list, and only one of them gets to
|
|
136
|
+
* write each row.
|
|
137
|
+
*/
|
|
138
|
+
export declare function rewardsOwed(items: readonly SetupItemDef[], done: ReadonlySet<string>, earned: ReadonlySet<string>): SetupReward[];
|
|
139
|
+
export interface ItemProgress {
|
|
140
|
+
/** Done, plus anything `ready` counts as good as done. */
|
|
141
|
+
progressed: number;
|
|
142
|
+
total: number;
|
|
143
|
+
percent: number;
|
|
144
|
+
/** The first step neither done nor ready. */
|
|
145
|
+
nextKey: string | null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* How far through one item is.
|
|
149
|
+
*
|
|
150
|
+
* `ready` is for a flow that saves nothing until its last step: its choices are
|
|
151
|
+
* made but nothing exists yet, so they tick without being done. They count
|
|
152
|
+
* towards the bar — the point of the bar is to show the end approaching — but
|
|
153
|
+
* never towards what has been earned.
|
|
154
|
+
*/
|
|
155
|
+
export declare function itemProgress(item: GuideItem, ready?: ReadonlySet<string>): ItemProgress;
|
|
156
|
+
/** How a step reads: done, ready to be paid, the one to do next, or still to do. */
|
|
157
|
+
export type StepState = "done" | "ready" | "next" | "todo";
|
|
158
|
+
export declare function stepState(step: GuideStep, nextKey: string | null, ready?: ReadonlySet<string>): StepState;
|
|
159
|
+
//# sourceMappingURL=guide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guide.d.ts","sourceRoot":"","sources":["../../src/setup-guide/guide.ts"],"names":[],"mappings":"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"}
|