import { useId, useState } from 'react' import { Link } from 'react-router' import { usePlan, useWeekSwap, type PlanDinner, type Swap } from '../plan/api.ts' import { cooking } from '../plan/PlanPage.tsx' import swapStyles from '../plan/SwapSheet.module.css' import { addDays, dayOfMonth, localNow, weekdayName, weekLabel, weekStart as weekOf } from '../plan/week.ts' import { useHouseholdSettings } from '../settings/api.ts' import buttonStyles from '../ui/Button.module.css' import { ErrorBanner } from '../ui/ErrorBanner.tsx' import { ListRow } from '../ui/ListRow.tsx' import { Photo } from '../ui/Photo.tsx' import { Segmented } from '../ui/Segmented.tsx' import { Sheet } from '../ui/Sheet.tsx' import { Skeleton } from '../ui/Skeleton.tsx' import { Tag } from '../ui/Tag.tsx' import type { DinnerDetail } from './detail.ts' import styles from './AddToWeekSheet.module.css' // PLAN is the Draft board, where a week with no plan is drafted. export const PLAN = '/plan' // Which is the week a dinner is added to: the household's current week or // the one after. export type Which = 'this' | 'next' export const weekNames: Record = { this: 'this week', next: 'next week' } // Added is a swap sent from the sheet: the week it went to and the swap. export type Added = { week: string; which: Which; swap: Swap } // planDinner is the dinner as it is planned on a day. function planDinner(dinner: DinnerDetail): PlanDinner { return { id: dinner.id, name: dinner.name, photo_id: dinner.photo_id, minutes: dinner.minutes_total, method: dinner.method } } type WeekDaysProps = { dinner: DinnerDetail week: string which: Which onAdd: (added: Added) => void } // WeekDays is the seven days of the week starting on week, each with its // dinner; choosing one swaps the dinner in as the Draft board swaps a day // (useWeekSwap). A week with no plan offers to draft it on the Draft board: // nothing here makes a plan up. A dinner already on the week can't be added // again, nor can one while a swap of the week is still being saved or the // week is being pushed to Calendar. function WeekDays({ dinner, week, which, onAdd }: WeekDaysProps) { const plan = usePlan(week) const { swap, push, refused, swapIn } = useWeekSwap(week) if (plan.isError) { return void plan.refetch()}>Couldn't load {weekNames[which]}'s plan. {plan.error.message} } if (plan.isPending) { return (
{Array.from({ length: 7 }, (_, i) => ( ))}
) } if (plan.data === null) { return (

There's no plan for {weekNames[which]} yet, so there's no day to add it to.

Draft {weekNames[which]} first
) } const days = plan.data.days const planned = days.find((day) => day.dinner.id === dinner.id) const choosable = planned === undefined && !refused function add(date: string) { const chosen: Swap = { date, dinner: planDinner(dinner), fromQuestLog: dinner.status === 'quest_log' } swapIn(chosen) onAdd({ week, which, swap: chosen }) } return ( <> {planned !== undefined ? (

{dinner.name} is already on {weekdayName(planned.date)} {weekNames[which]}.

) : swap.pending ? (

A change to {weekNames[which]} is still being saved.

) : ( push.pending &&

The plan for {weekNames[which]} is being pushed to Calendar.

)} ) } export type AddToWeekSheetProps = { dinner: DinnerDetail onAdd: (added: Added) => void onClose: () => void } // AddToWeekSheet is the sheet Add to this week opens: the seven days of the // household's current week, Monday to Sunday in its timezone, each with its // dinner, and a toggle to next week. Choosing a day replaces its dinner. export function AddToWeekSheet({ dinner, onAdd, onClose }: AddToWeekSheetProps) { const titleId = useId() const settings = useHouseholdSettings() const [which, setWhich] = useState('this') let body if (settings.isError) { body = ( void settings.refetch()}> Couldn't load the household settings. {settings.error.message} ) } else if (settings.isPending) { body = } else { const thisWeek = weekOf(localNow(settings.data.timezone, new Date()).date) const week = which === 'this' ? thisWeek : addDays(thisWeek, 7) body = ( <>

{weekLabel(week).dates} · replaces the day's dinner

) } return (

Add {dinner.name}

{body}
) }