/restaurants

This commit is contained in:
Timo Knuth
2026-04-30 16:59:27 +02:00
parent 152758db92
commit 8741edc362
11 changed files with 956 additions and 52 deletions

View File

@@ -13,21 +13,36 @@ import {
ONBOARDING_DOWNLOAD_COMPLETE_KEY,
} from '@/lib/revops';
type OnboardingChecklistProps = {
state: {
id?: string;
signupSourceSelfReported?: string | null;
primaryUseCase?: string | null;
firstQrCreatedAt?: string | null;
firstDynamicQrAt?: string | null;
firstScanAt?: string | null;
activationAt?: string | null;
} | null;
type ChecklistState = {
id?: string;
signupSourceSelfReported?: string | null;
primaryUseCase?: string | null;
firstQrCreatedAt?: string | null;
firstDynamicQrAt?: string | null;
firstScanAt?: string | null;
activationAt?: string | null;
onboardingCompletedAt?: string | null;
};
type OnboardingChecklistProps = {
state: ChecklistState | null;
};
function buildChecklistItems(state: ChecklistState, downloadDone: boolean) {
return getChecklistItems(state).map((item) =>
item.id === 'download'
? {
...item,
done: downloadDone || Boolean(state.firstScanAt),
}
: item
);
}
export function OnboardingChecklist({ state }: OnboardingChecklistProps) {
const [dismissed, setDismissed] = useState(false);
const [downloadDone, setDownloadDone] = useState(false);
const [storageReady, setStorageReady] = useState(false);
const stepMap: Record<string, number> = {
source: 1,
@@ -41,6 +56,7 @@ export function OnboardingChecklist({ state }: OnboardingChecklistProps) {
useEffect(() => {
setDismissed(localStorage.getItem(ONBOARDING_CHECKLIST_DISMISS_KEY) === '1');
setDownloadDone(localStorage.getItem(ONBOARDING_DOWNLOAD_COMPLETE_KEY) === '1');
setStorageReady(true);
const syncDownloadState = () => {
setDownloadDone(localStorage.getItem(ONBOARDING_DOWNLOAD_COMPLETE_KEY) === '1');
@@ -55,21 +71,26 @@ export function OnboardingChecklist({ state }: OnboardingChecklistProps) {
};
}, []);
if (!state || dismissed) {
const items = state ? buildChecklistItems(state, downloadDone) : [];
const completed = items.filter((item) => item.done).length;
const allDone = items.length > 0 && completed === items.length;
useEffect(() => {
if (!storageReady || !state) {
return;
}
if (state.onboardingCompletedAt || allDone) {
localStorage.setItem(ONBOARDING_CHECKLIST_DISMISS_KEY, '1');
setDismissed(true);
}
}, [allDone, state, storageReady]);
if (!state || !storageReady || dismissed || state.onboardingCompletedAt || allDone) {
return null;
}
const items = getChecklistItems(state).map((item) =>
item.id === 'download'
? {
...item,
done: downloadDone || Boolean(state.firstScanAt),
}
: item
);
const completed = items.filter((item) => item.done).length;
const progress = Math.round((completed / items.length) * 100);
const allDone = completed === items.length;
return (
<Card className="overflow-hidden rounded-[28px] border border-slate-200 bg-white p-0 shadow-none">