import { useState, type FormEvent } from 'react' import { Plus } from 'lucide-react' import { useNavigate } from 'react-router' import { useAddRegular, useRegulars, useRemoveRegular, type Regular } from '../dinners/api.ts' import { similarNames } from '../dinners/names.ts' import { useRefusals } from '../dinners/useRefusals.ts' import { Button } from '../ui/Button.tsx' import { Chip } from '../ui/Chip.tsx' import { ErrorBanner } from '../ui/ErrorBanner.tsx' import { Icon } from '../ui/Icon.tsx' import { Skeleton } from '../ui/Skeleton.tsx' import { TextInput } from '../ui/TextInput.tsx' import { OnboardingStep } from './OnboardingStep.tsx' import styles from './Onboarding.module.css' // MIN_REGULARS is how many Regulars the server has saved before the // household moves on. export const MIN_REGULARS = 3 // commonPicks are offered as one-tap Regulars until the household has them, // or a Regular the server would count as the same dinner. export const commonPicks = [ 'Beef tacos', 'Spaghetti bolognese', 'Chicken stir-fry', 'Pizza night', 'Chili', 'Pot roast', 'Burgers', 'Fried rice', ] // RegularsStep is onboarding step 2, handoff mock 1h: the household adds // the dinners it makes on repeat. Each add and remove shows at once and is // undone if the server refuses it. export function RegularsStep() { const navigate = useNavigate() const regulars = useRegulars() const add = useAddRegular() const remove = useRemoveRegular() const [draft, setDraft] = useState('') const { refusals, track } = useRefusals() const list = regulars.data ?? [] const picks = commonPicks.filter((pick) => !list.some((regular) => similarNames(regular.name, pick))) // Next waits for every add to be answered, so a refused add's error shows // here and an add the server takes back never counts towards the three. const adding = list.some((regular) => regular.pending) const saved = list.filter((regular) => !regular.pending).length function addRegular(name: string) { track(`add:${name.toLowerCase()}`, `add ${name}`, add.mutateAsync({ name })) } function removeRegular(regular: Regular) { track(`remove:${regular.id}`, `remove ${regular.name}`, remove.mutateAsync(regular)) } function onSubmit(event: FormEvent) { event.preventDefault() const name = draft.trim() if (name === '') return addRegular(name) setDraft('') } return ( void navigate('/onboarding/notifications')} > Next: notifications } >

Add the dinners your household makes on repeat. MealQuest builds suggestions from these.

setDraft(event.target.value)} /> {refusals.map((refusal) => (

{refusal.text}

))}

Your regulars ยท {list.length}

{regulars.isPending && } {regulars.isError && (
void regulars.refetch()}> Your Regulars could not load: {regulars.error.message}
)} {list.length > 0 && (
    {list.map((regular: Regular) => (
  • removeRegular(regular)} />
  • ))}
)} {regulars.isSuccess && picks.length > 0 && ( <>

Common picks

    {picks.map((pick) => (
  • ))}
)}
) }