import { Compass } from 'lucide-react' import { useId, useState, type ReactNode } from 'react' import { createPortal } from 'react-dom' import { Link } from 'react-router' import { useRegulars } from '../dinners/api.ts' import { useQuestLog, type QuestLogDinner } from '../discover/api.ts' import { DIFFICULTY_LABEL } from '../discover/DeckCard.tsx' import { ErrorBanner } from '../ui/ErrorBanner.tsx' import { Icon } from '../ui/Icon.tsx' import { Photo } from '../ui/Photo.tsx' import { Segmented } from '../ui/Segmented.tsx' import { Skeleton } from '../ui/Skeleton.tsx' import { useDraggable, type Float } from './drag.tsx' import { emptyLists, planDinner, sourceNames, type Source } from './SwapSheet.tsx' import styles from './PlanPanel.module.css' // DRAG_HINT says how a dinner is swapped in from the panel or the strip. const DRAG_HINT = 'Drag a dinner onto a day to swap it in.' // KEYS_HINT says how a dinner is swapped in with the keyboard. const KEYS_HINT = 'Press Enter or Space to pick it up, the arrow keys to choose a day, Enter to drop it on that day and Escape to cancel.' type List = ReturnType // ListBody is a list of the panel or the strip once it has loaded, or why it // has not: its error with Retry, skeletons while loading, or that it is // empty. function ListBody({ source, list, children }: { source: Source; list: List; children: (dinners: QuestLogDinner[]) => ReactNode }) { if (list.isError) { return ( void list.refetch()}> Couldn't load your {sourceNames[source]}. {list.error.message} ) } if (list.isPending) { return (
{Array.from({ length: 3 }, (_, i) => ( ))}
) } if (list.data.length === 0) return

{emptyLists[source]}

return children(list.data) } // Grip is the 6-dot drag handle of a panel row. function Grip() { return (