@fayz-ai/plugin-agenda 0.27.11 → 0.27.13
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/dist/AgendaGeneralSettings-YBI43RB6.js +96 -0
- package/dist/AgendaGeneralSettings-YBI43RB6.js.map +1 -0
- package/dist/AgendaMessageTemplates-46ZLTFLM.js +31 -0
- package/dist/AgendaMessageTemplates-46ZLTFLM.js.map +1 -0
- package/dist/AgendaPage-43OXQDZE.js +3174 -0
- package/dist/AgendaPage-43OXQDZE.js.map +1 -0
- package/dist/CheckinPage-SGWK2TQZ.js +904 -0
- package/dist/CheckinPage-SGWK2TQZ.js.map +1 -0
- package/dist/ConfirmationsView-DZJSYBXA.js +361 -0
- package/dist/ConfirmationsView-DZJSYBXA.js.map +1 -0
- package/dist/MyClientsTodayWidget-ZGTXJJKN.js +127 -0
- package/dist/MyClientsTodayWidget-ZGTXJJKN.js.map +1 -0
- package/dist/PersonAttendanceBlock-PHZVHFQ4.js +105 -0
- package/dist/PersonAttendanceBlock-PHZVHFQ4.js.map +1 -0
- package/dist/PersonAttendancesWidget-3NTWBGCU.js +1278 -0
- package/dist/PersonAttendancesWidget-3NTWBGCU.js.map +1 -0
- package/dist/PersonServicesWidget-4RJGKX3K.js +80 -0
- package/dist/PersonServicesWidget-4RJGKX3K.js.map +1 -0
- package/dist/chunk-37INOUNW.js +20 -0
- package/dist/chunk-37INOUNW.js.map +1 -0
- package/dist/chunk-A2VD5DVN.js +12 -0
- package/dist/chunk-A2VD5DVN.js.map +1 -0
- package/dist/chunk-HGJI2JR6.js +169 -0
- package/dist/chunk-HGJI2JR6.js.map +1 -0
- package/dist/chunk-VFQPXKXP.js +11 -0
- package/dist/chunk-VFQPXKXP.js.map +1 -0
- package/dist/chunk-WNANVT4F.js +2386 -0
- package/dist/chunk-WNANVT4F.js.map +1 -0
- package/dist/chunk-X7PKHXT6.js +18 -0
- package/dist/chunk-X7PKHXT6.js.map +1 -0
- package/dist/chunk-XTNSK4RJ.js +12 -0
- package/dist/chunk-XTNSK4RJ.js.map +1 -0
- package/dist/components/PersonAttendanceBlock.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2530 -19553
- package/dist/index.js.map +1 -1
- package/dist/migrations/integrations-google-calendar.browser.js +15 -0
- package/dist/migrations/integrations-google-calendar.browser.js.map +1 -0
- package/dist/migrations/integrations-google-calendar.js +1992 -0
- package/dist/migrations/integrations-google-calendar.js.map +1 -0
- package/dist/migrations/main.browser.js +29 -0
- package/dist/migrations/main.browser.js.map +1 -0
- package/dist/migrations/main.js +6440 -0
- package/dist/migrations/main.js.map +1 -0
- package/package.json +13 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/styles/calendar-styles.ts","../src/lib/agenda-url.ts","../src/components/BlockDialog.tsx","../src/components/LostSlotsCard.tsx","../src/components/ScheduleGridDialog.tsx","../src/components/FloatingPanel.tsx","../src/components/SeriesDeleteChoice.tsx","../src/components/AppointmentPopover.tsx","../src/components/EventContextMenu.tsx","../src/components/AgendaMobileList.tsx","../src/lib/schedule-engine.ts","../src/lib/calendar-events.ts","../src/views/CalendarView.tsx","../src/views/AgendaPage.tsx"],"names":["days","React","jsxs","jsx","Button","Modal","ModalContent","ModalHeader","ModalTitle","ModalBody","Input","STYLE_ID","useState","useEffect","useTranslation","useRef","createPortal","Fragment","Check","Pencil","Trash2","useMemo","formatCurrency","localDateKey","getCurrentLocale","useCallback","dow","booking","toast","PersonAvatar","PersonLink","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Switch"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAOA,IAAM,QAAA,GAAW,6BAAA;AAEjB,IAAM,GAAA;AAAA;AAAA,EAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AA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","file":"AgendaPage-43OXQDZE.js","sourcesContent":["/**\n * Injects agenda calendar CSS at runtime.\n * This ensures styles work both in symlinked dev mode and when consumed\n * as a built package (where CSS side-effect imports are extracted by tsup\n * and not automatically loaded).\n */\n\nconst STYLE_ID = 'saas-agenda-calendar-styles'\n\nconst css = /* css */ `\n/* Dark mode content background — uses the content token */\n.dark .agenda-calendar,\n.dark .agenda-calendar .fc,\n.dark .agenda-calendar .fc-view-harness,\n.dark .agenda-calendar .fc-timegrid,\n.dark .agenda-calendar .fc-scrollgrid,\n.dark .agenda-calendar .fc-timegrid-col,\n.dark .agenda-calendar .fc-daygrid-body,\n.dark .agenda-calendar .fc-timegrid-slot-lane {\n background-color: hsl(var(--content));\n}\n\n/* FullCalendar — Google Calendar inspired theme */\n\n.agenda-calendar {\n --fc-border-color: hsl(var(--border));\n --fc-today-bg-color: transparent;\n --fc-now-indicator-color: hsl(var(--destructive));\n --fc-highlight-color: hsl(var(--primary) / 0.06);\n --fc-non-business-color: hsl(var(--muted) / 0.15);\n --fc-neutral-bg-color: transparent;\n --fc-page-bg-color: transparent;\n --fc-event-border-color: transparent;\n}\n\n.agenda-calendar .fc {\n font-family: inherit;\n background: transparent;\n}\n\n.agenda-calendar .fc .fc-view-harness {\n background: transparent;\n}\n\n/* ── Column headers ── */\n.agenda-calendar .fc-col-header-cell {\n background: transparent;\n border-bottom: 1px solid var(--fc-border-color);\n border-left: none;\n border-right: none;\n border-top: none;\n}\n\n.agenda-calendar .fc-col-header-cell-cushion {\n padding: 8px 4px;\n font-weight: 400;\n font-size: 0.7rem;\n color: hsl(var(--muted-foreground));\n text-decoration: none;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n/* Today's column header */\n.agenda-calendar .fc-day-today .fc-col-header-cell-cushion {\n color: hsl(var(--primary-ink, var(--primary)));\n font-weight: 600;\n}\n\n/* Resource header (professional columns) */\n.agenda-calendar .fc .fc-resource-header {\n background: transparent;\n border-bottom: 1px solid var(--fc-border-color);\n}\n\n/* ── Time slots — compact ── */\n.agenda-calendar .fc-timegrid-slot {\n height: 1.5rem;\n border-bottom: 1px solid hsl(var(--border) / 0.4);\n}\n\n.agenda-calendar .fc-timegrid-slot-label {\n vertical-align: top;\n border: none;\n}\n\n.agenda-calendar .fc-timegrid-slot-label-cushion {\n font-size: 0.65rem;\n color: hsl(var(--muted-foreground) / 0.7);\n padding: 1px 8px 0 0;\n}\n\n/* Half-hour lines lighter */\n.agenda-calendar .fc-timegrid-slot-minor {\n border-bottom-style: none;\n}\n\n/* Column dividers */\n.agenda-calendar .fc-timegrid-col {\n border-right: 1px solid hsl(var(--border) / 0.5);\n}\n\n/* ── Events ── */\n.agenda-calendar .fc-event {\n border-radius: 6px;\n border-width: 0;\n border-left: 4px solid;\n cursor: pointer;\n transition: opacity 0.15s, box-shadow 0.15s, backdrop-filter 0.15s;\n font-size: 0.7rem;\n line-height: 1.3;\n margin: 0 2px;\n overflow: hidden;\n backdrop-filter: blur(8px) saturate(140%);\n -webkit-backdrop-filter: blur(8px) saturate(140%);\n}\n\n.agenda-calendar .fc-event .fc-event-main {\n background: inherit;\n border-radius: inherit;\n overflow: hidden;\n}\n\n.agenda-calendar .fc-event:not(.fc-bg-event):hover {\n opacity: 0.92;\n box-shadow: 0 2px 8px rgba(0,0,0,0.12);\n backdrop-filter: blur(12px) saturate(160%);\n -webkit-backdrop-filter: blur(12px) saturate(160%);\n}\n\n.agenda-calendar .fc-bg-event {\n pointer-events: none;\n}\n\n/* ── Now indicator ── */\n.agenda-calendar .fc-timegrid-now-indicator-line {\n border-color: hsl(var(--destructive));\n border-width: 2px;\n}\n\n.agenda-calendar .fc-timegrid-now-indicator-arrow {\n border-top-color: hsl(var(--destructive));\n}\n\n/* ── Month view ── */\n.agenda-calendar .fc-daygrid-day-number {\n font-size: 0.8rem;\n padding: 4px 8px;\n text-decoration: none;\n color: hsl(var(--foreground));\n}\n\n.agenda-calendar .fc-daygrid-day.fc-day-today .fc-daygrid-day-number {\n background-color: hsl(var(--primary));\n color: hsl(var(--primary-foreground));\n border-radius: 50%;\n width: 1.5rem;\n height: 1.5rem;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.75rem;\n}\n\n/* ── Selection ── */\n.agenda-calendar .fc-highlight {\n background: hsl(var(--primary) / 0.08);\n}\n\n/* ── Links ── */\n.agenda-calendar .fc a {\n text-decoration: none;\n color: inherit;\n}\n\n/* ── Scrollbar ── */\n.agenda-calendar .fc-scroller {\n scrollbar-width: thin;\n scrollbar-color: hsl(var(--muted-foreground) / 0.12) transparent;\n}\n\n.agenda-calendar .fc-scroller::-webkit-scrollbar {\n width: 6px;\n}\n\n.agenda-calendar .fc-scroller::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.agenda-calendar .fc-scroller::-webkit-scrollbar-thumb {\n background: hsl(var(--muted-foreground) / 0.12);\n border-radius: 3px;\n}\n\n/* ── Clean up borders ── */\n.agenda-calendar .fc .fc-timegrid {\n border: none;\n}\n\n.agenda-calendar .fc-scrollgrid {\n border: none !important;\n}\n\n.agenda-calendar .fc-scrollgrid td:last-child {\n border-right: none;\n}\n\n/* ── Unavailable time background — opaque/disabled feel ── */\n/* Fora da grade é FECHADO, e tem de se ler como fechado à distância de um\n braço. A 8% o hachurado sumia contra o branco da coluna aberta, e as duas\n faixas viravam a mesma — quem marca em cima de um horário que não existe\n descobre no erro, não no olho. */\n.agenda-calendar .fc-unavailable-bg {\n background: hsl(var(--muted-foreground) / 0.2) !important;\n background-image: repeating-linear-gradient(\n 45deg,\n transparent,\n transparent 4px,\n hsl(var(--muted-foreground) / 0.12) 4px,\n hsl(var(--muted-foreground) / 0.12) 8px\n ) !important;\n border-radius: 0;\n border-left: none !important;\n}\n\n/* ── Location label on schedule blocks ── */\n.agenda-calendar .fc-location-label {\n background: transparent !important;\n border: none !important;\n border-left-width: 0 !important;\n cursor: default !important;\n pointer-events: none;\n box-shadow: none !important;\n z-index: 1 !important;\n margin: 0 4px !important;\n font-weight: 500 !important;\n}\n\n.agenda-calendar .fc-location-label .fc-event-main {\n padding: 0 !important;\n}\n\n/* Week view day header with date */\n.agenda-calendar .fc-timegrid .fc-col-header-cell {\n padding: 4px 0;\n}\n\n/* ── Alternating resource column backgrounds ── */\n.agenda-calendar .fc-resource-alt {\n background-color: hsl(var(--muted) / 0.4) !important;\n}\n\n.dark .agenda-calendar .fc-resource-alt {\n background-color: hsl(var(--muted-foreground) / 0.08) !important;\n}\n\n/* Resource group header separator — stronger border between professionals */\n.agenda-calendar .fc-resource-group {\n border-left: 2px solid hsl(var(--border));\n}\n\n/* Also stripe the resource header label for the alt group */\n.agenda-calendar th.fc-resource-alt {\n background-color: hsl(var(--muted) / 0.4) !important;\n}\n\n.dark .agenda-calendar th.fc-resource-alt {\n background-color: hsl(var(--muted-foreground) / 0.06) !important;\n}\n/* ── Semana agrupada por DATA ──────────────────────────────────────────────\n O cabeçalho de cima é o dia e as colunas de baixo são as agendas daquele\n dia. Para o bloco existir aos olhos ele precisa de três coisas: o título do\n dia lendo como título, uma junta visível na virada do dia, e uma faixa\n alternando um dia sim outro não. Sem elas quarenta e duas colunas viram uma\n régua sem marca nenhuma.\n\n Sutil de propósito: a junta é UMA linha de cor cheia contra as linhas a meio\n tom que separam as agendas. Uma barra grossa gritaria mais alto que os\n próprios agendamentos, que é o que a tela veio mostrar. */\n\n/* O título do dia: é o grupo, então lê como grupo. */\n.agenda-calendar .fc-col-header-cell[data-date] > .fc-scrollgrid-sync-inner {\n background: hsl(var(--muted) / 0.4);\n}\n\n.dark .agenda-calendar .fc-col-header-cell[data-date] > .fc-scrollgrid-sync-inner {\n background: hsl(var(--muted-foreground) / 0.08);\n}\n\n.agenda-calendar .fc-col-header-cell[data-date] .fc-col-header-cell-cushion {\n font-weight: 600;\n font-size: 0.68rem;\n letter-spacing: 0.08em;\n color: hsl(var(--primary-ink, var(--primary)));\n}\n\n.agenda-calendar .fc-day-today.fc-col-header-cell[data-date] > .fc-scrollgrid-sync-inner {\n background: hsl(var(--primary) / 0.1);\n}\n\n/* A junta do bloco: a primeira agenda de cada dia fecha o dia anterior. */\n.agenda-calendar th.fc-day-start,\n.agenda-calendar td.fc-day-start {\n border-left: 1px solid hsl(var(--border)) !important;\n}\n\n/* …e a mesma junta sobe até o título, para o corte atravessar a tela inteira. */\n.agenda-calendar .fc-col-header-cell[data-date] + .fc-col-header-cell[data-date] {\n border-left: 1px solid hsl(var(--border));\n}\n\n/* O nome do profissional é a FOLHA agora: cabe pouco, então não pode vazar. */\n.agenda-calendar th[data-resource-id] {\n overflow: hidden;\n border-left: 1px solid hsl(var(--border) / 0.4);\n}\n\n.agenda-calendar th[data-resource-id] .fc-col-header-cell-cushion {\n padding: 0;\n text-transform: none;\n letter-spacing: 0;\n}\n\n/* The day header fills its column, so a holiday name ellipses inside it\n instead of pushing the day out. */\n.agenda-calendar .fc-col-header-cell[data-date] .fc-col-header-cell-cushion {\n display: block;\n max-width: 100%;\n overflow: hidden;\n}\n\n/* A day of the week opens that day. */\n.agenda-calendar .agenda-day-link {\n cursor: pointer;\n border-radius: 0.5rem;\n padding: 2px 4px;\n transition: background-color 120ms ease-out;\n}\n.agenda-calendar .agenda-day-link:hover,\n.agenda-calendar .agenda-day-link:focus-visible {\n background: hsl(var(--foreground) / 0.07);\n outline: none;\n}\n\n/* No schedule in the period: the whole grid reads as closed, in the same\n hatch as time outside a schedule — a blank grid looks bookable. On the slot\n rows, because with no schedule there may be no column to paint. */\n.agenda-calendar.agenda-unscheduled .fc-timegrid-slots td.fc-timegrid-slot-lane {\n background-color: hsl(var(--muted-foreground) / 0.2);\n background-image: repeating-linear-gradient(\n 45deg,\n transparent,\n transparent 4px,\n hsl(var(--muted-foreground) / 0.12) 4px,\n hsl(var(--muted-foreground) / 0.12) 8px\n );\n background-attachment: fixed;\n}\n`\n\nlet injected = false\n\nexport function injectCalendarStyles(): void {\n if (injected) return\n if (typeof document === 'undefined') return\n\n // Já presente (importação do CSS no dev, ou uma instância anterior deste\n // módulo depois de um hot-reload). Reescreve o conteúdo em vez de desistir:\n // desistir era o que fazia uma alteração de CSS só aparecer depois de um\n // recarregamento COMPLETO da página, com a folha velha no ar o tempo todo.\n const existing = document.getElementById(STYLE_ID)\n if (existing) {\n if (existing.textContent !== css) existing.textContent = css\n injected = true\n return\n }\n\n const style = document.createElement('style')\n style.id = STYLE_ID\n style.textContent = css\n document.head.appendChild(style)\n injected = true\n}\n","// The calendar's place in the URL, so a day can be linked to and Back returns\n// to where the person was: /agenda/week, /agenda/day/2026/10/15.\n\nexport type AgendaUrlView = 'day' | 'week' | 'month' | 'list'\n\nexport interface AgendaUrlTarget {\n view: AgendaUrlView\n /** Local calendar day. Absent means \"wherever the calendar already is\". */\n date?: Date\n}\n\nconst VIEWS: AgendaUrlView[] = ['day', 'week', 'month', 'list']\n\n/** `null` for the bare `/agenda` (the remembered view) and for anything that is not the calendar. */\nexport function parseAgendaPath(path: string): AgendaUrlTarget | null {\n const parts = (path.split('?')[0] ?? '').split('/').filter(Boolean)\n if (parts[0] !== 'agenda') return null\n const view = parts[1] as AgendaUrlView | undefined\n if (!view || !VIEWS.includes(view)) return null\n if (parts.length === 2) return { view }\n if (parts.length !== 5) return null\n const [y, m, d] = parts.slice(2).map(Number) as [number, number, number]\n const date = new Date(y, m - 1, d)\n // A date that rolled over (month 13, the 31st of a short month) is not a link to follow.\n if (date.getFullYear() !== y || date.getMonth() !== m - 1 || date.getDate() !== d) return null\n return { view, date }\n}\n\nexport function agendaPath(view: AgendaUrlView, date?: Date): string {\n if (!date) return `/agenda/${view}`\n const pad = (n: number) => String(n).padStart(2, '0')\n return `/agenda/${view}/${date.getFullYear()}/${pad(date.getMonth() + 1)}/${pad(date.getDate())}`\n}\n\n/** Which URL word a FullCalendar view type is. */\nexport function urlViewOf(viewType: string): AgendaUrlView {\n if (viewType.startsWith('list')) return 'list'\n if (viewType.endsWith('Day')) return 'day'\n if (viewType.endsWith('Week')) return 'week'\n return 'month'\n}\n\n/** The FullCalendar view type for a URL word, in the variant this agenda draws. */\nexport function calendarViewFor(view: AgendaUrlView, resourceCapable: boolean): string {\n if (view === 'day') return resourceCapable ? 'resourceTimeGridDay' : 'timeGridDay'\n if (view === 'week') return resourceCapable ? 'resourceTimeGridWeek' : 'timeGridWeek'\n if (view === 'list') return resourceCapable ? 'listWeek' : 'listMonth'\n return 'dayGridMonth'\n}\n","import React from 'react'\nimport { CalendarOff } from 'lucide-react'\nimport {\n Button, DatePicker, Input, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalTitle,\n PersonPicker, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Switch,\n Tabs, TabsList, TabsTrigger, Textarea, TimePicker, toast,\n} from '@fayz-ai/ui'\nimport { useAgendaStore, useAgendaProvider } from '../context'\nimport { todayLocal } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// NOVO BLOQUEIO / COMPROMISSO\n//\n// Diálogo próprio, como no V1, e não mais um \"tipo\" dentro do formulário de\n// agendamento. São duas coisas diferentes: um agendamento tem cliente, serviço,\n// preço e status; um bloqueio tem um título e um pedaço do dia. Enfiar os dois\n// no mesmo formulário obriga cada campo a perguntar \"eu existo agora?\", e foi\n// assim que a recorrência nunca coube.\n//\n// ── Por que recorrente é uma LINHA por dia da semana, e não por data ───────\n//\n// Um almoço de segunda a sexta até o fim do ano são 1.300 ocorrências. O banco\n// já sabe ler weekday + vigência + paridade de semana (`agenda_busy_blocks`,\n// migration 010), então o \"semana sim, semana não\" do V1 é um número guardado\n// uma vez — não milhares de linhas que alguém vai ter de apagar uma a uma\n// quando o horário do almoço mudar.\n// ---------------------------------------------------------------------------\n\nconst DIAS = [\n { v: 1, label: 'Seg' }, { v: 2, label: 'Ter' }, { v: 3, label: 'Qua' },\n { v: 4, label: 'Qui' }, { v: 5, label: 'Sex' }, { v: 6, label: 'Sáb' }, { v: 0, label: 'Dom' },\n]\n\n/** O vocabulário do V1, valor por valor. */\nconst REPETICAO = [\n { v: '0', label: 'Toda semana' },\n { v: '1', label: 'Semana sim, semana não' },\n { v: '2', label: 'A cada 3 semanas' },\n { v: '3', label: 'A cada 4 semanas' },\n]\n\nconst hoje = () => todayLocal()\n\n/** As linhas que formam UM bloqueio, e o que elas dizem em comum. */\nexport interface EditingBlock {\n ids: string[]\n assigneeId: string\n title: string\n description: string\n startsAt: string\n endsAt: string\n specificDate: string | null\n daysOfWeek: number[]\n validFrom: string | null\n validTo: string | null\n weekInterval: number\n}\n\nexport function BlockDialog({\n open, onClose, professionalId: prefillProfessional, date, editing, onSaved,\n}: {\n open: boolean\n onClose: () => void\n professionalId?: string | null\n /** A data que a pessoa clicou na grade, quando veio de lá. */\n date?: string | null\n /** O bloqueio que já existe — abre preenchido, e o pé oferece excluir. */\n editing?: EditingBlock | null\n onSaved?: () => void\n}) {\n const professionals = useAgendaStore((s) => s.agendaProfessionals)\n const provider = useAgendaProvider()\n\n const [assigneeId, setAssigneeId] = React.useState(prefillProfessional ?? '')\n const [title, setTitle] = React.useState('')\n const [description, setDescription] = React.useState('')\n const [mode, setMode] = React.useState<'single' | 'recurring'>('single')\n const [specificDate, setSpecificDate] = React.useState(date ?? hoje())\n const [allDay, setAllDay] = React.useState(false)\n const [startsAt, setStartsAt] = React.useState('12:00')\n const [endsAt, setEndsAt] = React.useState('13:00')\n const [days, setDays] = React.useState<number[]>([])\n const [validFrom, setValidFrom] = React.useState(date ?? hoje())\n const [validTo, setValidTo] = React.useState('')\n const [weekInterval, setWeekInterval] = React.useState('0')\n const [saving, setSaving] = React.useState(false)\n\n React.useEffect(() => {\n if (!open) return\n if (editing) {\n // Editar é REESCREVER o bloqueio: os campos voltam como estão, e salvar\n // apaga as linhas antigas e grava as novas — a mesma regra da grade de\n // horários, pelo mesmo motivo (o desenho da semana não tem identidade\n // linha a linha).\n setAssigneeId(editing.assigneeId)\n setTitle(editing.title)\n setDescription(editing.description)\n setMode(editing.daysOfWeek.length ? 'recurring' : 'single')\n setSpecificDate(editing.specificDate ?? hoje())\n setDays(editing.daysOfWeek)\n setValidFrom(editing.validFrom ?? hoje())\n setValidTo(editing.validTo ?? '')\n setWeekInterval(String(editing.weekInterval))\n setAllDay(editing.startsAt === '00:00' && editing.endsAt === '23:59')\n setStartsAt(editing.startsAt)\n setEndsAt(editing.endsAt)\n return\n }\n setAssigneeId(prefillProfessional ?? '')\n setTitle(''); setDescription(''); setMode('single'); setDays([]); setValidTo('')\n setSpecificDate(date ?? hoje())\n setValidFrom(date ?? hoje())\n }, [open, prefillProfessional, date, editing])\n\n const toggleDay = (d: number) =>\n setDays((cur) => (cur.includes(d) ? cur.filter((x) => x !== d) : [...cur, d]))\n\n // O V1 exige profissional e título; o resto tem padrão. E o botão que não\n // pode salvar DIZ o que falta, em vez de ficar morto em silêncio.\n const falta = !assigneeId\n ? 'Escolha o profissional'\n : !title.trim()\n ? 'Dê um título ao bloqueio'\n : mode === 'recurring' && days.length === 0\n ? 'Escolha ao menos um dia da semana'\n : null\n\n async function salvar() {\n if (falta || !provider.createBlock) return\n setSaving(true)\n try {\n if (editing && provider.deleteBlock) await provider.deleteBlock(editing.ids)\n await provider.createBlock({\n assigneeId,\n title: title.trim(),\n description: description.trim() || undefined,\n startsAt: allDay ? '00:00' : startsAt,\n endsAt: allDay ? '23:59' : endsAt,\n ...(mode === 'single'\n ? { specificDate }\n : {\n daysOfWeek: days,\n validFrom,\n validTo: validTo || null,\n weekInterval: Number(weekInterval),\n }),\n })\n toast.success(editing ? 'Bloqueio atualizado' : 'Bloqueio salvo')\n onSaved?.()\n onClose()\n } catch (err: any) {\n toast.error('Não foi possível salvar o bloqueio', { description: err?.message })\n } finally {\n setSaving(false)\n }\n }\n\n return (\n <Modal open={open} onOpenChange={(o) => { if (!o) onClose() }}>\n <ModalContent size=\"md\">\n <ModalHeader>\n <ModalTitle className=\"flex items-center gap-2\">\n <CalendarOff className=\"h-4 w-4\" aria-hidden />\n {editing ? 'Editar bloqueio' : 'Novo bloqueio / compromisso'}\n </ModalTitle>\n </ModalHeader>\n\n <ModalBody className=\"space-y-4\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Profissional *</label>\n {/* O MESMO seletor de gente do resto da agenda — retrato à\n esquerda, nome inteiro, busca quando a lista cresce. Um\n `Select` de texto aqui faria esta ser a única tela onde\n escolher um profissional não se parece com escolher um\n profissional. */}\n <PersonPicker\n options={professionals.map((p) => ({ id: p.id, name: p.name, avatarUrl: p.avatarUrl }))}\n value={assigneeId}\n onChange={setAssigneeId}\n placeholder=\"Selecione o profissional\"\n searchPlaceholder=\"Buscar profissional…\"\n />\n </div>\n\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Título *</label>\n <Input value={title} onChange={(e) => setTitle(e.target.value)}\n placeholder=\"Ex.: Almoço, Curso, Consulta médica\" />\n </div>\n\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Descrição</label>\n <Textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n className=\"min-h-0\"\n />\n </div>\n\n <Tabs value={mode} onValueChange={(v) => setMode(v as 'single' | 'recurring')}>\n <TabsList className=\"w-full\">\n <TabsTrigger value=\"single\" className=\"flex-1\">Único</TabsTrigger>\n <TabsTrigger value=\"recurring\" className=\"flex-1\">Recorrente</TabsTrigger>\n </TabsList>\n </Tabs>\n\n {mode === 'single' ? (\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Data *</label>\n <DatePicker value={specificDate} format=\"numeric\" onChange={setSpecificDate} />\n </div>\n ) : (\n <div className=\"space-y-3\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Dias da semana *</label>\n <div className=\"flex flex-wrap gap-1\">\n {DIAS.map((d) => {\n const on = days.includes(d.v)\n return (\n <Button variant=\"bare\" size=\"bare\"\n key={d.v} type=\"button\" onClick={() => toggleDay(d.v)}\n aria-pressed={on}\n className={'rounded-button border px-2.5 py-1 text-xs transition-colors ' +\n (on ? 'border-primary bg-primary/10 font-medium text-foreground'\n : 'border-input font-normal text-muted-foreground hover:bg-muted')}\n >\n {d.label}\n </Button>\n )\n })}\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">De *</label>\n <DatePicker value={validFrom} format=\"numeric\" onChange={setValidFrom} />\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Até</label>\n <DatePicker value={validTo} format=\"numeric\" onChange={setValidTo} />\n <p className=\"mt-1 text-[11px] text-muted-foreground\">Vazio = sem fim</p>\n </div>\n </div>\n\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Repetição</label>\n <Select value={weekInterval} onValueChange={setWeekInterval}>\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n {REPETICAO.map((r) => <SelectItem key={r.v} value={r.v}>{r.label}</SelectItem>)}\n </SelectContent>\n </Select>\n </div>\n </div>\n )}\n\n <div className=\"flex items-center justify-between rounded-lg border px-3 py-2\">\n <span className=\"text-sm\">Dia inteiro</span>\n <Switch size=\"sm\" checked={allDay} onCheckedChange={setAllDay} />\n </div>\n\n {!allDay && (\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Início *</label>\n <TimePicker value={startsAt} onChange={setStartsAt} interval={15} />\n </div>\n <div>\n <label className=\"mb-1 block text-xs font-medium text-muted-foreground\">Fim *</label>\n <TimePicker value={endsAt} onChange={setEndsAt} interval={15} min={startsAt} />\n </div>\n </div>\n )}\n </ModalBody>\n\n <ModalFooter className=\"items-center\">\n {/* Excluir fica à esquerda e discreto: é a ação de desfazer um erro,\n não o par visual de salvar. */}\n {editing && (\n <Button variant=\"bare\" size=\"bare\"\n type=\"button\"\n disabled={saving}\n onClick={async () => {\n if (!provider.deleteBlock) return\n setSaving(true)\n try {\n await provider.deleteBlock(editing.ids)\n toast.success(editing.ids.length > 1\n ? `Bloqueio removido de ${editing.ids.length} dias`\n : 'Bloqueio removido')\n onSaved?.(); onClose()\n } catch (err: any) {\n toast.error('Não foi possível remover o bloqueio', { description: err?.message })\n } finally { setSaving(false) }\n }}\n className=\"mr-auto text-xs font-medium text-destructive hover:underline disabled:opacity-60\"\n >\n Excluir bloqueio\n </Button>\n )}\n {falta && <span className=\"mr-auto text-xs text-muted-foreground\">{falta}</span>}\n <Button variant=\"ghost\" onClick={onClose}>Cancelar</Button>\n <Button onClick={salvar} disabled={!!falta || saving}>\n {saving ? 'Salvando…' : editing ? 'Salvar alterações' : 'Salvar bloqueio'}\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n )\n}\n","import React from 'react'\nimport { CalendarX, UserX } from 'lucide-react'\nimport { Button, Skeleton } from '@fayz-ai/ui'\nimport { useAgendaProvider } from '../context'\n\n// ---------------------------------------------------------------------------\n// O QUE O PERÍODO PERDEU.\n//\n// O V1 põe este cartão na coluna da agenda porque cancelamento e falta são o\n// número que some: a grade mostra o que VAI acontecer, e o horário que se\n// perdeu não desenha em lugar nenhum — some da tela junto com a chance de\n// remarcar. Trinta dias do Espaço Facial têm 189 cancelados e 167 faltas; nada\n// na agenda dizia isso.\n//\n// ── O cartão do V1 diz \"Cancelados e remarcados\"; este diz outra coisa ─────\n//\n// \"Remarcado\" é um TERCEIRO estado no V1, guardado em `appointment_status_logs`\n// — a linha que sabe que o agendamento das 14h virou o das 16h. Essa tabela não\n// tem destino no V2, e um contador de remarcados que sempre diz zero afirmaria\n// que ninguém remarca nesta casa. Então o cartão conta o que o V2 sabe —\n// cancelado e falta — e se chama pelo que mostra. Indicador ausente é honesto;\n// indicador errado é pior que nenhum.\n//\n// Clicar não abre relatório: liga o filtro de status daquele estado, e a grade\n// passa a desenhar o que estava escondido. A pergunta \"quais foram?\" se\n// responde na mesma tela.\n// ---------------------------------------------------------------------------\n\nexport function LostSlotsCard({ range, selectedStatuses, onPick }: {\n range: { start: string; end: string } | null\n selectedStatuses: string[]\n onPick: (status: string) => void\n}) {\n const provider = useAgendaProvider()\n const [counts, setCounts] = React.useState<{ cancelled: number; noShow: number } | null>(null)\n /** A consulta falhou. Diferente de \"ainda carregando\" e de \"deu zero\". */\n const [falhou, setFalhou] = React.useState(false)\n\n const key = range ? `${range.start}|${range.end}` : null\n React.useEffect(() => {\n if (!range || !provider.getLostCounts) { setCounts(null); return }\n let cancelled = false\n setCounts(null); setFalhou(false)\n provider.getLostCounts(range)\n .then((c) => { if (!cancelled) setCounts(c) })\n // NÃO CAI PARA ZERO. Um contador que não carregou não vira erro em cima\n // de quem só queria ver a agenda — mas \"zero perdidos\" é uma AFIRMAÇÃO, e\n // afirmar que ninguém desmarcou porque a consulta caiu é pior que não\n // dizer nada. Um 503 do banco (aconteceu aqui) apagava 189 cancelamentos\n // da tela sem deixar rastro.\n .catch(() => { if (!cancelled) setFalhou(true) })\n return () => { cancelled = true }\n }, [key, provider])\n\n // Sem resposta, sem cartão. O silêncio é honesto; o zero não seria.\n if (falhou) return null\n\n if (!provider.getLostCounts) return null\n\n if (counts === null) {\n return (\n <div className=\"space-y-1.5 py-1\">\n <Skeleton className=\"h-3 w-24\" />\n <Skeleton className=\"h-7 w-full\" />\n <Skeleton className=\"h-7 w-full\" />\n </div>\n )\n }\n\n // Zero em AMBOS não merece espaço: um período sem perda nenhuma não tem o que\n // dizer, e o cartão vazio só empurra os filtros para baixo.\n if (counts.cancelled === 0 && counts.noShow === 0) return null\n\n const linhas = [\n { status: 'cancelled', label: 'Cancelados', n: counts.cancelled, Icon: CalendarX, tone: 'text-destructive' },\n { status: 'no_show', label: 'Não compareceu', n: counts.noShow, Icon: UserX, tone: 'text-muted-foreground' },\n ].filter((l) => l.n > 0)\n\n return (\n <div className=\"space-y-1\">\n <p className=\"px-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">\n Perdidos no período\n </p>\n {linhas.map(({ status, label, n, Icon, tone }) => {\n const on = selectedStatuses.includes(status)\n return (\n <Button variant=\"bare\" size=\"bare\"\n key={status}\n type=\"button\"\n onClick={() => onPick(status)}\n aria-pressed={on}\n className={'flex w-full items-center justify-start gap-2 rounded-md px-1.5 py-1.5 text-left text-xs transition-colors ' +\n (on ? 'bg-muted font-medium text-foreground' : 'font-normal text-muted-foreground hover:bg-muted/50')}\n >\n <Icon className={`h-3.5 w-3.5 shrink-0 ${tone}`} aria-hidden />\n <span className=\"min-w-0 flex-1 truncate\">{label}</span>\n <span className=\"shrink-0 tabular-nums font-semibold text-foreground\">{n}</span>\n </Button>\n )\n })}\n </div>\n )\n}\n","import React from 'react'\nimport { Search } from 'lucide-react'\nimport { Button, Input, Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, PersonAvatar } from '@fayz-ai/ui'\nimport { ScheduleEditor } from '@fayz-ai/admin'\nimport { useTranslation } from '@fayz-ai/core'\nimport { useAgendaStore } from '../context'\n\n// ---------------------------------------------------------------------------\n// A GRADE DE HORÁRIOS, ALCANÇÁVEL DE DENTRO DA AGENDA.\n//\n// É a primeira pergunta de todo suporte: \"abri a agenda e não aparece nada\".\n// Quase nunca é agenda sem cliente — é agenda sem grade. O V1 resolve isso com\n// um botão \"Horários\" na própria coluna da agenda, e o editor que ele abre já\n// existia aqui (`ScheduleEditor`, do @fayz-ai/admin): faltava a porta.\n//\n// Modal e não navegação: quem vai configurar a grade está olhando para o dia\n// que ficou vazio, e mandá-lo para outra tela é fazê-lo voltar depois para\n// conferir se resolveu.\n// ---------------------------------------------------------------------------\n\nexport function ScheduleGridDialog({ open, onClose, professionalId }: {\n open: boolean\n onClose: () => void\n /** Quem a ficha pediu. Abrir a grade \"de alguém\" e cair na de outro é o\n * mesmo que a ação não ter funcionado. */\n professionalId?: string | null\n}) {\n const t = useTranslation()\n const professionals = useAgendaStore((s) => s.professionals)\n const invalidateSchedules = useAgendaStore((s) => s.invalidateSchedules)\n const [search, setSearch] = React.useState('')\n const [selectedId, setSelectedId] = React.useState<string | null>(null)\n\n // O primeiro da lista já vem escolhido: uma coluna de nomes ao lado de um\n // painel vazio faz o usuário adivinhar que ele precisa clicar.\n React.useEffect(() => {\n if (!open) return\n // Quem veio da ficha de alguém manda; sem isso, o primeiro da lista.\n setSelectedId((current) => professionalId ?? current ?? professionals[0]?.id ?? null)\n }, [open, professionalId, professionals])\n\n // Abrir e não ver de quem é a grade que está aberta ao lado é o mesmo que não\n // ter seleção: a lista tem centenas de nomes e rola por conta própria.\n const selectedRef = React.useRef<HTMLButtonElement>(null)\n React.useEffect(() => {\n if (!open || !selectedId) return\n const id = window.setTimeout(() => {\n selectedRef.current?.scrollIntoView({ block: 'nearest' })\n }, 0)\n return () => window.clearTimeout(id)\n }, [open, selectedId])\n\n const term = search.trim().toLowerCase()\n const shown = term\n ? professionals.filter((p) => p.name.toLowerCase().includes(term))\n : professionals\n\n return (\n <Modal open={open} onOpenChange={(o) => { if (!o) onClose() }}>\n {/* Largura cheia, como no V1. Sete colunas de dia mais a lista de\n profissionais não cabem em 1024px: a medição do DOM dava 74px de\n conteúdo em 66px de caixa, e o que aparecia era \"09:00\" cortado. */}\n <ModalContent size=\"full\" noPadding className=\"gap-0\">\n <ModalHeader className=\"border-b px-5 py-3.5\">\n <ModalTitle className=\"text-base\">{t('agenda.schedules.title')}</ModalTitle>\n </ModalHeader>\n {/* Empilhado no celular: duas colunas em 414px deixam a lista com 224px\n e o editor com 150px, e nenhum dos dois serve. No telefone a lista\n vira uma faixa curta em cima, e a grade fica com a largura toda. */}\n <ModalBody className=\"flex flex-col overflow-hidden p-0 sm:h-full sm:max-h-[78vh] sm:flex-row\">\n {/* Coluna de nomes — a mesma forma do V1: buscar, escolher, editar\n ao lado. */}\n <div className=\"flex max-h-44 shrink-0 flex-col border-b sm:max-h-none sm:w-56 sm:border-b-0 sm:border-r\">\n <div className=\"relative p-2\">\n <Search className=\"pointer-events-none absolute left-4 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground\" />\n <Input\n type=\"search\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder={t('agenda.schedules.searchProfessional')}\n className=\"h-auto rounded-md border-border bg-background py-1.5 pl-7 pr-2 text-xs shadow-none focus:border-primary focus-visible:ring-0 focus-visible:ring-offset-0\"\n />\n </div>\n <div className=\"flex-1 overflow-y-auto pb-2\">\n {shown.map((prof) => (\n <Button variant=\"bare\" size=\"bare\"\n key={prof.id}\n ref={selectedId === prof.id ? selectedRef : undefined}\n type=\"button\"\n onClick={() => setSelectedId(prof.id)}\n className={\n // Selecionado com o fundo de ativo da casa e barra à\n // esquerda: numa lista de 277 nomes, um cinza a mais que o\n // vizinho não diz de quem é a grade aberta ao lado.\n //\n // O NOME fica em `text-foreground`, não na cor primária: o\n // primário desta marca é um dourado claro, e dourado sobre\n // fundo claro é o texto que ninguém lê. A cor identifica a\n // linha (fundo e barra); quem carrega a informação é o\n // nome, e ele precisa de contraste.\n 'flex w-full items-center justify-start gap-2 border-l-2 px-3 py-2 text-left text-sm transition-colors ' +\n (selectedId === prof.id\n ? 'border-primary bg-primary/10 font-semibold text-foreground'\n : 'border-transparent font-normal text-muted-foreground hover:bg-muted/50 hover:text-foreground')\n }\n >\n {/* O mesmo retrato do seletor e da grade: a coluna desta\n caixa é a MESMA lista de gente, e ela não pode parecer\n outra. */}\n <PersonAvatar name={prof.name} src={prof.avatarUrl} size=\"sm\" />\n <span className=\"truncate\">{prof.name}</span>\n </Button>\n ))}\n {shown.length === 0 && (\n <p className=\"px-3 py-2 text-xs text-muted-foreground\">—</p>\n )}\n </div>\n </div>\n\n {/* Sem `pb`: o pé do editor é `sticky bottom-0`, e um respiro embaixo\n deixaria a lista rolar por baixo dele numa fresta de 16px. */}\n <div className=\"min-w-0 flex-1 overflow-y-auto px-4 pt-4\">\n {selectedId\n ? <ScheduleEditor assigneeId={selectedId} onSaved={invalidateSchedules} />\n : <p className=\"text-sm text-muted-foreground\">{t('agenda.schedules.pickProfessional')}</p>}\n </div>\n </ModalBody>\n </ModalContent>\n </Modal>\n )\n}\n","import React, { useEffect, useRef, useState, useCallback } from 'react'\nimport { createPortal } from 'react-dom'\n\n// ---------------------------------------------------------------------------\n// Inject animations once\n// ---------------------------------------------------------------------------\n\nconst STYLE_ID = 'saas-floating-panel'\nif (typeof document !== 'undefined' && !document.getElementById(STYLE_ID)) {\n const s = document.createElement('style')\n s.id = STYLE_ID\n s.textContent = `\n @keyframes _fp-dismiss { from { opacity:1; transform:scale(1) } to { opacity:0; transform:scale(.96) } }\n @keyframes _fp-expand { from { opacity:1; transform:scale(1) } to { opacity:0; transform:scale(1.08) } }\n .saas-fp-dismissing { animation: _fp-dismiss 150ms ease-in forwards; pointer-events: none }\n .saas-fp-expanding { animation: _fp-expand 200ms ease-in forwards; pointer-events: none }\n `\n document.head.appendChild(s)\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype Phase = 'visible' | 'dismissing' | 'expanding'\n\nexport interface FloatingPanelRef {\n /** Dismiss with fade-out, then call onClose */\n dismiss: () => void\n /** Expand-out animation (e.g. popover → modal), then call callback */\n expandThen: (callback: () => void) => void\n}\n\ninterface FloatingPanelProps {\n position: { x: number; y: number }\n width: number\n height: number\n /** Offset from cursor (default: { x: 0, y: 0 }) */\n offset?: { x: number; y: number }\n onClose: () => void\n className?: string\n children: (ref: FloatingPanelRef) => React.ReactNode\n zIndex?: number\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function FloatingPanel({\n position, width, height, offset, onClose, className, children, zIndex = 100,\n}: FloatingPanelProps) {\n const ref = useRef<HTMLDivElement>(null)\n const [phase, setPhase] = useState<Phase>('visible')\n const phaseRef = useRef<Phase>('visible')\n phaseRef.current = phase\n const onCloseRef = useRef(onClose)\n onCloseRef.current = onClose\n const expandCallbackRef = useRef<(() => void) | null>(null)\n\n const dismiss = useCallback(() => {\n if (phaseRef.current !== 'visible') return\n setPhase('dismissing')\n setTimeout(() => onCloseRef.current(), 150)\n }, [])\n\n const expandThen = useCallback((callback: () => void) => {\n if (phaseRef.current !== 'visible') return\n expandCallbackRef.current = callback\n setPhase('expanding')\n setTimeout(() => {\n callback()\n onCloseRef.current()\n }, 220)\n }, [])\n\n // Outside click + Escape\n useEffect(() => {\n function handleClick(e: MouseEvent) {\n if (phaseRef.current !== 'visible') return\n if (ref.current && !ref.current.contains(e.target as Node)) {\n // Don't dismiss if clicking another calendar event — let eventClick handle it\n const target = e.target as HTMLElement\n if (target.closest('.fc-event')) return\n dismiss()\n }\n }\n function handleKey(e: KeyboardEvent) {\n if (e.key === 'Escape') dismiss()\n }\n document.addEventListener('mousedown', handleClick)\n document.addEventListener('keydown', handleKey)\n return () => {\n document.removeEventListener('mousedown', handleClick)\n document.removeEventListener('keydown', handleKey)\n }\n }, [dismiss])\n\n // Clamp position to viewport\n const ox = offset?.x ?? 0\n const oy = offset?.y ?? 0\n let x = position.x + ox\n let y = position.y + oy\n if (x + width > window.innerWidth - 12) x = x - width - ox * 2\n if (y + height > window.innerHeight - 12) y = y - height - oy * 2\n if (x < 12) x = 12\n if (y < 12) y = 12\n\n const panelRef: FloatingPanelRef = { dismiss, expandThen }\n\n return createPortal(\n <div ref={ref}\n style={{ position: 'fixed', left: x, top: y, zIndex, transition: phase === 'visible' ? 'left 200ms ease-out, top 200ms ease-out' : undefined }}\n className={`fayz-glass-surface rounded-modal border bg-popover shadow-lg overflow-hidden ${\n phase === 'expanding' ? 'saas-fp-expanding'\n : phase === 'dismissing' ? 'saas-fp-dismissing'\n : 'animate-in fade-in zoom-in-95 duration-150'\n } ${className ?? ''}`}>\n {children(panelRef)}\n </div>,\n document.body,\n )\n}\n","import React, { useEffect, useState } from 'react'\nimport { useTranslation } from '@fayz-ai/core'\nimport { useAgendaProvider, useAgendaStore } from '../context'\nimport type { SeriesScope } from '../lib/recurrence'\nimport { Button } from '@fayz-ai/ui'\n\n// ---------------------------------------------------------------------------\n// Deleting one occurrence and deleting the whole series are two different\n// gestures, and on the popover and the context menu they shared one button —\n// the modal already asks. This is the same question in a shape small enough to\n// live inside a floating panel.\n// ---------------------------------------------------------------------------\n\ninterface Target { id: string; seriesId?: string | null }\n\nexport function useSeriesDelete(booking: Target, enabled: boolean, onDone: () => void) {\n const provider = useAgendaProvider()\n const deleteBooking = useAgendaStore((s) => s.deleteBooking)\n const deleteBookingSeries = useAgendaStore((s) => s.deleteBookingSeries)\n // `null` is \"not counted yet\", which is not the same as \"no series\".\n const [seriesSize, setSeriesSize] = useState<number | null>(null)\n const [deleting, setDeleting] = useState<SeriesScope | null>(null)\n\n const seriesId = booking.seriesId ?? null\n\n // Counted only once the person reaches for delete: clicking an event to read\n // it should not cost a query it will never use.\n useEffect(() => {\n if (!enabled || !seriesId || !provider.countSeriesOccurrences) return\n let alive = true\n provider.countSeriesOccurrences(seriesId)\n .then((n) => { if (alive) setSeriesSize(n) })\n .catch(() => { if (alive) setSeriesSize(0) })\n return () => { alive = false }\n }, [enabled, seriesId, provider])\n\n // Optimistic while the count is in flight — a booking that carries a series\n // id almost always has siblings, and the alternative is a confirm step that\n // changes shape under the cursor. A count of 1 (the siblings were already\n // deleted) collapses back to the plain confirm.\n const isSeries = Boolean(seriesId) && seriesSize !== 1 && seriesSize !== 0\n\n async function remove(scope: SeriesScope) {\n setDeleting(scope)\n try {\n if (scope === 'series' && seriesId) await deleteBookingSeries(seriesId)\n else await deleteBooking(booking.id)\n onDone()\n } catch {\n setDeleting(null)\n }\n }\n\n return { isSeries, seriesSize, deleting, remove }\n}\n\nexport function SeriesDeleteChoice({ seriesSize, deleting, onPick, onCancel }: {\n seriesSize: number | null\n deleting: SeriesScope | null\n onPick: (scope: SeriesScope) => void\n onCancel: () => void\n}) {\n const t = useTranslation()\n const allLabel = t('agenda.recurrence.scopeSeriesShort').replace('{{count}}', seriesSize ? String(seriesSize) : '…')\n // Side by side, each half the row: the two scopes are alternatives of equal\n // weight, and stacking them read as a list where one was the default.\n const btn = 'flex-1 min-w-0 whitespace-normal rounded border border-destructive/30 px-2 py-1 text-center'\n + ' text-[11px] font-medium text-destructive hover:bg-destructive/10 disabled:opacity-40 transition-colors'\n\n return (\n <div className=\"px-3 py-2 space-y-1.5\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-[11px] font-medium text-destructive\">{t('agenda.recurrence.scopeDeleteTitle')}</span>\n <Button variant=\"bare\" size=\"bare\" type=\"button\" onClick={onCancel} disabled={deleting !== null}\n className=\"rounded px-1.5 py-0.5 text-[11px] font-medium text-muted-foreground hover:bg-muted/50 transition-colors\">\n {t('agenda.appointment.cancel')}\n </Button>\n </div>\n <div className=\"flex items-stretch gap-1.5\">\n <Button variant=\"bare\" size=\"bare\" type=\"button\" className={btn} disabled={deleting !== null} onClick={() => onPick('this')}>\n {deleting === 'this' ? t('agenda.appointment.deleting') : t('agenda.recurrence.scopeThisShort')}\n </Button>\n <Button variant=\"bare\" size=\"bare\" type=\"button\" className={btn} disabled={deleting !== null} onClick={() => onPick('series')}>\n {deleting === 'series' ? t('agenda.appointment.deleting') : allLabel}\n </Button>\n </div>\n </div>\n )\n}\n","import React, { useState, useRef, useEffect } from 'react'\nimport { X, Pencil, Trash2, Clock, MapPin, User, FileText, DollarSign, Check, AlertTriangle, HandCoins } from 'lucide-react'\nimport { PersonLink } from '@fayz-ai/admin'\nimport { FloatingPanel, type FloatingPanelRef } from './FloatingPanel'\nimport { useAgendaConfig, useAgendaStore } from '../context'\nimport { useTranslation, formatCurrency } from '@fayz-ai/core'\nimport { isStatusAvailable } from '../types'\nimport { SeriesDeleteChoice, useSeriesDelete } from './SeriesDeleteChoice'\nimport type { CalendarBooking } from '../types'\nimport { Button } from '@fayz-ai/ui'\n\ninterface Props {\n booking: CalendarBooking\n position: { x: number; y: number }\n onClose: () => void\n onEdit: (id: string) => void\n}\n\nfunction fmtTime(iso: string) {\n return new Date(iso).toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })\n}\nfunction fmtDate(iso: string) {\n return new Date(iso).toLocaleDateString(undefined, { weekday: 'long', month: 'long', day: 'numeric' })\n}\n\n// Inline status select for the popover\nfunction PopoverStatusSelect({ value, statuses, bookingStartsAt, onChange }: {\n value: string; statuses: Array<{ value: string; label: string; color: string; availableWhen?: string }>\n bookingStartsAt: string; onChange: (v: string) => void\n}) {\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null)\n const current = statuses.find((s) => s.value === value)\n\n useEffect(() => {\n if (!open) return\n const h = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false) }\n document.addEventListener('mousedown', h)\n return () => document.removeEventListener('mousedown', h)\n }, [open])\n\n return (\n <div ref={ref} className=\"relative inline-block\">\n <Button variant=\"bare\" size=\"bare\" type=\"button\" onClick={() => setOpen((p) => !p)}\n className=\"inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-[11px] font-medium transition-colors hover:opacity-80\"\n style={{ backgroundColor: (current?.color ?? '#6b7280') + '18', color: current?.color ?? '#6b7280' }}>\n <span className=\"h-2 w-2 rounded-full\" style={{ backgroundColor: current?.color }} />\n {current?.label ?? value}\n <svg className=\"h-3 w-3 opacity-50\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M4 6l4 4 4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/>\n </svg>\n </Button>\n {open && (\n <div className=\"fayz-glass-surface absolute bottom-full left-0 z-50 mb-1 rounded-lg border bg-popover shadow-lg py-1 animate-in fade-in zoom-in-95 duration-100 min-w-[140px]\">\n {statuses.map((s) => {\n const available = isStatusAvailable(s as any, bookingStartsAt)\n return (\n <Button variant=\"bare\" size=\"bare\" key={s.value} type=\"button\" disabled={!available}\n onClick={() => { if (available) { onChange(s.value); setOpen(false) } }}\n className={`font-normal justify-start whitespace-normal flex w-full items-center gap-2 px-3 py-1.5 text-xs transition-colors ${\n !available ? 'disabled:pointer-events-auto disabled:cursor-not-allowed disabled:opacity-30' : s.value === value ? 'bg-muted/30' : 'hover:bg-muted/50'\n }`}>\n <span className=\"h-2 w-2 rounded-full shrink-0\" style={{ backgroundColor: s.color }} />\n <span>{s.label}</span>\n </Button>\n )\n })}\n </div>\n )}\n </div>\n )\n}\n\nexport function AppointmentPopover({ booking, position, onClose, onEdit }: Props) {\n const t = useTranslation()\n const config = useAgendaConfig()\n const updateStatus = useAgendaStore((s) => s.updateBookingStatus)\n const openModal = useAgendaStore((s) => s.openAppointmentModal)\n const [confirmingDelete, setConfirmingDelete] = useState(false)\n const series = useSeriesDelete(booking, confirmingDelete, onClose)\n const deleting = series.deleting !== null\n const statusConfig = config.statuses.find((s) => s.value === booking.status)\n const color = statusConfig?.color ?? '#6b7280'\n const timeRange = `${fmtTime(booking.startsAt)}${booking.endsAt ? ' – ' + fmtTime(booking.endsAt) : ''}`\n\n return (\n <>\n <FloatingPanel position={position} width={320} height={340} onClose={onClose}>\n {(panel) => (\n <>\n {/* Action bar */}\n <div className=\"flex items-center justify-end gap-0.5 px-3 pt-3 pb-1\">\n {confirmingDelete && series.isSeries ? (\n <div className=\"w-full\">\n <SeriesDeleteChoice seriesSize={series.seriesSize} deleting={series.deleting}\n onPick={(scope) => { void series.remove(scope) }} onCancel={() => setConfirmingDelete(false)} />\n </div>\n ) : confirmingDelete ? (\n <>\n <span className=\"text-xs text-destructive font-medium mr-auto pl-1\">{t('agenda.appointment.deleteConfirm')}</span>\n <Button variant=\"bare\" size=\"bare\" onClick={() => setConfirmingDelete(false)}\n className=\"rounded px-2 py-0.5 text-[11px] font-medium hover:bg-muted/50 transition-colors\">{t('agenda.appointment.cancel')}</Button>\n <Button variant=\"bare\" size=\"bare\" onClick={() => { void series.remove('this') }} disabled={deleting}\n className=\"rounded bg-destructive border border-destructive px-2 py-0.5 text-[11px] font-medium text-destructive-foreground hover:bg-destructive/90 shadow-button-primary active:shadow-button-inset disabled:opacity-40 transition-colors\">{deleting ? t('agenda.appointment.deleting') : t('agenda.appointment.confirmDelete')}</Button>\n </>\n ) : (\n <>\n <Button variant=\"bare\" size=\"bare\" onClick={() => panel.expandThen(() => onEdit(booking.id))}\n className=\"p-1.5 rounded-full hover:bg-muted transition-colors\" title={t('common.edit')}>\n <Pencil className=\"h-4 w-4 text-muted-foreground\" />\n </Button>\n <Button variant=\"bare\" size=\"bare\" onClick={() => setConfirmingDelete(true)}\n className=\"p-1.5 rounded-full hover:bg-destructive/10 transition-colors\" title={t('common.delete')}>\n <Trash2 className=\"h-4 w-4 text-muted-foreground hover:text-destructive\" />\n </Button>\n <Button variant=\"bare\" size=\"bare\" onClick={panel.dismiss} className=\"p-1.5 rounded-full hover:bg-muted transition-colors\">\n <X className=\"h-4 w-4 text-muted-foreground\" />\n </Button>\n </>\n )}\n </div>\n\n {/* Content */}\n <div className=\"px-5 pb-5 space-y-3\">\n <div className=\"flex items-start gap-3\">\n <span className=\"mt-1.5 h-3 w-3 rounded shrink-0\" style={{ backgroundColor: color }} />\n <div className=\"min-w-0\">\n {/* Client agendas link to the person; simple events (no client\n capability) render the free-text title as a plain heading —\n booking.clientName carries the event title in that model. */}\n {config.capabilities.client ? (\n <PersonLink personId={booking.clientId} name={booking.clientName ?? 'Unknown'} className=\"text-base\" />\n ) : (\n <p className=\"text-base font-medium truncate\">{booking.clientName || t('agenda.appointment.untitled')}</p>\n )}\n <p className=\"text-sm text-muted-foreground mt-0.5\">{fmtDate(booking.startsAt)} · {timeRange}</p>\n </div>\n </div>\n\n {booking.services && booking.services.length > 0 && (\n <div className=\"flex items-start gap-3\">\n <Clock className=\"h-4 w-4 mt-0.5 text-muted-foreground shrink-0\" />\n <div className=\"text-sm space-y-0.5\">\n {booking.services.map((svc) => (\n <p key={svc.id}>{svc.name} <span className=\"text-muted-foreground\">({svc.durationMinutes}min)</span></p>\n ))}\n </div>\n </div>\n )}\n\n {config.capabilities.professional && booking.professionalName && (\n <div className=\"flex items-center gap-3\">\n <User className=\"h-4 w-4 text-muted-foreground shrink-0\" />\n <span className=\"text-sm\">{booking.professionalName}</span>\n </div>\n )}\n\n {booking.locationName && (\n <div className=\"flex items-center gap-3\">\n <MapPin className=\"h-4 w-4 text-muted-foreground shrink-0\" />\n <span className=\"text-sm\">{booking.locationName}</span>\n </div>\n )}\n\n {booking.notes && (\n <div className=\"flex items-start gap-3\">\n <FileText className=\"h-4 w-4 mt-0.5 text-muted-foreground shrink-0\" />\n <p className=\"text-sm text-muted-foreground\">{booking.notes}</p>\n </div>\n )}\n\n {booking.orderTotal != null && booking.orderTotal > 0 && (() => {\n const total = formatCurrency(booking.orderTotal, config.currency.code)\n const ps = booking.paymentStatus ?? 'none'\n const hasFinancial = config.modules.financial && booking.orderId\n\n // No financial module — just show total\n if (!hasFinancial) {\n return (\n <div className=\"pt-2 border-t fayz-glass-divider flex items-center justify-between text-sm\">\n <span className=\"text-muted-foreground\">{t('agenda.appointment.total')}</span>\n <span className=\"font-medium\">{total}</span>\n </div>\n )\n }\n\n const badgeConfig: Record<string, { icon: React.ElementType; bg: string; text: string; label: string }> = {\n none: { icon: HandCoins, bg: 'bg-warning/10 hover:bg-warning/15', text: 'text-warning', label: `${total} · ${t('agenda.payment.collect')}` },\n pending: { icon: Clock, bg: 'bg-warning/10 hover:bg-warning/15', text: 'text-warning', label: `${total} · ${t('agenda.payment.pending')}` },\n partial: { icon: DollarSign, bg: 'bg-warning/10 hover:bg-warning/15', text: 'text-warning', label: `${total} · ${t('agenda.payment.partial')}` },\n paid: { icon: Check, bg: 'bg-success/10 hover:bg-success/15', text: 'text-success', label: `${total} · ${t('agenda.payment.paid')}` },\n overdue: { icon: AlertTriangle, bg: 'bg-destructive/10 hover:bg-destructive/15', text: 'text-destructive', label: `${total} · ${t('agenda.payment.overdue')}` },\n cancelled: { icon: X, bg: 'bg-muted hover:bg-muted/80', text: 'text-muted-foreground', label: `${total} · ${t('agenda.payment.cancelled')}` },\n }\n const cfg = badgeConfig[ps] ?? badgeConfig.none\n const StatusIcon = cfg.icon\n\n return (\n <div className=\"pt-2 border-t fayz-glass-divider flex items-center justify-between\">\n <span className=\"text-xs text-muted-foreground\">{t('agenda.appointment.total')}</span>\n <Button variant=\"bare\" size=\"bare\"\n type=\"button\"\n onClick={() => { onClose(); openModal('edit', { bookingId: booking.id, initialTab: 'financial' }) }}\n className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium transition-colors ${cfg.bg} ${cfg.text}`}\n >\n <StatusIcon className=\"h-3 w-3\" />\n {cfg.label}\n </Button>\n </div>\n )\n })()}\n\n {/* Status workflow — hidden for simple events (no status capability). */}\n {config.capabilities.status && (\n <div className=\"pt-2 border-t fayz-glass-divider\">\n <PopoverStatusSelect\n value={booking.status}\n statuses={config.statuses}\n bookingStartsAt={booking.startsAt}\n onChange={(v) => { updateStatus(booking.id, v); onClose() }}\n />\n </div>\n )}\n </div>\n </>\n )}\n </FloatingPanel>\n </>\n )\n}\n","import React, { useRef, useState, useMemo } from 'react'\nimport { createPortal } from 'react-dom'\nimport { Pencil, Trash2, Check } from 'lucide-react'\nimport { FloatingPanel } from './FloatingPanel'\nimport { useAgendaConfig, useAgendaStore } from '../context'\nimport { useTranslation } from '@fayz-ai/core'\nimport { isStatusAvailable } from '../types'\nimport { SeriesDeleteChoice, useSeriesDelete } from './SeriesDeleteChoice'\nimport type { CalendarBooking } from '../types'\nimport { Button } from '@fayz-ai/ui'\n\n// ---------------------------------------------------------------------------\n// Tooltip — portaled to body\n// ---------------------------------------------------------------------------\n\nfunction Tooltip({ anchor, label }: { anchor: DOMRect; label: string }) {\n return createPortal(\n <div style={{ position: 'fixed', left: anchor.left + anchor.width / 2, top: anchor.bottom + 6, transform: 'translateX(-50%)', zIndex: 120 }}\n className=\"pointer-events-none\">\n <div className=\"rounded-md bg-foreground text-background px-2 py-0.5 text-[11px] font-medium whitespace-nowrap shadow-lg\">\n {label}\n </div>\n </div>,\n document.body,\n )\n}\n\n// ---------------------------------------------------------------------------\n// Status dot with portaled tooltip\n// ---------------------------------------------------------------------------\n\nfunction StatusDot({ color, label, isActive, disabled, onClick }: {\n color: string; label: string; isActive: boolean; disabled?: boolean; onClick: () => void\n}) {\n const [hover, setHover] = useState(false)\n const btnRef = useRef<HTMLButtonElement>(null)\n const [rect, setRect] = useState<DOMRect | null>(null)\n\n return (\n <>\n <Button variant=\"bare\" size=\"bare\" ref={btnRef} type=\"button\" onClick={disabled ? undefined : onClick} disabled={disabled}\n onMouseEnter={() => { setHover(true); if (btnRef.current) setRect(btnRef.current.getBoundingClientRect()) }}\n onMouseLeave={() => setHover(false)}\n className={`flex h-7 w-7 items-center justify-center rounded-full transition-all ${\n disabled ? 'disabled:pointer-events-auto disabled:cursor-not-allowed disabled:opacity-25' : isActive ? 'ring-2 ring-offset-2 ring-offset-popover' : 'hover:scale-110'\n }`}\n style={{ backgroundColor: color, ['--tw-ring-color' as any]: isActive ? color : undefined }}>\n {isActive && <Check className=\"h-3.5 w-3.5 text-white\" strokeWidth={2.5} />}\n </Button>\n {hover && rect && <Tooltip anchor={rect} label={label} />}\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Context Menu\n// ---------------------------------------------------------------------------\n\ninterface Props {\n booking: CalendarBooking\n position: { x: number; y: number }\n onClose: () => void\n onEdit: (id: string) => void\n}\n\nexport function EventContextMenu({ booking, position, onClose, onEdit }: Props) {\n const t = useTranslation()\n const config = useAgendaConfig()\n const updateStatus = useAgendaStore((s) => s.updateBookingStatus)\n const [confirming, setConfirming] = useState(false)\n const series = useSeriesDelete(booking, confirming, onClose)\n const deleting = series.deleting !== null\n\n return (\n <FloatingPanel position={position} width={230} height={180} offset={{ x: 4, y: 4 }} onClose={onClose} zIndex={110}>\n {(panel) => (\n <>\n <div className=\"py-1\">\n <Button variant=\"bare\" size=\"bare\" onClick={() => panel.expandThen(() => onEdit(booking.id))}\n className=\"font-normal justify-start rounded-none whitespace-normal flex w-full items-center gap-3 px-4 py-2 text-sm hover:bg-muted/50 transition-colors\">\n <Pencil className=\"h-4 w-4 text-muted-foreground\" /> {t('agenda.contextMenu.edit')}\n </Button>\n {confirming && series.isSeries ? (\n <SeriesDeleteChoice seriesSize={series.seriesSize} deleting={series.deleting}\n onPick={(scope) => { void series.remove(scope) }} onCancel={() => setConfirming(false)} />\n ) : confirming ? (\n <div className=\"flex items-center justify-between px-4 py-2\">\n <span className=\"text-xs text-destructive font-medium\">{t('agenda.appointment.deleteConfirm')}</span>\n <div className=\"flex items-center gap-1.5\">\n <Button variant=\"bare\" size=\"bare\" onClick={() => setConfirming(false)}\n className=\"rounded px-2 py-0.5 text-[11px] font-medium hover:bg-muted/50 transition-colors\">{t('agenda.appointment.cancel')}</Button>\n <Button variant=\"bare\" size=\"bare\" onClick={() => { void series.remove('this') }} disabled={deleting}\n className=\"rounded bg-destructive border border-destructive px-2 py-0.5 text-[11px] font-medium text-destructive-foreground hover:bg-destructive/90 shadow-button-primary active:shadow-button-inset disabled:opacity-40 transition-colors\">{deleting ? t('agenda.appointment.deleting') : t('agenda.appointment.confirmDelete')}</Button>\n </div>\n </div>\n ) : (\n <Button variant=\"bare\" size=\"bare\" onClick={() => setConfirming(true)}\n className=\"font-normal justify-start rounded-none whitespace-normal flex w-full items-center gap-3 px-4 py-2 text-sm hover:bg-muted/50 transition-colors text-destructive\">\n <Trash2 className=\"h-4 w-4\" /> {t('agenda.contextMenu.delete')}\n </Button>\n )}\n </div>\n\n {/* Status workflow — hidden for simple events (no status capability). */}\n {config.capabilities.status && (\n <div className=\"border-t px-4 py-3\">\n <p className=\"text-[11px] font-medium text-muted-foreground mb-2\">{t('agenda.contextMenu.changeStatus')}</p>\n <div className=\"flex items-center gap-1.5\">\n {config.statuses.map((s) => {\n const available = isStatusAvailable(s, booking.startsAt)\n return (\n <StatusDot key={s.value} color={s.color} label={available ? s.label : `${s.label} ${t('agenda.contextMenu.notAvailable')}`}\n isActive={booking.status === s.value}\n disabled={!available}\n onClick={() => { if (available) { updateStatus(booking.id, s.value); panel.dismiss() } }} />\n )\n })}\n </div>\n </div>\n )}\n </>\n )}\n </FloatingPanel>\n )\n}\n","import React, { useMemo } from 'react'\nimport { formatCurrency, useTranslation, getCurrentLocale } from '@fayz-ai/core'\nimport type { CalendarBooking } from '../types'\nimport { localDateKey } from '@fayz-ai/core'\nimport { Button } from '@fayz-ai/ui'\n\n// ---------------------------------------------------------------------------\n// Mobile agenda list — a thumb-friendly, date-grouped list of upcoming items.\n// Rendered on <md viewports instead of the FullCalendar grid. Each row shows a\n// category/status dot, the title, the time, and (for finance-style events) the\n// amount. Fed straight from the store bookings so it works for any seeded app.\n// ---------------------------------------------------------------------------\n\nfunction startOfDay(d: Date): Date {\n const x = new Date(d)\n x.setHours(0, 0, 0, 0)\n return x\n}\n\nfunction timeLabel(iso: string): string {\n const d = new Date(iso)\n return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`\n}\n\nexport interface AgendaMobileListProps {\n bookings: CalendarBooking[]\n statusColors: Record<string, string>\n currencyCode: string\n onSelect: (booking: CalendarBooking) => void\n /** Lets the empty state offer the one thing the screen is for. */\n onCreate?: () => void\n}\n\n/**\n * Loading state for the mobile list. Shaped like the list it replaces — a day\n * heading and a couple of rows — so the screen does not jump when real data\n * lands. A blank pane while the query runs reads as \"nothing scheduled\", which\n * is the one answer this screen must never give wrongly.\n */\nexport function AgendaMobileListSkeleton() {\n return (\n <div className=\"flex-1 space-y-5 overflow-hidden px-3 py-3\" aria-busy=\"true\" aria-live=\"polite\">\n {[0, 1].map((g) => (\n <div key={g} className=\"animate-pulse\">\n <div className=\"mb-2 ml-1 h-3 w-20 rounded bg-muted\" />\n <div className=\"space-y-1.5\">\n {[0, 1].map((r) => (\n <div key={r} className=\"flex items-center gap-3 rounded-card border border-border bg-card px-3 py-3\">\n <div className=\"h-2 w-2 shrink-0 rounded-full bg-muted\" />\n <div className=\"min-w-0 flex-1 space-y-1.5\">\n <div className=\"h-3.5 w-2/3 rounded bg-muted\" />\n <div className=\"h-3 w-12 rounded bg-muted\" />\n </div>\n <div className=\"h-3.5 w-14 shrink-0 rounded bg-muted\" />\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n )\n}\n\nexport function AgendaMobileList({ bookings, statusColors, currencyCode, onSelect, onCreate }: AgendaMobileListProps) {\n const t = useTranslation()\n const locale = getCurrentLocale() === 'pt-BR' ? 'pt-BR' : 'en'\n\n const groups = useMemo(() => {\n const todayStart = startOfDay(new Date()).getTime()\n const sorted = bookings\n .filter((b) => !!b.startsAt)\n .slice()\n .sort((a, b) => (a.startsAt < b.startsAt ? -1 : a.startsAt > b.startsAt ? 1 : 0))\n const map = new Map<string, CalendarBooking[]>()\n for (const b of sorted) {\n const day = startOfDay(new Date(b.startsAt))\n if (day.getTime() < todayStart) continue // upcoming only\n const key = localDateKey(day)\n const list = map.get(key) ?? []\n list.push(b)\n map.set(key, list)\n }\n return Array.from(map.entries()).map(([key, items]) => ({ key, date: new Date(key + 'T00:00:00'), items }))\n }, [bookings])\n\n function dayLabel(date: Date): string {\n const today = startOfDay(new Date())\n const diff = Math.round((startOfDay(date).getTime() - today.getTime()) / 86400000)\n if (diff === 0) return t('agenda.list.today')\n if (diff === 1) return t('agenda.list.tomorrow')\n return date.toLocaleDateString(locale, { weekday: 'long', day: 'numeric', month: 'long' })\n }\n\n if (groups.length === 0) {\n return (\n <div className=\"flex flex-1 flex-col items-center justify-center gap-4 px-6 py-16 text-center\">\n <p className=\"text-sm text-muted-foreground\">{t('agenda.list.empty')}</p>\n {onCreate && (\n <Button variant=\"bare\" size=\"bare\"\n type=\"button\"\n onClick={onCreate}\n className=\"fz-tap inline-flex items-center rounded-full bg-primary px-5 text-sm font-medium text-primary-foreground active:scale-[0.98]\"\n >\n {t('agenda.calendar.newAppointment')}\n </Button>\n )}\n </div>\n )\n }\n\n return (\n <div className=\"flex-1 overflow-y-auto px-3 py-3 space-y-5\">\n {groups.map((g) => (\n <div key={g.key}>\n <h3 className=\"px-1 pb-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {dayLabel(g.date)}\n </h3>\n <div className=\"space-y-1.5\">\n {g.items.map((b) => {\n const color = statusColors[b.status] ?? '#6b7280'\n const hasAmount = typeof b.orderTotal === 'number' && b.orderTotal > 0\n return (\n <Button variant=\"bare\" size=\"bare\"\n key={b.id}\n onClick={() => onSelect(b)}\n className=\"font-normal justify-start whitespace-normal flex w-full items-center gap-3 rounded-card border bg-card px-3 py-2.5 text-left shadow-sm transition-colors active:bg-muted/50\"\n >\n <span className=\"h-2.5 w-2.5 shrink-0 rounded-full\" style={{ backgroundColor: color }} />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-foreground\">{b.clientName ?? '—'}</p>\n <p className=\"text-xs text-muted-foreground\">{timeLabel(b.startsAt)}</p>\n </div>\n {hasAmount && (\n <span className=\"shrink-0 text-sm font-semibold tabular-nums text-foreground\">\n {formatCurrency(b.orderTotal, currencyCode)}\n </span>\n )}\n </Button>\n )\n })}\n </div>\n </div>\n ))}\n </div>\n )\n}\n","// ---------------------------------------------------------------------------\n// O MOTOR DE GRADES — o mesmo que o banco roda, agora também na tela.\n//\n// `public.agenda_working_windows` decide quais janelas um profissional tem num\n// dia, e é ele que o \"horários disponíveis\" consulta. A GRADE DESENHADA, que é\n// o que a recepção lê, decidia por conta própria: pegava toda linha do weekday\n// e desenhava. As duas respostas divergiam em três pontos, e as três vezes a\n// tela era a errada.\n//\n// VIGÊNCIA a grade vale de `validFrom` a `validTo`. Sem isso, grade\n// encerrada continua abrindo coluna e grade que só começa em\n// 2027 já abre hoje.\n//\n// PRECEDÊNCIA durante a vigência de uma grade de EXCEÇÃO, cada weekday que\n// ela define SUBSTITUI a padrão naquele dia — e só naquele. Os\n// weekdays que ela não define seguem a padrão. Somar as duas,\n// que era o que a tela fazia, desenha a semana antiga por baixo\n// da nova: o horário que a casa MUDOU continua ofertado.\n//\n// PARIDADE `weekInterval`: 0 = toda semana; N = atende uma e pula N,\n// ancorado na PRIMEIRA ocorrência daquele weekday dentro da\n// vigência. E quando a paridade da exceção pula a semana, o dia\n// fica FECHADO — não volta para a padrão.\n//\n// A fonte é o motor puro do V1 (`resolveEffectiveWindows`, `blockActiveOnDate`),\n// que lá é compartilhado verbatim entre o front e as edge functions. Aqui ele\n// vive num arquivo só, com teste, porque duas cópias da mesma regra voltam a\n// divergir — foi exatamente o que aconteceu entre o SQL e a tela.\n// ---------------------------------------------------------------------------\n\nexport interface GridRow {\n dayOfWeek?: number | null\n specificDate?: string | null\n gridKind?: string | null\n weekInterval?: number | null\n validFrom?: string | null\n validTo?: string | null\n isActive?: boolean\n}\n\n/** O dia da semana de um `YYYY-MM-DD`, sem passar por fuso. */\nfunction dow(iso: string): number {\n const [y, m, d] = iso.slice(0, 10).split('-').map(Number)\n return new Date(Date.UTC(y, m - 1, d)).getUTCDay()\n}\n\n/** Dias desde a época, em UTC — subtração de datas sem horário de verão no meio. */\nfunction days(iso: string): number {\n const [y, m, d] = iso.slice(0, 10).split('-').map(Number)\n return Math.round(Date.UTC(y, m - 1, d) / 86400000)\n}\n\n/**\n * Esta grade vale no dia `iso`?\n *\n * Comparação de TEXTO: `YYYY-MM-DD` ordena igual como string, e\n * `new Date('2025-04-30')` é meia-noite UTC — no Brasil, o dia anterior. Uma\n * vigência que começa no dia 30 abriria no dia 29.\n *\n * Ponta ausente é ponta aberta, como o V1 escreve (\"Vazio = sem data final\").\n */\nexport function gridAppliesOn(grid: Pick<GridRow, 'validFrom' | 'validTo'>, iso: string): boolean {\n const dia = iso.slice(0, 10)\n if (grid.validFrom && dia < grid.validFrom.slice(0, 10)) return false\n if (grid.validTo && dia > grid.validTo.slice(0, 10)) return false\n return true\n}\n\n/**\n * Esta é \"semana sim\"?\n *\n * Espelho de `public.agenda_week_parity_active`. A âncora é a primeira\n * ocorrência DAQUELE weekday dentro da vigência — por isso o desconto de uma\n * semana quando o weekday cai antes do dia em que a vigência começou: uma\n * grade que começa numa quarta e define segunda só tem a primeira segunda na\n * semana seguinte.\n *\n * Sem `validFrom` não há âncora, e sem âncora não há paridade: vale sempre.\n */\nexport function weekParityActive(\n validFrom: string | null | undefined,\n iso: string,\n weekInterval: number | null | undefined,\n): boolean {\n const passo = weekInterval ?? 0\n if (passo <= 0 || !validFrom) return true\n const dia = iso.slice(0, 10)\n const inicio = validFrom.slice(0, 10)\n const semanas = (days(dia) - dow(dia) - (days(inicio) - dow(inicio))) / 7\n - (dow(dia) < dow(inicio) ? 1 : 0)\n return semanas >= 0 && semanas % (passo + 1) === 0\n}\n\n/**\n * As janelas efetivas de UM profissional no dia `iso`.\n *\n * Espelho de `public.agenda_working_windows`, na mesma ordem de decisão:\n *\n * 1. fora da vigência não participa de nada — nem como exceção que fecha;\n * 2. a exceção de DATA manda em tudo, e conta MESMO INATIVA: é assim que o\n * \"dia de folga\" apaga a semana em vez de deixar a padrão voltar;\n * 3. a grade de exceção que define este weekday tira a padrão do dia,\n * mesmo quando a paridade dela pula a semana.\n */\nexport function effectiveWindows<T extends GridRow>(rows: T[], iso: string): T[] {\n const dia = iso.slice(0, 10)\n const semana = dow(dia)\n const vigentes = rows.filter((r) => gridAppliesOn(r, dia))\n\n // 2. A exceção de DATA. Existir já basta para calar a semana; só as ativas\n // viram janela.\n const doDia = vigentes.filter((r) => r.specificDate?.slice(0, 10) === dia)\n if (doDia.length > 0) return doDia.filter((r) => r.isActive !== false)\n\n const semanais = vigentes.filter(\n (r) => !r.specificDate && r.isActive !== false && r.dayOfWeek === semana,\n )\n\n // 3. Alguém definiu este weekday numa grade de exceção? Repare que a\n // paridade NÃO entra aqui: exceção que pula a semana fecha o dia.\n const temExcecao = semanais.some((r) => r.gridKind === 'exception')\n\n const comParidade = semanais.filter((r) => weekParityActive(r.validFrom, dia, r.weekInterval))\n return temExcecao\n ? comParidade.filter((r) => r.gridKind === 'exception')\n : comParidade\n}\n\n/** Atalho para a pergunta que a coluna faz: \"esta pessoa abre neste dia?\". */\nexport function opensOnDate(rows: GridRow[], iso: string): boolean {\n return effectiveWindows(rows, iso).length > 0\n}\n","import type { EventInput } from '@fullcalendar/core'\nimport type { CalendarBooking } from '../types'\n\n/**\n * Booking → FullCalendar event. Extracted from CalendarView so the resource-lane\n * rule below is testable without mounting the grid.\n */\n/**\n * Card fill by the SERVICE, as V1 paints it (AdvancedCalendar): a revision is black, otherwise the\n * colour the service was given, otherwise blue. The status moves to a stripe on the left. Opt-in\n * per tenant (FAY-1613).\n */\nexport const REVISION_CARD_COLOR = '#111827'\nexport const DEFAULT_SERVICE_CARD_COLOR = '#3b82f6'\n\nexport type ServiceAppearance = Record<string, { kind: string; color: string | null }>\n\nexport function bookingCardColor(booking: CalendarBooking, looks: ServiceAppearance): string | null {\n const own = (booking.services ?? []).map((s) => (s.serviceId ? looks[s.serviceId] : undefined)).filter(Boolean) as Array<{ kind: string; color: string | null }>\n if (own.length === 0) return null\n if (own.some((l) => l.kind === 'return')) return REVISION_CARD_COLOR\n return own.find((l) => l.color)?.color ?? DEFAULT_SERVICE_CARD_COLOR\n}\n\n/** Text that stays readable on a colour someone picked for a service (amber, yellow, light grey…). */\nexport function readableTextOn(hex: string): string {\n let h = hex.replace('#', '')\n if (h.length === 3) h = h.split('').map((c) => c + c).join('')\n const [r, g, b] = [0, 2, 4].map((i) => parseInt(h.slice(i, i + 2), 16) / 255)\n const lin = (c: number) => (c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4)\n const L = 0.2126 * lin(r!) + 0.7152 * lin(g!) + 0.0722 * lin(b!)\n // Pick whichever of black or white contrasts more (WCAG relative luminance).\n return (L + 0.05) / 0.05 > 1.05 / (L + 0.05) ? '#111827' : '#ffffff'\n}\n\nexport function bookingToEvent(\n booking: CalendarBooking,\n statusColors: Record<string, string>,\n visibleResourceIds: string[] = [],\n serviceLooks?: ServiceAppearance,\n): EventInput {\n const color = statusColors[booking.status] ?? '#6b7280'\n const kindColor = serviceLooks ? bookingCardColor(booking, serviceLooks) : null\n const serviceNames = booking.services?.map((service) => service.name).join(', ') ?? ''\n return {\n id: booking.id,\n // A tenant-wide block (an imported whole-agenda Google event, for example)\n // has no assignee. Availability treats it as busy for every professional, so\n // resource views must render it in every visible lane instead of dropping it.\n ...(booking.professionalId\n ? { resourceId: booking.professionalId }\n : visibleResourceIds.length > 0\n ? { resourceIds: visibleResourceIds }\n : {}),\n title: booking.clientName ?? 'Sem cliente',\n start: booking.startsAt,\n end: booking.endsAt ?? undefined,\n backgroundColor: kindColor ?? color + '30',\n borderColor: kindColor ?? color,\n textColor: kindColor ? readableTextOn(kindColor) : color,\n extendedProps: { booking, serviceNames, ...(kindColor ? { statusStripe: color } : {}) },\n }\n}\n","import React, { useRef, useEffect, useLayoutEffect, useCallback, useMemo, useState } from 'react'\nimport { injectCalendarStyles } from '../styles/calendar-styles'\nimport FullCalendar from '@fullcalendar/react'\nimport dayGridPlugin from '@fullcalendar/daygrid'\nimport timeGridPlugin from '@fullcalendar/timegrid'\nimport resourceTimeGridPlugin from '@fullcalendar/resource-timegrid'\nimport interactionPlugin from '@fullcalendar/interaction'\nimport type { DateClickArg } from '@fullcalendar/interaction'\nimport listPlugin from '@fullcalendar/list'\nimport ptBrLocale from '@fullcalendar/core/locales/pt-br'\nimport type { EventInput, EventClickArg, DateSelectArg, EventDropArg } from '@fullcalendar/core'\nimport { ChevronLeft, ChevronRight, Plus, ChevronDown, Settings, Ban, Clock3 } from 'lucide-react'\nimport { usePluginPrefs, PageActions, useTenantPluginSettings, useAdminPath, adminNavigateTo } from '@fayz-ai/admin'\nimport { agendaPath, calendarViewFor, parseAgendaPath, urlViewOf } from '../lib/agenda-url'\nimport { getCurrentLocale, navigateApp, currentAppPath, appHref } from '@fayz-ai/core'\nimport { useTranslation, useDataChanged, useActiveUnitId } from '@fayz-ai/core'\nimport { useAgendaConfig, useAgendaProvider, useAgendaStore } from '../context'\nimport { useAgendaSettings } from '../hooks/useAgendaSettings'\nimport {\n Button,\n MiniCalendar,\n Badge,\n ConfirmDialog,\n toast,\n MultiSelect,\n PersonAvatar,\n PersonMultiPicker,\n Select,\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n Switch,\n SegmentedControl,\n PageHeaderActions,\n abbreviatePersonName,\n} from '@fayz-ai/ui'\nimport { StatusFilterList } from '../components/FilterRail'\nimport { AgendaFilterRail, AgendaRailColumn, AdaptiveFilter, INLINE_FILTER_MAX } from '../components/AgendaFilterRail'\nimport { BlockDialog, type EditingBlock } from '../components/BlockDialog'\nimport { LostSlotsCard } from '../components/LostSlotsCard'\nimport { ScheduleGridDialog } from '../components/ScheduleGridDialog'\nimport { AppointmentModal } from '../components/AppointmentModal'\nimport { AppointmentPopover } from '../components/AppointmentPopover'\nimport { PersonLink } from '@fayz-ai/admin'\nimport { EventContextMenu } from '../components/EventContextMenu'\nimport { AgendaMobileList, AgendaMobileListSkeleton } from '../components/AgendaMobileList'\nimport type { CalendarBooking, Professional, Schedule } from '../types'\nimport type { AgendaHoliday } from '../data/types'\nimport { effectiveWindows, opensOnDate } from '../lib/schedule-engine'\nimport { bookingToEvent, type ServiceAppearance } from '../lib/calendar-events'\nimport { localDateKey } from '@fayz-ai/core'\nimport { getTurnQueueLeader, subscribeTurnQueueLeader } from '../lib/turn-queue-presence'\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * `2026-09-28T14:30:00` pelo relógio LOCAL. `toISOString` devolveria UTC, e um\n * clique nas 14h no Brasil viraria 17h no formulário.\n */\nfunction localDateTimeString(d: Date): string {\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${localDateKey(d)}T${pad(d.getHours())}:${pad(d.getMinutes())}:00`\n}\n\n/**\n * Generate FullCalendar background events showing unavailable time.\n * For each day, creates background blocks for the gaps OUTSIDE working hours\n * within the visible business hours window. This grays out non-working time.\n */\nfunction generateAvailabilityEvents(\n schedules: Schedule[],\n professionals: { id: string }[],\n dateRange: { start: string; end: string } | null,\n businessHours?: { startTime: string; endTime: string },\n locationMap?: Map<string, string>,\n defaultLocationName?: string,\n): EventInput[] {\n if (!dateRange || schedules.length === 0) return []\n\n const bgEvents: EventInput[] = []\n const startDate = new Date(dateRange.start)\n const endDate = new Date(dateRange.end)\n const bizStart = businessHours?.startTime ?? '08:00'\n const bizEnd = businessHours?.endTime ?? '20:00'\n\n // Group schedules by assignee\n const byAssignee = new Map<string, Schedule[]>()\n for (const s of schedules) {\n const aid = s.assigneeId\n if (!aid) continue\n const list = byAssignee.get(aid) ?? []\n list.push(s)\n byAssignee.set(aid, list)\n }\n\n function timeToMinutes(t: string): number {\n const [h, m] = t.split(':').map(Number)\n return h * 60 + m\n }\n\n function minutesToTime(m: number): string {\n return `${String(Math.floor(m / 60)).padStart(2, '0')}:${String(m % 60).padStart(2, '0')}`\n }\n\n const bizStartMin = timeToMinutes(bizStart)\n const bizEndMin = timeToMinutes(bizEnd)\n\n for (const prof of professionals) {\n const profSchedules = byAssignee.get(prof.id) ?? []\n\n const current = new Date(startDate)\n while (current < endDate) {\n const dateStr = localDateKey(current)\n\n // AS MESMAS JANELAS QUE O BANCO OFERECE. Esta função desenhava por conta\n // própria — todo weekday que batia virava faixa — e divergia de\n // `agenda_working_windows` em vigência, precedência e paridade. Agora as\n // duas leem a mesma regra, que mora em `lib/schedule-engine.ts`.\n const daySchedules = effectiveWindows(profSchedules, dateStr)\n\n // Convert working periods to sorted minute ranges, preserving locationId\n const workRanges = daySchedules\n .map((s) => {\n const locId = s.locationId ?? (s.metadata?.locationId as string | undefined)\n return {\n start: timeToMinutes(s.startsAt),\n end: timeToMinutes(s.endsAt),\n // A grade sem local É uma grade, e no V1 ela se anuncia igual: a\n // faixa aberta leva o nome do local em cima. Cair para o nome\n // padrão em vez de não escrever nada é o que faz a coluna dizer\n // \"aqui abre\" — sem a etiqueta, grade aberta e grade vazia se\n // parecem, e a recepção descobre a diferença clicando.\n locationName:\n (locId && locationMap ? locationMap.get(locId) : undefined) ?? defaultLocationName,\n }\n })\n .sort((a, b) => a.start - b.start)\n\n // Compute unavailable gaps within business hours\n let cursor = bizStartMin\n for (const range of workRanges) {\n const availStart = Math.max(range.start, bizStartMin)\n const availEnd = Math.min(range.end, bizEndMin)\n\n // Gap before this working range = unavailable\n if (cursor < availStart) {\n bgEvents.push({\n resourceId: prof.id,\n start: dateStr + 'T' + minutesToTime(cursor) + ':00',\n end: dateStr + 'T' + minutesToTime(availStart) + ':00',\n display: 'background',\n classNames: ['fc-unavailable-bg'],\n })\n }\n\n // Location label on available range\n if (availStart < availEnd && range.locationName) {\n bgEvents.push({\n id: `loc-${prof.id}-${dateStr}-${minutesToTime(availStart)}`,\n resourceId: prof.id,\n start: dateStr + 'T' + minutesToTime(availStart) + ':00',\n end: dateStr + 'T' + minutesToTime(availStart + 20) + ':00',\n title: range.locationName,\n display: 'auto',\n editable: false,\n backgroundColor: 'transparent',\n borderColor: 'transparent',\n textColor: '#a3a3a3',\n classNames: ['fc-location-label'],\n extendedProps: { isLocationLabel: true },\n })\n }\n\n cursor = Math.max(cursor, availEnd)\n }\n\n // Gap after last working range = unavailable\n if (cursor < bizEndMin) {\n bgEvents.push({\n resourceId: prof.id,\n start: dateStr + 'T' + minutesToTime(cursor) + ':00',\n end: dateStr + 'T' + minutesToTime(bizEndMin) + ':00',\n display: 'background',\n classNames: ['fc-unavailable-bg'],\n })\n }\n\n\n current.setDate(current.getDate() + 1)\n }\n }\n\n return bgEvents\n}\n\n// ---------------------------------------------------------------------------\n// Loading skeleton — mimics the resource-timegrid-week layout\n// ---------------------------------------------------------------------------\n\nfunction CalendarSkeleton({ profCount = 2 }: { profCount?: number }) {\n const days = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT']\n const hours = ['07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00']\n\n return (\n <div className=\"flex-1 overflow-hidden animate-pulse\">\n <div className=\"flex border-b\" style={{ paddingLeft: 56 }}>\n {Array.from({ length: profCount }).map((_, pi) => (\n <div key={pi} className=\"flex-1 border-r last:border-r-0 py-2 px-3\">\n <div className=\"flex items-center justify-center gap-2\">\n <div className=\"h-6 w-6 rounded-full bg-muted\" />\n <div className=\"h-3 w-20 rounded bg-muted\" />\n </div>\n </div>\n ))}\n </div>\n <div className=\"flex border-b\" style={{ paddingLeft: 56 }}>\n {Array.from({ length: profCount }).map((_, pi) => (\n <div key={pi} className=\"flex-1 flex border-r last:border-r-0\">\n {days.map((d) => (\n <div key={d} className=\"flex-1 py-1.5 text-center\">\n <span className=\"text-[10px] text-muted-foreground/40\">{d}</span>\n </div>\n ))}\n </div>\n ))}\n </div>\n <div className=\"relative\">\n {hours.map((h) => (\n <div key={h} className=\"flex border-b border-border/30\" style={{ height: 50 }}>\n <div className=\"w-14 shrink-0 pr-2 text-right\">\n <span className=\"text-[10px] text-muted-foreground/30\">{h}</span>\n </div>\n <div className=\"flex-1 flex\">\n {Array.from({ length: profCount * 7 }).map((_, ci) => (\n <div key={ci} className={`flex-1 border-r border-border/20 ${Math.floor(ci / 7) % 2 === 1 ? 'bg-muted/20' : ''}`} />\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n )\n}\n\n/**\n * O PISO da coluna de um dia numa view de recurso.\n *\n * Piso, não largura: enquanto couber, as colunas encolhem e a grade ocupa a\n * tela inteira como sempre ocupou. O piso só entra quando não cabe mais — e aí\n * a grade para de encolher e o contêiner ROLA.\n *\n * Sem ele o FullCalendar divide a largura disponível pelo número de colunas e\n * aceita qualquer resultado, inclusive 14px: foi o que empilhou \"ADRIANA SILVA\n * MOREIRA\" por cima de \"Adriellen Cristiana Duarte\" na captura do Espaço\n * Facial. `dayMinWidth` faria isto nativamente, mas exige o plugin premium\n * ScrollGrid, que não está instalado — então o piso é imposto por fora, com\n * `min-width` no filho e `overflow-x` no pai.\n *\n * O valor tem que ficar ABAIXO do ponto em que o cabeçalho do dia se compacta\n * sozinho (`dayHeaderCompact`, ~50px: \"SEG. 9/7\" vira \"S 7\"). Com um piso ACIMA\n * dele a coluna nunca chega a apertar, o cabeçalho nunca encolhe, e a grade\n * larga e rolando é o que aparece — foi o que a segunda captura mostrou. Abaixo\n * dele, a coluna encolhe até o cabeçalho curto e só então a rolagem entra.\n */\n/**\n * As linhas que formam UM bloqueio.\n *\n * Um recorrente é uma linha por dia da semana, todas com o mesmo título,\n * horário e vigência (ver `createBlock`). Quem clicou no almoço da quarta quer\n * mexer no ALMOÇO, não recortar a quarta dele — então o diálogo abre o grupo\n * inteiro, e é o grupo que se salva ou se apaga.\n */\nfunction toEditingBlock(clicado: Schedule, todos: Schedule[]): EditingBlock {\n const meta = (clicado.metadata as any)?.agenda ?? {}\n const mesmoGrupo = (s: Schedule) =>\n s.assigneeId === clicado.assigneeId &&\n s.startsAt === clicado.startsAt &&\n s.endsAt === clicado.endsAt &&\n ((s.metadata as any)?.agenda?.title ?? null) === (meta.title ?? null) &&\n (s as any).validFrom === (clicado as any).validFrom &&\n (s as any).validTo === (clicado as any).validTo\n\n const grupo = clicado.specificDate ? [clicado] : todos.filter(mesmoGrupo)\n return {\n ids: grupo.map((s) => s.id),\n assigneeId: clicado.assigneeId ?? '',\n title: meta.title ?? 'Bloqueio',\n description: meta.description ?? '',\n startsAt: clicado.startsAt.slice(0, 5),\n endsAt: clicado.endsAt.slice(0, 5),\n specificDate: clicado.specificDate,\n daysOfWeek: clicado.specificDate\n ? []\n : [...new Set(grupo.map((s) => s.dayOfWeek).filter((d): d is number => d != null))],\n validFrom: (clicado as any).validFrom ?? null,\n validTo: (clicado as any).validTo ?? null,\n weekInterval: (clicado as any).weekInterval ?? 0,\n }\n}\n\nconst MIN_COLUMN_PX = 48\n\n/**\n * O PISO da coluna de UM PROFISSIONAL, quando a data é o grupo de cima.\n *\n * Com `datesAboveResources` a folha da grade deixa de ser um dia e passa a ser\n * uma pessoa: o cabeçalho que precisa caber não é mais \"S 7\" e sim um avatar\n * mais \"Ana B.\". Abaixo disto os nomes se sobrepõem — foi o que pintou\n * \"Andr é T.Bianca Espaço Gabriella\" numa fileira só.\n *\n * Uma semana com seis agendas passa dos quatro mil pixels e ROLA. É o preço do\n * formato: agrupar por dia só significa alguma coisa se o dia couber inteiro no\n * mesmo bloco, e seis pessoas lado a lado não cabem em tela nenhuma.\n */\nconst RESOURCE_COLUMN_MIN_PX = 96\n\n/** Piso da altura da agenda: abaixo disto a grade não é utilizável, e é melhor\n * a página rolar do que a semana virar uma tarja. */\nconst MIN_SHELL_HEIGHT = 360\n\n\n/**\n * O teto de agendas escolhidas À MÃO ao mesmo tempo.\n *\n * Não vale para o padrão. \"Nenhuma escolhida\" quer dizer TODAS, recortadas pelo\n * PERÍODO — quem tem grade aberta ou horário marcado num dia visível —, e esse\n * corte não precisa de número: numa rede com 759 agendáveis a semana desenha as\n * seis pessoas que de fato trabalham nela, e a sétima entra no dia em que abrir\n * grade.\n *\n * Havia aqui um `MAX_DEFAULT_AGENDAS = 6` que marcava seis caixinhas sozinho.\n * Ele resolvia o sintoma errado — quantas pessoas existem, não quantas\n * trabalham — e escolhia pelo alfabeto, que não sabe nada sobre o dia.\n *\n * Aqui o limite é sobre leitura: dez colunas por dia já são setenta numa\n * semana, e rolar além disso não é ler uma agenda, é procurar uma.\n */\nconst MAX_SELECTED_AGENDAS = 10\n\n// Quantos nomes o seletor lista antes de exigir busca. Rolar 739 caixinhas não\n// é uma forma de achar ninguém.\nconst MAX_PICKER_ROWS = 40\n\n\n// Resource views — one column per professional. Used when the app has staff.\nconst RESOURCE_VIEW_OPTIONS = [\n { key: 'resourceTimeGridDay', labelKey: 'agenda.calendar.viewDay' },\n { key: 'resourceTimeGridWeek', labelKey: 'agenda.calendar.viewWeek' },\n { key: 'dayGridMonth', labelKey: 'agenda.calendar.viewMonth' },\n // A QUARTA VISÃO DO V1, que faltava no salão: a lista.\n //\n // A grade responde \"como está o dia\" e exige varrer colunas; a lista responde\n // \"o que acontece, em que ordem\" e se lê de cima para baixo — é a visão de\n // quem confere a véspera, imprime o dia ou procura um nome sem saber a hora.\n // O V1 a chama de \"Agenda\", e é esse o nome aqui: \"Lista\" descreve a forma,\n // \"Agenda\" descreve o que ela mostra.\n //\n // Sem recursos de propósito: uma lista não tem colunas, e o profissional\n // aparece na linha, junto do cliente e do serviço.\n { key: 'listWeek', labelKey: 'agenda.calendar.viewAgenda' },\n] as const\n\n// Non-resource variants — used when there are no professionals/resources (e.g. a\n// personal-finance agenda). A resource timegrid renders an EMPTY grid with zero\n// resource columns and drops events that have no resourceId, so those apps fall\n// back to a plain month/day/week calendar.\nconst PLAIN_VIEW_OPTIONS = [\n { key: 'timeGridDay', labelKey: 'agenda.calendar.viewDay' },\n { key: 'timeGridWeek', labelKey: 'agenda.calendar.viewWeek' },\n { key: 'dayGridMonth', labelKey: 'agenda.calendar.viewMonth' },\n { key: 'listMonth', labelKey: 'agenda.calendar.viewList' },\n] as const\n\n// Sentinel view key for the thumb-friendly mobile agenda list (AgendaMobileList),\n// which is NOT a FullCalendar view. Selected by default on <md so B2C opens on the\n// list; picking any grid option (Dia/Semana/Mês) mounts the real calendar instead.\nconst MOBILE_LIST_VIEW = '__mobileList__'\nconst AGENDA_POLL_INTERVAL_MS = 30_000\nconst AGENDA_REALTIME_DEBOUNCE_MS = 300\n\n/** Collapse a resource view to a plain month calendar when there are no resources. */\nfunction viewForNoResources(view: string): string {\n return view.startsWith('resource') ? 'dayGridMonth' : view\n}\n\n/** Promote a plain timegrid to its resource variant when the app has resources. */\nfunction viewForResources(view: string): string {\n if (view === 'timeGridWeek') return 'resourceTimeGridWeek'\n if (view === 'timeGridDay') return 'resourceTimeGridDay'\n return view\n}\n\n/** Small viewport (<md) → render the thumb-friendly agenda list instead of the grid. */\nfunction useIsMobile(): boolean {\n const [isMobile, setIsMobile] = useState(() =>\n typeof window !== 'undefined' && window.matchMedia('(max-width: 767px)').matches)\n useEffect(() => {\n if (typeof window === 'undefined') return\n const mq = window.matchMedia('(max-width: 767px)')\n const onChange = () => setIsMobile(mq.matches)\n mq.addEventListener('change', onChange)\n return () => mq.removeEventListener('change', onChange)\n }, [])\n return isMobile\n}\n\n// ---------------------------------------------------------------------------\n// Calendar View\n// ---------------------------------------------------------------------------\n\nexport function CalendarView() {\n injectCalendarStyles()\n const config = useAgendaConfig()\n const provider = useAgendaProvider()\n const t = useTranslation()\n const currentLocale = getCurrentLocale()\n const fcLocale = currentLocale === 'pt-BR' ? ptBrLocale : undefined\n const calendarRef = useRef<FullCalendar>(null)\n const prefs = usePluginPrefs('agenda', {\n calendarView: config.defaultCalendarView ?? 'resourceTimeGridDay',\n // Como a SEMANA se agrupa: 'day' põe o dia em cima e as pessoas dentro\n // dele; 'professional' inverte. 'auto' é o padrão e deixa a agenda decidir\n // pelo tamanho da equipe — ver `weekGrouping` mais abaixo.\n weekGrouping: 'auto',\n // Which weekdays the WEEK draws: 'auto', or the shown days (0 = Sunday) — see `shownWeekDays`.\n weekDays: 'auto' as 'auto' | number[],\n })\n /**\n * O EIXO DE CIMA DA SEMANA — o \"Agrupar por: Dia · Profissional\" do V1.\n *\n * Por dia: um bloco por data, as pessoas dentro. É a leitura de quem pergunta\n * \"como está a terça?\" — a terça é um bloco só.\n *\n * Por profissional: um bloco por pessoa, os sete dias dentro. É a leitura de\n * quem pergunta \"como está a semana da Ana?\" — e ela é IMPOSSÍVEL no outro\n * formato, porque a Ana fica espalhada em sete colunas distantes.\n *\n * Vale só na SEMANA: no dia há uma data só, e invertê-la não muda nada.\n */\n const weekGroupingPref = (prefs.get('weekGrouping') as 'auto' | 'day' | 'professional') ?? 'auto'\n const agendaSettings = useAgendaSettings()\n const effectiveBusinessHours = {\n startTime: agendaSettings.startTime,\n endTime: agendaSettings.endTime,\n }\n\n const bookings = useAgendaStore((s) => s.bookings)\n const bookingsLoading = useAgendaStore((s) => s.bookingsLoading)\n const professionals = useAgendaStore((s) => s.professionals)\n const professionalsLoading = useAgendaStore((s) => s.professionalsLoading)\n const professionalsTruncated = useAgendaStore((s) => s.professionalsTruncated)\n const currentView = useAgendaStore((s) => s.currentView)\n const selectedProfIds = useAgendaStore((s) => s.selectedProfessionalIds)\n const selectedStatuses = useAgendaStore((s) => s.selectedStatuses)\n const schedules = useAgendaStore((s) => s.schedules)\n const schedulesLoading = useAgendaStore((s) => s.schedulesLoading)\n const fetchBookings = useAgendaStore((s) => s.fetchBookings)\n const fetchProfessionals = useAgendaStore((s) => s.fetchProfessionals)\n const fetchLocations = useAgendaStore((s) => s.fetchLocations)\n const storeLocations = useAgendaStore((s) => s.locations)\n const selectedLocationId = useAgendaStore((s) => s.selectedLocationId)\n const fetchSchedules = useAgendaStore((s) => s.fetchSchedules)\n const invalidateSchedules = useAgendaStore((s) => s.invalidateSchedules)\n const rescheduleBooking = useAgendaStore((s) => s.rescheduleBooking)\n const setView = useAgendaStore((s) => s.setView)\n const setFilters = useAgendaStore((s) => s.setFilters)\n const _openModal = useAgendaStore((s) => s.openAppointmentModal)\n const closeModal = useAgendaStore((s) => s.closeAppointmentModal)\n const modalState = useAgendaStore((s) => s.appointmentModal)\n\n // Os filtros que o V1 tem na coluna e o V2 não tinha. Moram AQUI e não no\n // store: nenhum deles vai ao servidor — o serviço filtra o que já chegou, e\n // \"ocultar grades vazias\" decide quais colunas desenhar. Pôr no store faria\n // a agenda refazer a consulta para responder uma pergunta que ela já sabe.\n const [serviceFilter, setServiceFilter] = useState<string[]>([])\n const [hideEmptyGrids, setHideEmptyGrids] = useState(false)\n const [schedulesOpen, setSchedulesOpen] = useState(false)\n // O bloqueio tem diálogo PRÓPRIO desde o porte do V1 — ver BlockDialog.\n const [blockFor, setBlockFor] = React.useState<{ professionalId: string | null; date: string | null } | null>(null)\n /** Quem a ficha pediu ao abrir os Horários. */\n const [schedulesFor, setSchedulesFor] = React.useState<string | null>(null)\n /** O bloqueio aberto para editar. */\n const [editingBlock, setEditingBlock] = React.useState<EditingBlock | null>(null)\n\n // Resource-capable = the app has professionals/staff. When it doesn't (e.g. a\n // personal-finance agenda), resource views render empty, so we force plain\n // (non-resource) views and default to a month calendar.\n const isMobile = useIsMobile()\n const resourceCapable = professionals.length > 0\n const viewOptions = resourceCapable ? RESOURCE_VIEW_OPTIONS : PLAIN_VIEW_OPTIONS\n\n // Mobile (<md) has its own view selection, independent of the desktop pref: it\n // defaults to the thumb-friendly list and lets the user switch to any grid view\n // (Dia/Semana/Mês) without changing the desktop's stored calendarView. The list\n // sentinel replaces FullCalendar's own listMonth so mobile always gets the rich\n // AgendaMobileList, and a list option is offered even for resource apps.\n // ── A altura da agenda é MEDIDA, não calculada ──────────────────────────\n //\n // Era `h-[calc(100vh-7.5rem)]`, e o 7.5rem era um palpite sobre onde a tela\n // começa. Na casca real ela começa a 126px, não 120 — e o contêiner de página\n // ainda soma 24px de `padding-bottom`. Trinta pixels a mais do que cabe: o\n // suficiente para a página ganhar rolagem e mostrar uma faixa branca embaixo\n // do calendário, que é exatamente o defeito que isto conserta.\n //\n // Um número mágico sobre a altura de um cabeçalho que ele não controla é uma\n // aposta que se perde em toda mudança de casca, de zoom ou de densidade. Medir\n // a própria posição responde certo em todas elas.\n const shellRef = useRef<HTMLDivElement>(null)\n const [shellHeight, setShellHeight] = useState<number | undefined>(undefined)\n useLayoutEffect(() => {\n const measure = () => {\n const el = shellRef.current\n if (!el) return\n const top = el.getBoundingClientRect().top\n // O respiro que o contêiner de página reserva embaixo (`pb-6`). Lido do\n // pai em vez de fixado aqui, pelo mesmo motivo que a altura é medida.\n const parent = el.parentElement\n const pad = parent ? parseFloat(getComputedStyle(parent).paddingBottom) || 0 : 0\n setShellHeight(Math.max(MIN_SHELL_HEIGHT, window.innerHeight - top - pad))\n }\n measure()\n window.addEventListener('resize', measure)\n // A casca muda de altura sem a janela mudar — barra de aviso, banner de\n // plano, o menu mobile abrindo. O observer pega o que o resize não pega.\n const ro = new ResizeObserver(measure)\n if (document.body) ro.observe(document.body)\n return () => { window.removeEventListener('resize', measure); ro.disconnect() }\n }, [])\n\n const [mobileView, setMobileView] = useState<string>(MOBILE_LIST_VIEW)\n const mobileViewOptions = useMemo(\n () => [\n ...viewOptions.filter((o) => o.key !== 'listMonth'),\n { key: MOBILE_LIST_VIEW, labelKey: 'agenda.calendar.viewList' },\n ],\n [viewOptions],\n )\n const mobileGridActive = isMobile && mobileView !== MOBILE_LIST_VIEW\n\n const [selectedBooking, setSelectedBooking] = useState<CalendarBooking | null>(null)\n const [popoverAnchor, setPopoverAnchor] = useState<{ x: number; y: number } | null>(null)\n const [popoverVisible, _setPopoverVisible] = useState(false)\n const popoverVisibleRef = useRef(false)\n const setPopoverVisible = useCallback((v: boolean) => { popoverVisibleRef.current = v; _setPopoverVisible(v) }, [])\n const [contextMenu, setContextMenu] = useState<{ booking: CalendarBooking; x: number; y: number } | null>(null)\n const [contextMenuVisible, _setContextMenuVisible] = useState(false)\n const contextMenuVisibleRef = useRef(false)\n const setContextMenuVisible = useCallback((v: boolean) => { contextMenuVisibleRef.current = v; _setContextMenuVisible(v) }, [])\n const [scheduleConfirm, setScheduleConfirm] = useState<{ onConfirm: () => void } | null>(null)\n const [calendarTitle, setCalendarTitle] = useState('')\n const [selectedDate, setSelectedDate] = useState(new Date())\n const [visibleRange, setVisibleRange] = useState<{ start: string; end: string } | null>(null)\n\n // Leaving the calendar ends the booking form with it. The open flag lives in\n // the store, which outlives this screen — without this, navigating away with\n // a half-filled form and coming back reopened it, days later, still holding\n // the slot you abandoned.\n useEffect(() => () => closeModal(), [closeModal])\n\n // Wrap openModal to always dismiss popover/context menu first\n const openModal: typeof _openModal = useCallback((...args) => {\n setPopoverVisible(false); setSelectedBooking(null); setPopoverAnchor(null)\n setContextMenuVisible(false); setContextMenu(null)\n _openModal(...args)\n }, [_openModal])\n\n const statusColors = useMemo(() => {\n const map: Record<string, string> = {}\n for (const s of config.statuses) map[s.value] = s.color\n return map\n }, [config.statuses])\n\n // A unidade em que a tela está muda QUEM tem agenda. Sem isto o seletor\n // continuaria mostrando o quadro da unidade anterior depois da troca.\n const activeUnitId = useActiveUnitId()\n const [nextProfessionalId, setNextProfessionalId] = useState(() => getTurnQueueLeader(activeUnitId))\n\n useEffect(() => {\n setNextProfessionalId(getTurnQueueLeader(activeUnitId))\n return subscribeTurnQueueLeader((unitId, professionalId) => {\n if (unitId === activeUnitId) setNextProfessionalId(professionalId)\n })\n }, [activeUnitId])\n\n useEffect(() => {\n fetchProfessionals()\n if (config.modules.locationSelection) fetchLocations()\n }, [activeUnitId])\n\n // AS GRADES DO PERÍODO, não as da conta.\n //\n // `fetchSchedules()` sem recorte lia as 1331 linhas do salão migrado a cada\n // montagem — para desenhar sete dias. Pior que o custo: elas chegavam\n // DEPOIS das colunas, e a grade se redesenhava de oito agendas para duas\n // vinte segundos adiante, com quem estava lendo no meio.\n const schedulesKey = useAgendaStore((s) => s.schedulesKey)\n const agendaProfessionalsKey = useAgendaStore((s) => s.agendaProfessionalsKey)\n\n const scheduleQuery = useMemo(() => {\n if (!visibleRange) return null\n const days = new Set<number>()\n const cursor = new Date(visibleRange.start)\n const end = new Date(visibleRange.end)\n // In the WEEK, ask for the whole week even when some days are hidden: what\n // decides whether Saturday and Sunday are drawn is whether anyone works\n // them, and a range that already left them out could never answer that.\n if (currentView.endsWith('Week')) {\n cursor.setDate(cursor.getDate() - cursor.getDay())\n end.setTime(cursor.getTime())\n end.setDate(end.getDate() + 7)\n return {\n daysOfWeek: [0, 1, 2, 3, 4, 5, 6],\n from: localDateKey(cursor),\n to: localDateKey(end),\n }\n }\n for (let i = 0; cursor < end && i < 62; i++) {\n days.add(cursor.getDay())\n cursor.setDate(cursor.getDate() + 1)\n }\n return {\n daysOfWeek: [...days],\n from: visibleRange.start.slice(0, 10),\n to: visibleRange.end.slice(0, 10),\n }\n }, [visibleRange, currentView])\n\n const wantedSchedulesKey = useMemo(\n () => (scheduleQuery ? 'agenda:schedules:' + JSON.stringify(scheduleQuery) : null),\n [scheduleQuery],\n )\n\n // PEDE ATÉ BATER, em vez de pedir uma vez e torcer.\n //\n // O calendário dispara `datesSet` mais de uma vez na abertura — a visão\n // guardada nas preferências desenha um mês antes de a tela virar dia —, e os\n // dois pedidos chegavam fora de ordem: o do mês respondia por último e\n // carimbava a memória com o recorte errado. A tela ficava esperando um\n // recorte que ninguém mais ia pedir, e a grade não desenhava nunca.\n //\n // Comparar o que se tem com o que se quer a cada rodada desfaz qualquer\n // ordem de chegada. `dedup` segura a repetição enquanto a resposta não vem.\n useEffect(() => {\n if (!scheduleQuery) return\n if (schedulesKey === wantedSchedulesKey) return\n void fetchSchedules(scheduleQuery)\n }, [scheduleQuery, wantedSchedulesKey, schedulesKey, activeUnitId, fetchSchedules])\n\n // Os BLOQUEIOS do mesmo período. Consulta à parte porque a pergunta é outra:\n // a grade diz quando ABRE, o bloqueio diz quando FECHA.\n const blocks = useAgendaStore((s) => s.blocks)\n const fetchBlocks = useAgendaStore((s) => s.fetchBlocks)\n useEffect(() => {\n if (!visibleRange) return\n void fetchBlocks({ from: visibleRange.start.slice(0, 10), to: visibleRange.end.slice(0, 10) })\n }, [visibleRange, activeUnitId, fetchBlocks])\n\n // ── O CALENDÁRIO DA CASA ───────────────────────────────────────────────\n //\n // O feriado estava no banco desde sempre — 179 linhas só no Espaço Facial —\n // e não chegava a tela nenhuma: a tabela existia, a RPC existia, e nenhuma\n // linha de TypeScript as chamava. A agenda desenhava o 7 de setembro como\n // uma terça qualquer.\n //\n // O que desenha é o que FECHA (`closes`). A data comemorativa entra como\n // legenda — o V1 a guarda no mesmo lugar, mas ela é assunto de campanha, e\n // pintar o Dia do Sorvete de vermelho ensinaria a ignorar o vermelho.\n const [holidays, setHolidays] = useState<AgendaHoliday[]>([])\n const holidayRangeKey = visibleRange ? `${visibleRange.start.slice(0, 10)}|${visibleRange.end.slice(0, 10)}` : null\n useEffect(() => {\n if (!visibleRange || !provider.getHolidays) { setHolidays([]); return }\n let cancelado = false\n provider.getHolidays({ from: visibleRange.start.slice(0, 10), to: visibleRange.end.slice(0, 10) }, activeUnitId)\n .then((rows) => { if (!cancelado) setHolidays(rows) })\n // Um calendário que não carregou não vira erro em cima de quem só queria\n // ver a agenda.\n .catch(() => { if (!cancelado) setHolidays([]) })\n return () => { cancelado = true }\n }, [holidayRangeKey, activeUnitId, provider])\n\n /** Por dia: o que fecha manda no dia, e os nomes entram na ordem em que vieram. */\n const holidayByDate = useMemo(() => {\n const map = new Map<string, { closes: boolean; names: string[] }>()\n for (const h of holidays) {\n const atual = map.get(h.date)\n if (atual) {\n atual.closes = atual.closes || h.closes\n if (!atual.names.includes(h.name)) atual.names.push(h.name)\n } else {\n map.set(h.date, { closes: h.closes, names: [h.name] })\n }\n }\n return map\n }, [holidays])\n\n // ── O padrão deixa de ser \"todas\" quando \"todas\" são muitas ──────────────\n //\n // Lista vazia sempre significou \"todas\", e numa clínica de seis agendas isso\n // é a resposta certa. Com 739 é uma semana com 739 colunas: a tela congela\n // antes de desenhar a primeira, e não há como escapar porque o seletor está\n // dentro dela.\n //\n // A saída não é recortar em silêncio — seria uma tela dizendo \"todas\" e\n // mostrando doze. É ESCOLHER por padrão: a seleção vira explícita, as doze\n // aparecem marcadas, as outras desmarcadas, e mudar isso é a mesma caixinha\n // de sempre. Só na primeira carga; depois disso quem manda é a pessoa.\n //\n // E ESCOLHER QUEM TEM GRADE ABERTA, não quem vem primeiro no alfabeto.\n //\n // A ordem da lista é o nome da pessoa, e o nome não diz nada sobre o dia: a\n // agenda abria em seis colunas em branco enquanto quem atendia naquela manhã\n // ficava fora da tela. Grade aberta é a única coisa que responde \"esta coluna\n // tem alguma chance de ter algo nela\" — é o mesmo critério do V1, onde o\n // seletor de Profissionais só lista quem tem grade na unidade.\n //\n // Quem não tem grade não some do seletor: continua lá, marcado como \"sem\n // grade\", porque não ter grade é um problema de configuração que a recepção\n // precisa ENXERGAR — e é a causa nº 1 de \"abri a agenda e não aparece nada\".\n const scheduledProfIds = useMemo(\n () => new Set(schedules.filter((sch) => sch.isActive !== false)\n .map((sch) => sch.assigneeId).filter(Boolean) as string[]),\n [schedules],\n )\n\n /**\n * A grade de cada pessoa, indexada para a pergunta que a tela faz: \"esta\n * pessoa abre NESTE dia?\".\n *\n * Uma exceção de data SUBSTITUI a semana naquele dia — é a folga, o feriado,\n * o plantão extra. Sem isso, quem tirou a sexta continuava com coluna na\n * sexta, e quem foi escalado num domingo não tinha.\n */\n const scheduleIndex = useMemo(() => {\n const byProf = new Map<string, Schedule[]>()\n for (const sch of schedules) {\n if (!sch.assigneeId) continue\n // A INATIVA ENTRA. Uma exceção de data inativa é a FOLGA, e é ela que\n // apaga a semana naquele dia — filtrá-la aqui devolvia a grade padrão\n // justamente no dia em que a pessoa não vem. Quem decide o que é janela\n // é o motor, que conhece a diferença entre \"não existe\" e \"existe\n // fechado\".\n const list = byProf.get(sch.assigneeId) ?? []\n list.push(sch)\n byProf.set(sch.assigneeId, list)\n }\n return byProf\n }, [schedules])\n\n /** Os dias que a tela mostra agora — o eixo de toda a regra abaixo. */\n const visibleDates = useMemo(() => {\n if (!visibleRange) return [] as Array<{ iso: string; dow: number }>\n const out: Array<{ iso: string; dow: number }> = []\n const cursor = new Date(visibleRange.start)\n const end = new Date(visibleRange.end)\n // Teto de segurança: a visão de mês já é 42 dias, e um intervalo torto não\n // pode virar laço infinito.\n for (let i = 0; cursor < end && i < 62; i++) {\n out.push({ iso: localDateKey(cursor), dow: cursor.getDay() })\n cursor.setDate(cursor.getDate() + 1)\n }\n return out\n }, [visibleRange])\n\n const opensOn = useCallback((profId: string, iso: string, _dow: number) => {\n const rows = scheduleIndex.get(profId)\n return !!rows && opensOnDate(rows, iso)\n }, [scheduleIndex])\n\n /**\n * THE DAYS THE WEEK DRAWS. A house closed at the weekend pays two sevenths\n * of the grid for columns that are always grey. On 'auto' Saturday and\n * Sunday drop out when no schedule opens on them; Monday to Friday always\n * stay — a midweek day off is something to see, not to hide. A list is the\n * person choosing, and it wins.\n *\n * Measured on the days OF THE WEEK ON SCREEN, not on the visible range: a\n * hidden day is not in the range, and a rule that read it there could never\n * bring it back. With no schedule at all the week stays whole — \"nothing is\n * configured\" must not look like \"closed at the weekend\".\n */\n const weekDaysPref = prefs.get('weekDays') as 'auto' | number[]\n const lastAutoWeekDays = useRef('0123456')\n // As a STRING first: the calendar reports a new range every time its hidden\n // days change, and a fresh array each time would feed that straight back in.\n const shownWeekDaysKey = useMemo<string>(() => {\n const all = [0, 1, 2, 3, 4, 5, 6]\n if (Array.isArray(weekDaysPref)) {\n const chosen = all.filter((d) => weekDaysPref.includes(d))\n return (chosen.length > 0 ? chosen : all).join('')\n }\n // Only a WEEK's schedules cover all seven days, and only once they have\n // arrived for this very week. Anything else keeps the last answer — a day\n // view knows one weekday, and deciding from it would drop the rest.\n const settled = currentView.endsWith('Week') && !schedulesLoading && schedulesKey === wantedSchedulesKey\n if (!settled) return lastAutoWeekDays.current\n if (!visibleRange || scheduleIndex.size === 0) return (lastAutoWeekDays.current = all.join(''))\n const sunday = new Date(visibleRange.start)\n // The range may already start on Monday; the week's Sunday is the day before it.\n sunday.setDate(sunday.getDate() - sunday.getDay())\n const works = (dow: number) => {\n const day = new Date(sunday)\n day.setDate(day.getDate() + dow)\n const iso = localDateKey(day)\n for (const [profId] of scheduleIndex) if (opensOn(profId, iso, dow)) return true\n return false\n }\n return (lastAutoWeekDays.current = all.filter((d) => (d !== 0 && d !== 6) || works(d)).join(''))\n }, [weekDaysPref, visibleRange, scheduleIndex, opensOn, currentView, schedulesLoading, schedulesKey, wantedSchedulesKey])\n const shownWeekDays = useMemo(() => shownWeekDaysKey.split('').map(Number), [shownWeekDaysKey])\n const weekViewOptions = useMemo(() => {\n const hiddenDays = [0, 1, 2, 3, 4, 5, 6].filter((d) => !shownWeekDays.includes(d))\n // Per view, never global: a hidden day in the DAY view makes the calendar\n // skip to the next one when someone opens it.\n return { resourceTimeGridWeek: { hiddenDays }, timeGridWeek: { hiddenDays } }\n }, [shownWeekDays])\n const toggleWeekDay = useCallback((dow: number) => {\n const next = shownWeekDays.includes(dow) ? shownWeekDays.filter((d) => d !== dow) : [...shownWeekDays, dow].sort()\n // A week with no days is not a week.\n if (next.length > 0) prefs.set('weekDays', next)\n }, [shownWeekDays, prefs])\n\n /**\n * QUEM APARECE — a regra do V1, medida no código dele\n * (AdvancedCalendar.baseDisplayedProfessionals):\n *\n * nenhum filtro marcado = TODOS,\n * e então só quem tem GRADE ou HORÁRIO MARCADO num dia visível.\n *\n * Não há teto, e não precisa haver: o corte não é um número, é o período.\n * Uma rede com 759 agendáveis desenha as seis pessoas que trabalham nesta\n * semana, e no dia em que a sétima abrir grade ela entra sozinha — o que\n * \"as seis primeiras em ordem alfabética\" nunca ia fazer.\n *\n * O horário marcado entra junto com a grade porque um agendamento herdado —\n * de alguém que já não tem grade — continua sendo trabalho de alguém naquele\n * dia. Escondê-lo seria apagar o compromisso, não a coluna.\n */\n const relevantProfIds = useMemo(() => {\n const ids = new Set<string>()\n for (const [profId] of scheduleIndex) {\n if (visibleDates.some((d) => opensOn(profId, d.iso, d.dow))) ids.add(profId)\n }\n for (const booking of bookings) {\n if (booking.professionalId) ids.add(booking.professionalId)\n }\n return [...ids]\n }, [scheduleIndex, visibleDates, opensOn, bookings])\n\n const relevantSet = useMemo(() => new Set(relevantProfIds), [relevantProfIds])\n\n const fetchAgendaProfessionals = useAgendaStore((s) => s.fetchAgendaProfessionals)\n const agendaProfessionals = useAgendaStore((s) => s.agendaProfessionals)\n useEffect(() => {\n void fetchAgendaProfessionals(relevantProfIds)\n }, [relevantProfIds, fetchAgendaProfessionals])\n\n /** O seletor: quem trabalha no período primeiro, o resto do quadro depois. */\n const pickerProfessionals = useMemo(() => {\n const byId = new Map<string, Professional>()\n for (const p of agendaProfessionals) byId.set(p.id, p)\n for (const p of professionals) if (!byId.has(p.id)) byId.set(p.id, p)\n const all = [...byId.values()].sort((a, b) => a.name.localeCompare(b.name))\n return [...all.filter((p) => relevantSet.has(p.id)), ...all.filter((p) => !relevantSet.has(p.id))]\n }, [agendaProfessionals, professionals, relevantSet])\n\n\n // SEM semeadura. O filtro de Profissionais nasce VAZIO, e vazio quer dizer\n // \"todas\" — a mesma regra que Status e Serviço já seguem, e a mesma do V1.\n //\n // Havia aqui um efeito que marcava seis caixinhas sozinho, para não desenhar\n // 759 colunas. Ele resolvia o sintoma errado: o problema nunca foi quantas\n // pessoas existem, foi quantas TRABALHAM nesta semana. Com o período como\n // corte, a conta de franquia desenha as seis que abriram grade — e a sétima\n // aparece no dia em que abrir, em vez de depender de onde o nome dela cai no\n // alfabeto. Marcar por conta própria também mentia sobre a escolha: as\n // caixinhas diziam que alguém tinha escolhido aquilo.\n\n // A troca de unidade recomeça a conversa: o quadro é outro, e uma seleção\n // feita sobre o anterior não descreve mais nada.\n useEffect(() => { if (selectedProfIds.length) setFilters({ professionalIds: [] }) }, [activeUnitId])\n\n // Busca do seletor. Filtra o que está em memória; quando o servidor cortou no\n // teto (`professionalsTruncated`), quem não veio também precisa ser\n // encontrável, então a busca vai ao banco.\n const [profSearch, setProfSearch] = useState('')\n useEffect(() => {\n if (!professionalsTruncated) return\n const term = profSearch.trim()\n const timer = setTimeout(() => { void fetchProfessionals(term ? { search: term } : undefined) }, 250)\n return () => clearTimeout(timer)\n }, [profSearch, professionalsTruncated])\n\n // Keep the view consistent with resource-capability, in case a stale/shared\n // pref selected the wrong variant. No resources → a resource view is an empty\n // grid that drops the seeded events; resources → a plain timegrid loses the\n // per-professional columns.\n useEffect(() => {\n const api = calendarRef.current?.getApi()\n if (!api) return\n if (!resourceCapable && currentView.startsWith('resource')) {\n api.changeView('dayGridMonth')\n } else if (resourceCapable && (currentView === 'timeGridWeek' || currentView === 'timeGridDay')) {\n api.changeView(viewForResources(currentView))\n }\n }, [resourceCapable, currentView])\n\n // Mobile renders the agenda list (no FullCalendar), so the grid's datesSet —\n // which normally drives fetchBookings — never fires. Fetch a wide upcoming\n // window directly so the list has data.\n useEffect(() => {\n if (!isMobile) return\n const start = new Date(); start.setHours(0, 0, 0, 0); start.setDate(start.getDate() - 1)\n const end = new Date(start); end.setDate(end.getDate() + 91)\n fetchBookings({ start: start.toISOString(), end: end.toISOString() })\n }, [isMobile, fetchBookings])\n\n // A booking created outside the grid — the assistant, the public page,\n // another device — repaints the calendar it belongs to. Without this the\n // manager who just said \"agenda a Maria amanhã às 10\" still sees yesterday's\n // grid and reloads the tab by hand.\n const refreshVisibleBookings = useCallback(() => {\n if (visibleRange) {\n void fetchBookings(visibleRange)\n return\n }\n const start = new Date(); start.setHours(0, 0, 0, 0); start.setDate(start.getDate() - 1)\n const end = new Date(start); end.setDate(end.getDate() + 91)\n void fetchBookings({ start: start.toISOString(), end: end.toISOString() })\n }, [visibleRange, fetchBookings])\n\n useDataChanged({}, refreshVisibleBookings, [refreshVisibleBookings])\n\n // Writes this tab never saw — a Google webhook, another device, the public\n // booking page — arrive through the provider's realtime subscription. The\n // 30s visibility-aware poll is the net for a sleeping/disconnected socket;\n // a hidden tab does no database work, and returning to it refreshes at once.\n useEffect(() => {\n if (typeof window === 'undefined' || typeof document === 'undefined') return\n\n let refreshTimer: ReturnType<typeof setTimeout> | undefined\n let unsubscribe: (() => void) | undefined\n\n const scheduleRefresh = (delay = 0) => {\n if (document.visibilityState === 'hidden') return\n if (refreshTimer) clearTimeout(refreshTimer)\n refreshTimer = setTimeout(refreshVisibleBookings, delay)\n }\n\n try {\n unsubscribe = provider.subscribeToBookingChanges?.(() => scheduleRefresh(AGENDA_REALTIME_DEBOUNCE_MS))\n } catch (error) {\n console.warn('[agenda] Realtime unavailable; using the polling fallback.', error)\n }\n\n const pollTimer = window.setInterval(() => scheduleRefresh(), AGENDA_POLL_INTERVAL_MS)\n const onVisibilityChange = () => { if (document.visibilityState === 'visible') scheduleRefresh() }\n const onFocus = () => scheduleRefresh()\n\n document.addEventListener('visibilitychange', onVisibilityChange)\n window.addEventListener('focus', onFocus)\n\n return () => {\n if (refreshTimer) clearTimeout(refreshTimer)\n window.clearInterval(pollTimer)\n document.removeEventListener('visibilitychange', onVisibilityChange)\n window.removeEventListener('focus', onFocus)\n unsubscribe?.()\n }\n }, [provider, refreshVisibleBookings])\n\n // Os serviços QUE ESTÃO NA TELA, não o catálogo inteiro.\n //\n // O filtro do V1 lista o catálogo; aqui ele lista o que o período carregou.\n // É deliberado: oferecer um serviço que ninguém agendou nesta semana é\n // oferecer um clique que só pode esvaziar a grade, e a recepção lê grade\n // vazia como defeito antes de ler como filtro.\n // O filtro lista o CATÁLOGO, não o que por acaso está marcado na semana.\n //\n // Derivar as opções das reservas carregadas tinha uma consequência que só\n // aparece na semana errada: numa semana vazia — ou numa casa que acabou de\n // migrar e ainda não marcou nada — o filtro nascia sem uma linha, e quem o\n // abria concluía que o salão não tem serviço cadastrado. Um filtro só é\n // honesto se ele mostra o que dá para escolher.\n //\n // `serviceLookup` é a MESMA fonte que o formulário de agendamento usa, então\n // o nome que se filtra e o nome que se marca não têm como divergir.\n const [catalogServices, setCatalogServices] = useState<Array<{ value: string; label: string }>>([])\n useEffect(() => {\n const lookup = config.serviceLookup\n if (!lookup?.list) { setCatalogServices([]); return }\n let alive = true\n void lookup.list().then((rows) => {\n if (!alive) return\n setCatalogServices(rows.map((r) => ({ value: r.id, label: r.label })))\n }).catch(() => { if (alive) setCatalogServices([]) })\n return () => { alive = false }\n }, [config.serviceLookup])\n\n const serviceOptions = useMemo(() => {\n const map = new Map<string, string>()\n for (const option of catalogServices) map.set(option.value, option.label)\n // O que está na tela entra mesmo que o catálogo não o devolva (um serviço\n // desativado depois de marcado continua marcado, e sumir do filtro\n // esconderia o agendamento dele).\n for (const booking of bookings) {\n for (const service of booking.services ?? []) {\n if (service.serviceId) map.set(service.serviceId, service.name)\n }\n }\n return [...map].map(([value, label]) => ({ value, label }))\n .sort((a, b) => a.label.localeCompare(b.label))\n }, [catalogServices, bookings])\n\n // Vazio é TODOS — a mesma regra que o rail já usa para agendas e status, e a\n // que o próprio `MultiSelect` documenta.\n const filteredBookings = useMemo(() => {\n if (serviceFilter.length === 0) return bookings\n const wanted = new Set(serviceFilter)\n return bookings.filter((b) => (b.services ?? []).some((sv) => sv.serviceId && wanted.has(sv.serviceId)))\n }, [bookings, serviceFilter])\n\n const drawnProfessionals = useMemo(() => {\n const byName = (a: Professional, b: Professional) => a.name.localeCompare(b.name)\n\n // SEM FILTRO, A GRADE VEM DE UMA FONTE SÓ: `agendaProfessionals`, que é a\n // resposta do servidor à pergunta \"destes ids, quem atende aqui?\".\n //\n // Antes ela somava a lista do SELETOR, que é outra coisa: um recorte do\n // quadro, cortado no teto e refeito a cada busca — e refeito também pelo\n // poll de configuração, que a cada trinta segundos a devolvia diferente.\n // Duas colunas desapareciam cinquenta segundos depois de a tela abrir,\n // porque elas só estavam ali por estarem naquela lista.\n //\n // Uma pergunta, uma resposta, uma grade.\n if (selectedProfIds.length === 0) {\n const period = [...agendaProfessionals].filter((p) => relevantSet.has(p.id)).sort(byName)\n if (!hideEmptyGrids) return period\n const busyNow = new Set(filteredBookings.map((b) => b.professionalId).filter(Boolean) as string[])\n return period.filter((p) => busyNow.has(p.id))\n }\n\n // Escolha à mão: aí sim as duas listas se somam. Conferir a agenda de quem\n // está de férias é legítimo, e essa pessoa não está entre as do período.\n const byId = new Map<string, Professional>()\n for (const p of agendaProfessionals) byId.set(p.id, p)\n for (const p of professionals) if (!byId.has(p.id)) byId.set(p.id, p)\n const picked = [...byId.values()].filter((p) => selectedProfIds.includes(p.id)).sort(byName)\n\n if (!hideEmptyGrids) return picked\n // \"Ocultar grades vazias\" é mais estrito: sem CLIENTE no período, a coluna\n // sai. Uma grade aberta e vazia é informação — é onde cabe encaixar\n // alguém —, e por isso ela só some quando pedem.\n const busy = new Set(filteredBookings.map((b) => b.professionalId).filter(Boolean) as string[])\n return picked.filter((p) => busy.has(p.id))\n }, [agendaProfessionals, professionals, selectedProfIds, relevantSet, hideEmptyGrids, filteredBookings])\n\n /**\n * As colunas já são as definitivas?\n *\n * Duas perguntas têm de ter voltado: as GRADES (que dizem quem trabalha no\n * período) e as PESSOAS daquelas grades. Enquanto uma das duas está no ar, o\n * conjunto ainda pode encolher — e encolher na cara de quem lê é pior do que\n * demorar.\n *\n * Um filtro escolhido à mão dispensa a espera: ali quem decidiu foi a pessoa,\n * e a lista não vai mudar sozinha.\n */\n const columnsSettled = useMemo(() => {\n // Escolha à mão dispensa espera: quem decidiu foi a pessoa, e a lista não\n // muda sozinha.\n if (selectedProfIds.length > 0) return true\n // As grades em memória descrevem ESTE período? `schedulesLoading` não\n // responde isso: ele nasce `false` porque o pedido só sai depois do\n // primeiro desenho, e na primeira pintura \"não está carregando\" e \"já\n // carregou\" são a mesma coisa. Era esse buraco que deixava oito colunas\n // aparecerem por cinco segundos.\n if (!scheduleQuery) return false\n if (schedulesKey !== wantedSchedulesKey) return false\n // E as pessoas dessas grades já foram BUSCADAS? A pergunta é sobre o\n // pedido, não sobre o resultado: alguém com grade pode não voltar — saiu\n // da agenda, mudou de unidade —, e exigir que TODO id apareça deixaria a\n // grade em esqueleto para sempre por causa de um cadastro desatualizado.\n return agendaProfessionalsKey === 'agenda:columns:' + [...relevantProfIds].sort().join(',')\n }, [selectedProfIds, scheduleQuery, schedulesKey, wantedSchedulesKey, agendaProfessionalsKey, relevantProfIds])\n\n\n /**\n * O período inteiro está sem grade?\n *\n * Só depois de `columnsSettled`: antes disso \"nenhuma grade\" e \"as grades\n * ainda não chegaram\" são indistinguíveis, e mostrar o aviso na primeira\n * pintura o faria piscar em toda abertura de tela.\n */\n const semGradeNoPeriodo = useMemo(() => {\n if (!columnsSettled || schedulesLoading || visibleDates.length === 0) return false\n // Medido NO PERÍODO, não no total: o salão migrado tem 1331 grades, e\n // nenhuma delas vale em fevereiro de 2025. \"Tem grade cadastrada\" e \"tem\n // grade nesta semana\" são perguntas diferentes, e é a segunda que decide\n // se a tela tem o que desenhar.\n for (const [profId] of scheduleIndex) {\n if (visibleDates.some((d) => opensOn(profId, d.iso, d.dow))) return false\n }\n return true\n }, [columnsSettled, schedulesLoading, visibleDates, scheduleIndex, opensOn])\n\n const resources = useMemo(() => drawnProfessionals.map((p) => ({\n id: p.id, title: p.name,\n // Sem `locationName`: ele SEMPRE foi nulo (o mapeador nunca o preencheu),\n // então a segunda linha do cabeçalho da coluna nunca desenhou. E agora que\n // a pessoa pode atender em VÁRIAS unidades não há um nome para pôr ali —\n // além de a grade já estar recortada por uma unidade, o que faria o\n // subtítulo repetir a mesma palavra em toda coluna.\n extendedProps: { avatarUrl: p.avatarUrl },\n })), [drawnProfessionals])\n\n const visibleResourceIds = useMemo(() => resources.map((resource) => resource.id), [resources])\n\n // SOZINHO NA AGENDA, a semana se lê por PESSOA.\n //\n // Agrupar por dia com um profissional só desenha sete blocos de uma coluna\n // cada, com o mesmo nome repetido sete vezes no cabeçalho — o eixo de cima\n // não separa nada, e a semana da pessoa, que é a única pergunta que sobra,\n // fica partida em sete pedaços distantes. Por profissional vira um bloco com\n // os sete dias dentro, que é a semana como ela se lê.\n //\n // Padrão, não imposição: `'auto'` só vale enquanto ninguém escolheu. Tocar no\n // controle grava 'day' ou 'professional' e a escolha manda, inclusive numa\n // casa de uma pessoa só.\n const weekGrouping: 'day' | 'professional' = weekGroupingPref === 'auto'\n ? (resources.length <= 1 ? 'professional' : 'day')\n : weekGroupingPref\n\n // A largura ABAIXO da qual a grade para de encolher. Acima dela o `min-width`\n // não faz nada e o layout é o de sempre — é só quando a tela aperta que ele\n // segura o piso e a rolagem aparece.\n //\n // `undefined` fora das views de recurso: lá as colunas são os sete dias e\n // sete sempre couberam, e um piso à toa só criaria rolagem sem motivo.\n const gridMinWidth = useMemo(() => {\n if (!currentView.startsWith('resource')) return undefined\n const daysInView = currentView.endsWith('Day') ? 1 : 7\n const columns = Math.max(1, resources.length) * daysInView\n // Quem é a FOLHA decide o piso. Agrupado por dia, a folha é a pessoa e o\n // que precisa caber é \"Ana B.\" com retrato; agrupado por profissional, a\n // folha é o dia e \"S 7\" cabe em bem menos.\n const folhaEPessoa = currentView.endsWith('Day') || weekGrouping === 'day'\n const floor = folhaEPessoa ? Math.max(MIN_COLUMN_PX, RESOURCE_COLUMN_MIN_PX) : MIN_COLUMN_PX\n // Mais a régua de horas à esquerda, que não é coluna de dia mas ocupa.\n return columns * floor + 64\n }, [currentView, resources.length, weekGrouping])\n\n /**\n * OS BLOQUEIOS NA GRADE.\n *\n * Até aqui um bloqueio salvo não desenhava em lugar nenhum: ele subtraía o\n * horário da oferta e sumia. A recepção bloqueava o almoço, olhava a coluna,\n * via o espaço branco de sempre e marcava alguém em cima — o único jeito de\n * descobrir era o horário não aparecer na hora de agendar.\n *\n * As três regras de quando um bloqueio vale num dia são as MESMAS que\n * `agenda_busy_blocks` usa no banco (migration 010), e por isso estão\n * escritas aqui na mesma ordem:\n *\n * ocorrência única `specific_date` bate com o dia\n * faixa sem weekday vigência cobre o dia, e ele vale o dia inteiro\n * recorrente por weekday mesmo dia da semana, vigência cobre, e a\n * PARIDADE bate (\"semana sim, semana não\")\n */\n const blockEvents = useMemo(() => {\n if (!visibleRange || blocks.length === 0) return [] as any[]\n const out: any[] = []\n const semanasEntre = (de: string, ate: string) =>\n Math.floor((new Date(ate + 'T00:00:00').getTime() - new Date(de + 'T00:00:00').getTime()) / 604800000)\n\n for (const b of blocks) {\n if (!b.assigneeId) continue\n const titulo = ((b.metadata as any)?.agenda?.title as string | undefined) ?? 'Bloqueio'\n for (const { iso, dow } of visibleDates) {\n const dentroDaVigencia =\n (!(b as any).validFrom || (b as any).validFrom <= iso) &&\n (!(b as any).validTo || iso <= (b as any).validTo)\n let vale = false\n if (b.specificDate) vale = b.specificDate === iso\n else if (b.dayOfWeek == null) vale = dentroDaVigencia\n else if (b.dayOfWeek === dow && dentroDaVigencia) {\n const passo = ((b as any).weekInterval ?? 0) + 1\n vale = passo <= 1 || !(b as any).validFrom\n || semanasEntre((b as any).validFrom, iso) % passo === 0\n }\n if (!vale) continue\n out.push({\n id: `block-${b.id}-${iso}`,\n resourceId: b.assigneeId,\n title: titulo,\n start: `${iso}T${b.startsAt}`,\n end: `${iso}T${b.endsAt}`,\n // Arrastável: mudar o almoço de 12h para 12h30 é o ajuste mais comum\n // que existe nesta tela, e obrigar a abrir um diálogo para quinze\n // minutos é o tipo de caminho que faz a pessoa deixar errado.\n editable: true,\n // A cor vai no EVENTO, com as variáveis do tema: o FullCalendar\n // pinta o fundo inline a partir da cor do calendário, e uma regra de\n // folha externa perdia a corrida em recarga quente — o bloqueio saía\n // azul, idêntico a um atendimento. Inline é determinístico, e as\n // `var()` continuam respondendo ao tema claro/escuro.\n backgroundColor: 'hsl(var(--muted-foreground) / 0.16)',\n borderColor: 'hsl(var(--muted-foreground) / 0.4)',\n textColor: 'hsl(var(--foreground))',\n classNames: ['fc-agenda-block'],\n extendedProps: { isBlock: true, blockId: b.id },\n })\n }\n }\n return out\n }, [blocks, visibleDates, visibleRange])\n\n const cardPrefs = useTenantPluginSettings('agenda', { cardColorByServiceKind: false })\n const colorByKind = cardPrefs.get('cardColorByServiceKind')\n const serviceIdsKey = useMemo(() => {\n if (!colorByKind) return ''\n const ids = new Set<string>()\n for (const b of filteredBookings) for (const sv of b.services ?? []) if (sv.serviceId) ids.add(sv.serviceId)\n return [...ids].sort().join(',')\n }, [colorByKind, filteredBookings])\n const [serviceLooks, setServiceLooks] = useState<ServiceAppearance | undefined>(undefined)\n useEffect(() => {\n if (!serviceIdsKey || !provider.getServiceAppearance) { setServiceLooks(undefined); return }\n let alive = true\n provider.getServiceAppearance(serviceIdsKey.split(','))\n .then((m) => { if (alive) setServiceLooks(m) })\n .catch(() => { if (alive) setServiceLooks(undefined) })\n return () => { alive = false }\n }, [serviceIdsKey, provider])\n\n const bookingEvents = useMemo(() =>\n filteredBookings.map((b) => bookingToEvent(b, statusColors, visibleResourceIds, colorByKind ? serviceLooks : undefined)),\n [filteredBookings, statusColors, visibleResourceIds, colorByKind, serviceLooks])\n\n // Merge static config locations with dynamically fetched locations\n const allLocations = useMemo(() => {\n const map = new Map<string, string>()\n for (const loc of config.locations) map.set(loc.id, loc.name)\n for (const loc of storeLocations) map.set(loc.id, loc.name)\n return map\n }, [config.locations, storeLocations])\n\n const locationMap = useMemo(() => {\n if (!config.modules.locationSelection || allLocations.size === 0) return undefined\n return allLocations\n }, [config.modules.locationSelection, allLocations])\n\n // Só as agendas DESENHADAS: um evento de disponibilidade para uma coluna que\n // não existe não aparece em lugar nenhum, e gerar um por dia por profissional\n // para 739 pessoas custa o mesmo que desenhá-las.\n // O nome que a faixa aberta leva quando a grade não aponta local nenhum.\n // Com UM local cadastrado é o nome dele — a casa tem um endereço e não há o\n // que escolher; com nenhum ou vários, o rótulo genérico do V1.\n const defaultLocationName = useMemo(() => {\n if (allLocations.size === 1) return [...allLocations.values()][0]\n return t('agenda.calendar.defaultLocation')\n }, [allLocations, t])\n\n const availabilityEvents = useMemo(() =>\n generateAvailabilityEvents(\n schedules, drawnProfessionals, visibleRange, effectiveBusinessHours,\n locationMap, defaultLocationName,\n ),\n [schedules, drawnProfessionals, visibleRange, effectiveBusinessHours, locationMap, defaultLocationName])\n\n const events = useMemo(() => {\n // A LISTA não tem colunas, e o que serve à grade atrapalha nela.\n //\n // A etiqueta de local é um evento de 20 minutos que escreve \"Local Padrão\"\n // no alto da faixa aberta — na grade é uma legenda discreta; na lista vira\n // uma LINHA igual à de um atendimento, e quem abre a agenda do dia lê\n // \"08:00 Local Padrão\" duas vezes antes do primeiro cliente.\n //\n // O fundo de indisponibilidade some junto, pelo mesmo motivo: \"fora da\n // grade\" é uma área da coluna, não um compromisso.\n const ehLista = currentView.startsWith('list')\n const disponibilidade = ehLista\n ? availabilityEvents.filter((e: any) => !e.extendedProps?.isLocationLabel && e.display !== 'background')\n : availabilityEvents\n return [...bookingEvents, ...disponibilidade, ...blockEvents]\n }, [bookingEvents, availabilityEvents, blockEvents, currentView])\n\n const storedView = prefs.get('calendarView')\n // A link names the view and the day; the remembered view is for the bare /agenda.\n const adminPath = useAdminPath()\n const urlTarget = useMemo(() => parseAgendaPath(adminPath), [adminPath])\n const effectiveInitialView = urlTarget\n ? calendarViewFor(urlTarget.view, resourceCapable)\n : resourceCapable ? viewForResources(storedView) : viewForNoResources(storedView)\n\n // ── Calendar handlers ──\n const handleDatesSet = useCallback((arg: { startStr: string; endStr: string; view: { title: string; type: string } }) => {\n setCalendarTitle(arg.view.title)\n setView(arg.view.type)\n setVisibleRange({ start: arg.startStr, end: arg.endStr })\n fetchBookings({ start: arg.startStr, end: arg.endStr })\n // Once the URL names a view, it keeps naming the one on screen — replaced,\n // not pushed: paging through weeks must not bury the Back button.\n const here = currentAppPath()\n if (parseAgendaPath(here)) {\n const api = calendarRef.current?.getApi()\n const next = agendaPath(urlViewOf(arg.view.type), api?.getDate())\n if (next !== here) { try { window.history.replaceState(null, '', appHref(next)) } catch { /* the view still changed */ } }\n }\n }, [fetchBookings, setView])\n\n // Back/Forward and typed links: the calendar follows the URL without remounting.\n useEffect(() => {\n if (!urlTarget) return\n const api = calendarRef.current?.getApi()\n if (!api) return\n const view = calendarViewFor(urlTarget.view, resourceCapable)\n const sameDay = !urlTarget.date || api.getDate().toDateString() === urlTarget.date.toDateString()\n if (api.view.type === view && sameDay) return\n api.changeView(view)\n if (urlTarget.date) { api.gotoDate(urlTarget.date); setSelectedDate(urlTarget.date) }\n }, [urlTarget, resourceCapable])\n\n /** A day of the week, opened on its own. The week stays one Back away. */\n const openDay = useCallback((date: Date) => {\n const api = calendarRef.current?.getApi()\n // Name where we are first, or Back would land on a URL that says nothing\n // and the remembered view — now \"day\" — would answer for it.\n if (api && !parseAgendaPath(currentAppPath())) {\n try { window.history.replaceState(null, '', appHref(agendaPath(urlViewOf(api.view.type), api.getDate()))) } catch { /* Back degrades to the list */ }\n }\n adminNavigateTo(agendaPath('day', date))\n }, [])\n\n // Double-click → open edit directly\n // Right-click → context menu\n const handleEventDidMount = useCallback((arg: { event: any; el: HTMLElement }) => {\n const booking = arg.event.extendedProps?.booking as CalendarBooking | undefined\n if (booking) arg.el.setAttribute('data-booking-id', booking.id)\n // NEM TODO EVENTO É UM AGENDAMENTO.\n //\n // Desde que o BLOQUEIO passou a desenhar na grade, estes dois ouvintes\n // liam `extendedProps.booking` de um evento que não tem nenhum. O duplo\n // clique estourava em `booking.id`; o botão direito era pior — guardava\n // `booking: undefined` no menu e a agenda INTEIRA caía no error boundary,\n // com \"Não foi possível carregar esta tela\" no lugar do dia de trabalho.\n //\n // Sair sem fazer nada é o certo aqui: o clique simples já abre o diálogo\n // do bloqueio (ver `handleEventClick`), e o duplo clique dispara um\n // clique antes. Um menu de contexto para bloqueio é outra conversa.\n const temAgendamento = () => !!arg.event.extendedProps?.booking\n arg.el.addEventListener('dblclick', (e) => {\n if (!temAgendamento()) return\n e.preventDefault()\n e.stopPropagation()\n skipClickRef.current = true\n const booking = arg.event.extendedProps.booking as CalendarBooking\n setSelectedBooking(null)\n setPopoverAnchor(null)\n setContextMenu(null)\n openModal('edit', { bookingId: booking.id })\n })\n arg.el.addEventListener('contextmenu', (e) => {\n if (!temAgendamento()) return\n e.preventDefault()\n const booking = arg.event.extendedProps.booking as CalendarBooking\n const menuW = 210, menuH = 200\n let x = e.clientX + 4\n let y = e.clientY + 4\n if (x + menuW > window.innerWidth - 12) x = x - menuW\n if (y + menuH > window.innerHeight - 12) y = y - menuH\n setContextMenu({ booking, x, y })\n setContextMenuVisible(true)\n setSelectedBooking(null)\n setPopoverAnchor(null)\n })\n }, [])\n\n // Flag to suppress single-click after a double-click\n const skipClickRef = useRef(false)\n\n // Hover timer — show popover after 4s hover on a booking event\n const hoverTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const handleEventMouseEnter = useCallback((arg: { event: any; el: HTMLElement }) => {\n if (arg.event.display === 'background') return\n if (arg.event.extendedProps?.isLocationLabel) return\n const booking = arg.event.extendedProps.booking as CalendarBooking\n if (!booking) return\n\n hoverTimerRef.current = setTimeout(() => {\n const rect = arg.el.getBoundingClientRect()\n const popW = 320, popH = 340\n let x = rect.right + 8\n let y = rect.top + rect.height / 2 - popH / 2\n if (x + popW > window.innerWidth - 16) x = rect.left - popW - 8\n if (x < 16) x = Math.max(16, rect.left + rect.width / 2 - popW / 2)\n if (y + popH > window.innerHeight - 16) y = window.innerHeight - popH - 16\n if (y < 16) y = 16\n setSelectedBooking(booking)\n setPopoverAnchor({ x, y })\n setPopoverVisible(true)\n }, 3000)\n }, [])\n\n const handleEventMouseLeave = useCallback(() => {\n if (hoverTimerRef.current) {\n clearTimeout(hoverTimerRef.current)\n hoverTimerRef.current = null\n }\n }, [])\n\n // Single click — open popover instantly, or slide to new position if already open\n const handleEventClick = useCallback((arg: EventClickArg) => {\n if (skipClickRef.current) { skipClickRef.current = false; return }\n // Ignore clicks on background availability events and location labels\n if (arg.event.display === 'background') return\n if (arg.event.extendedProps?.isLocationLabel) return\n // O BLOQUEIO abre o diálogo dele, não o popover de agendamento: ele não\n // tem cliente, serviço nem pagamento, e as ações que cabem são outras\n // duas — mudar o horário ou desfazer.\n if (arg.event.extendedProps?.isBlock) {\n setContextMenu(null); setContextMenuVisible(false)\n const clicado = blocks.find((b) => b.id === arg.event.extendedProps.blockId)\n if (clicado) setEditingBlock(toEditingBlock(clicado, blocks))\n return\n }\n setContextMenu(null); setContextMenuVisible(false)\n const booking = arg.event.extendedProps.booking as CalendarBooking\n if (!booking) return\n const rect = arg.el.getBoundingClientRect()\n const popW = 320, popH = 340\n let x = rect.right + 8\n let y = rect.top + rect.height / 2 - popH / 2\n if (x + popW > window.innerWidth - 16) x = rect.left - popW - 8\n if (x < 16) x = Math.max(16, rect.left + rect.width / 2 - popW / 2)\n if (y + popH > window.innerHeight - 16) y = window.innerHeight - popH - 16\n if (y < 16) y = 16\n // Always update — if popover is already open it slides to the new position\n setSelectedBooking(booking)\n setPopoverAnchor({ x, y })\n setPopoverVisible(true)\n // `blocks` nas dependências: com a lista vazia o callback congelava a do\n // PRIMEIRO render — sempre vazia —, e clicar num bloqueio não achava a\n // linha dele. O sintoma era o clique não fazer nada.\n }, [blocks])\n\n // Find the schedule block covering a given time slot for a professional\n const findScheduleForSlot = useCallback((professionalId: string | undefined, dateTimeStr: string): Schedule | null => {\n if (!professionalId) return null\n const dt = new Date(dateTimeStr)\n // Data pelo relógio LOCAL: `toISOString` devolve o dia anterior para\n // qualquer horário a partir das 21h no Brasil, e este é o cálculo que\n // decide se o clique cai em grade aberta ou pede confirmação.\n const pad = (n: number) => String(n).padStart(2, '0')\n const dateStr = `${dt.getFullYear()}-${pad(dt.getMonth() + 1)}-${pad(dt.getDate())}`\n const timeMin = dt.getHours() * 60 + dt.getMinutes()\n\n // O MESMO motor da grade desenhada. Aqui ele decide se clicar num vão\n // abre o formulário direto ou pergunta antes (\"fora da grade\") — e a\n // pergunta tem de concordar com o que a tela desenhou.\n const profSchedules = schedules.filter((s) => s.assigneeId === professionalId)\n const daySchedules = effectiveWindows(profSchedules, dateStr)\n\n for (const s of daySchedules) {\n const [sh, sm] = s.startsAt.split(':').map(Number)\n const [eh, em] = s.endsAt.split(':').map(Number)\n if (timeMin >= sh * 60 + sm && timeMin < eh * 60 + em) return s\n }\n return null\n }, [schedules])\n\n // UM caminho só para \"abrir o formulário a partir de um vão da grade\": o\n // arrasto do mouse (`select`) e o toque no tablet (`dateClick`) desembocam\n // aqui, e a janela de 500 ms garante UM formulário por gesto — o toque\n // longo dispara os dois eventos, e sem ela o segundo apagava o prefill do\n // primeiro.\n const lastSlotOpenRef = useRef(0)\n const openCreateForSlot = useCallback((startStr: string, endStr: string, professionalId: string | undefined) => {\n calendarRef.current?.getApi().unselect()\n\n const now = Date.now()\n if (now - lastSlotOpenRef.current < 500) return\n lastSlotOpenRef.current = now\n\n // Don't open create if popover/context menu is showing — dismiss them instead\n if (popoverVisibleRef.current || contextMenuVisibleRef.current) {\n setPopoverVisible(false); setSelectedBooking(null); setPopoverAnchor(null)\n setContextMenuVisible(false); setContextMenu(null)\n return\n }\n\n const schedule = findScheduleForSlot(professionalId, startStr)\n\n const proceed = () => {\n const locId = schedule?.locationId ?? (schedule?.metadata?.locationId as string | undefined)\n openModal('create', { prefill: { startsAt: startStr, endsAt: endStr, professionalId, locationId: locId || undefined } })\n }\n\n // Warn if no schedule covers this slot — only when the working-hours module\n // is on (off by default in eventMode:'simple', so simple/Google-Calendar\n // events never surface the \"no open schedule for this professional\" dialog).\n if (config.modules.workingHours && !schedule) {\n setScheduleConfirm({ onConfirm: proceed })\n return\n }\n\n proceed()\n }, [openModal, findScheduleForSlot, config.modules.workingHours])\n\n const handleSelect = useCallback((arg: DateSelectArg) => {\n openCreateForSlot(arg.startStr, arg.endStr, arg.resource?.id)\n }, [openCreateForSlot])\n\n // O TOQUE NO IPAD.\n //\n // `selectable` só nasce de um ARRASTO. No dedo, arrasto é toque LONGO — e o\n // toque curto, que é o gesto que todo mundo faz, não produzia evento nenhum:\n // a grade parecia morta no tablet. `dateClick` é esse toque.\n const handleDateClick = useCallback((arg: DateClickArg) => {\n const professionalId = (arg as { resource?: { id: string } }).resource?.id\n if (arg.allDay) {\n openCreateForSlot(arg.dateStr, localDateKey(new Date(arg.date.getTime() + 86_400_000)), professionalId)\n return\n }\n const end = new Date(arg.date.getTime() + config.slotDuration * 60_000)\n openCreateForSlot(localDateTimeString(arg.date), localDateTimeString(end), professionalId)\n }, [openCreateForSlot, config.slotDuration])\n\n const handleEventDrop = useCallback(async (arg: EventDropArg) => {\n // O BLOQUEIO move o GRUPO. Um recorrente é uma linha por dia da semana com\n // o mesmo horário; arrastar a quarta e deixar a segunda para trás criaria\n // um \"Almoço\" que muda de hora no meio da semana sem ninguém ter pedido.\n //\n // O toast diz QUANTOS dias mudaram — a informação chega depois do gesto,\n // mas chega, e desfazer é arrastar de volta.\n if (arg.event.extendedProps?.isBlock) {\n const clicado = blocks.find((b) => b.id === arg.event.extendedProps.blockId)\n if (!clicado || !provider.createBlock || !provider.deleteBlock) { arg.revert(); return }\n const grupo = toEditingBlock(clicado, blocks)\n const hhmm = (iso: string) => new Date(iso).toTimeString().slice(0, 5)\n try {\n await provider.deleteBlock(grupo.ids)\n await provider.createBlock({\n assigneeId: arg.newResource?.id ?? grupo.assigneeId,\n title: grupo.title,\n description: grupo.description || undefined,\n startsAt: hhmm(arg.event.startStr),\n endsAt: hhmm(arg.event.endStr),\n ...(grupo.specificDate\n ? { specificDate: arg.event.startStr.slice(0, 10) }\n : {\n daysOfWeek: grupo.daysOfWeek,\n validFrom: grupo.validFrom ?? undefined,\n validTo: grupo.validTo,\n weekInterval: grupo.weekInterval,\n }),\n })\n toast.success(grupo.ids.length > 1\n ? `${grupo.title} movido em ${grupo.ids.length} dias`\n : `${grupo.title} movido`)\n invalidateSchedules()\n } catch (err: any) {\n arg.revert()\n toast.error('Não foi possível mover o bloqueio', { description: err?.message })\n }\n return\n }\n const booking = arg.event.extendedProps.booking as CalendarBooking\n try { await rescheduleBooking(booking.id, arg.event.startStr, arg.event.endStr, arg.newResource?.id ?? undefined) }\n catch { arg.revert() }\n }, [rescheduleBooking, blocks, provider, invalidateSchedules])\n\n const handleViewChange = useCallback((v: string) => {\n calendarRef.current?.getApi().changeView(v)\n prefs.set('calendarView', v)\n }, [prefs])\n // Mobile switcher: swap between the list sentinel and a real grid view. When a\n // grid is picked we also sync the store's currentView so the resource-collapse\n // effect doesn't fight the freshly-mounted mobile calendar; if it's already\n // mounted (grid → grid), changeView animates in place.\n const handleMobileViewChange = useCallback((v: string) => {\n setMobileView(v)\n if (v === MOBILE_LIST_VIEW) return\n setView(v)\n calendarRef.current?.getApi()?.changeView(v)\n }, [setView])\n const handlePrev = useCallback(() => calendarRef.current?.getApi().prev(), [])\n const handleNext = useCallback(() => calendarRef.current?.getApi().next(), [])\n const handleToday = useCallback(() => { calendarRef.current?.getApi().today(); setSelectedDate(new Date()) }, [])\n\n function handleMiniDateSelect(date: Date) {\n setSelectedDate(date)\n calendarRef.current?.getApi().gotoDate(date)\n }\n\n function toggleProfessional(id: string) {\n if (selectedProfIds.includes(id)) {\n setFilters({ professionalIds: selectedProfIds.filter((p) => p !== id) })\n return\n }\n // Recusar é melhor do que aceitar e desenhar ilegível. A alternativa —\n // deixar marcar e mostrar colunas de 14px — foi o que quebrou a tela.\n if (selectedProfIds.length >= MAX_SELECTED_AGENDAS) {\n toast.error(t('agenda.sidebar.tooManyAgendas', { max: String(MAX_SELECTED_AGENDAS) }))\n return\n }\n setFilters({ professionalIds: [...selectedProfIds, id] })\n }\n\n function toggleStatus(value: string) {\n const next = selectedStatuses.includes(value)\n ? selectedStatuses.filter((s) => s !== value)\n : [...selectedStatuses, value]\n setFilters({ statuses: next })\n }\n\n // Alternating resource backgrounds — apply via DOM after render\n const wrapperRef = useRef<HTMLDivElement>(null)\n\n // FullCalendar measures its columns once and only re-measures on a WINDOW\n // resize. Opening/closing the assistant rail (or the sidebar) resizes the\n // container without one, so the grid stayed locked at the narrow width until\n // a real window resize came along. Watch the container and hand FC the new box.\n useEffect(() => {\n const container = wrapperRef.current\n if (!container) return\n let frame = 0\n let lastWidth = container.clientWidth\n let lastHeight = container.clientHeight\n const ro = new ResizeObserver(() => {\n const width = container.clientWidth\n const height = container.clientHeight\n if (width === lastWidth && height === lastHeight) return\n lastWidth = width\n lastHeight = height\n // Next frame, not inline: measuring inside the observer callback reads a\n // mid-layout box (and trips the RO loop warning). The rail animates, so\n // this fires on each frame and the last one settles on the final width.\n cancelAnimationFrame(frame)\n frame = requestAnimationFrame(() => calendarRef.current?.getApi()?.updateSize())\n })\n ro.observe(container)\n return () => { cancelAnimationFrame(frame); ro.disconnect() }\n // Re-attach whenever the calendar branch remounts (skeleton → grid, mobile\n // list → grid), since the observed node is gone on the other branches.\n }, [isMobile, mobileGridActive, professionalsLoading, professionals.length])\n\n // Responsive day headers — collapse weekday names to a single initial (S M T\n // W T F S, Google-Calendar style) when day columns get too narrow. Measured\n // from the actual rendered column width so it adapts to resource count + view.\n const [dayHeaderCompact, setDayHeaderCompact] = useState(false)\n useEffect(() => {\n const container = wrapperRef.current\n if (!container) return\n let frame = 0\n const measure = () => {\n // Measure an actual DAY column ([data-date]) — in resource views the first\n // .fc-col-header-cell is the wide resource header, not a day column.\n const cell = container.querySelector('.fc-col-header-cell[data-date]') as HTMLElement | null\n if (!cell) return\n const colWidth = cell.getBoundingClientRect().width\n // Collapse to single-letter ONLY when the full weekday label can't fit.\n // Measure the widest full line (\"WED\" / \"12/14\") in the header's font so\n // the breakpoint adapts to font + locale instead of a magic number.\n const cushion = (cell.querySelector('.fc-col-header-cell-cushion') as HTMLElement | null) ?? cell\n const cs = getComputedStyle(cushion)\n const probe = document.createElement('span')\n probe.style.cssText = 'position:absolute;visibility:hidden;white-space:nowrap;top:-9999px'\n probe.style.fontSize = cs.fontSize\n probe.style.fontWeight = cs.fontWeight\n probe.style.fontFamily = cs.fontFamily\n probe.style.letterSpacing = cs.letterSpacing\n probe.style.textTransform = cs.textTransform\n document.body.appendChild(probe)\n probe.textContent = 'Wed'\n const weekdayWidth = probe.getBoundingClientRect().width\n probe.textContent = '12/14'\n const dateWidth = probe.getBoundingClientRect().width\n probe.remove()\n const needed = Math.max(weekdayWidth, dateWidth) + 12 // text + cushion padding\n setDayHeaderCompact(colWidth < needed)\n }\n // FullCalendar reflows its inner day columns on a later tick than the\n // container resize, so re-measure across a few frames to read settled widths.\n const timers: ReturnType<typeof setTimeout>[] = []\n const schedule = () => {\n cancelAnimationFrame(frame)\n frame = requestAnimationFrame(measure)\n timers.forEach(clearTimeout)\n timers.length = 0\n timers.push(setTimeout(measure, 130), setTimeout(measure, 330))\n }\n schedule()\n const ro = new ResizeObserver(schedule)\n ro.observe(container)\n return () => { cancelAnimationFrame(frame); timers.forEach(clearTimeout); ro.disconnect() }\n }, [resources, currentView, visibleRange])\n\n /**\n * Pinta o AGRUPAMENTO da grade.\n *\n * Na semana a data é o grupo de cima e o profissional é a folha, então quem\n * precisa de faixa é o DIA: sem ela doze colunas seguidas viram uma régua sem\n * junta e ninguém acha onde domingo acaba. A primeira coluna de cada dia\n * ainda ganha uma linha grossa (`fc-day-start`), que é a parede do bloco.\n *\n * No dia só existe uma data — aí a faixa volta a ser por pessoa, que é a\n * única divisão que sobrou.\n */\n const applyResourceStriping = useCallback(() => {\n const container = wrapperRef.current\n if (!container) return\n const resourceIds = resources.map((r: { id: string }) => r.id)\n const cells = Array.from(container.querySelectorAll('[data-resource-id]'))\n if (cells.length === 0) return\n\n const dates: string[] = []\n for (const el of cells) {\n const d = el.getAttribute('data-date')\n if (d && !dates.includes(d)) dates.push(d)\n }\n const groupByDate = dates.length > 1\n const firstResource = resourceIds[0]\n\n for (const el of cells) {\n const rid = el.getAttribute('data-resource-id')\n const date = el.getAttribute('data-date')\n if (groupByDate) {\n const idx = date ? dates.indexOf(date) : -1\n el.classList.toggle('fc-resource-alt', idx % 2 === 1)\n el.classList.toggle('fc-day-start', rid === firstResource)\n } else {\n const idx = rid ? resourceIds.indexOf(rid) : -1\n el.classList.toggle('fc-resource-alt', resourceIds.length > 1 && idx % 2 === 1)\n el.classList.remove('fc-day-start')\n }\n }\n }, [resources])\n\n useEffect(() => {\n applyResourceStriping()\n const t1 = setTimeout(applyResourceStriping, 100)\n const t2 = setTimeout(applyResourceStriping, 300)\n return () => { clearTimeout(t1); clearTimeout(t2) }\n }, [applyResourceStriping, currentView, visibleRange, bookings])\n\n // Listen for cross-plugin booking open requests (e.g., from financial invoice detail)\n useEffect(() => {\n function handleOpenBooking(e: Event) {\n const detail = (e as CustomEvent).detail ?? {}\n const externalSource = detail.source\n ? { type: String(detail.source), id: detail.waitlistId, waitlistId: detail.waitlistId }\n : undefined\n if (detail.bookingId) {\n openModal('edit', { bookingId: detail.bookingId, externalSource })\n return\n }\n openModal('create', {\n prefill: detail.prefill ?? {\n clientId: detail.clientId,\n professionalId: detail.professionalId,\n locationId: detail.locationId,\n startsAt: detail.startsAt,\n },\n externalSource,\n })\n }\n // As ações da ficha de uma pessoa chegam por aqui: elas navegam para a\n // agenda e AVISAM, porque a grade e o bloqueio só fazem sentido dentro do\n // calendário — ao lado do que já está marcado. Ver o `registerPersonActions`\n // em ../index.ts.\n const handleOpenSchedules = (e: Event) => {\n const detail = (e as CustomEvent).detail ?? {}\n if (detail.professionalId) setFilters({ professionalIds: [detail.professionalId] })\n setSchedulesOpen(true)\n setSchedulesFor(((e as CustomEvent).detail ?? {}).professionalId ?? null)\n }\n const handleOpenBlock = (e: Event) => {\n const detail = (e as CustomEvent).detail ?? {}\n setBlockFor({ professionalId: detail.professionalId ?? null, date: detail.date ?? null })\n }\n window.addEventListener('agenda:open-booking', handleOpenBooking)\n window.addEventListener('agenda:open-schedules', handleOpenSchedules)\n window.addEventListener('agenda:open-block', handleOpenBlock)\n return () => {\n window.removeEventListener('agenda:open-booking', handleOpenBooking)\n window.removeEventListener('agenda:open-schedules', handleOpenSchedules)\n window.removeEventListener('agenda:open-block', handleOpenBlock)\n }\n }, [openModal, setFilters])\n\n // Custom day header: weekday + date stacked. When columns get narrow it\n // collapses the weekday to a single initial (S / 16, Google-Calendar style).\n // Always returns explicit content — returning undefined renders an EMPTY\n // header in the React adapter rather than falling back to the default.\n const dayHeaderContent = useCallback((arg: any) => {\n const date: Date = arg.date\n const dateLocale = currentLocale === 'pt-BR' ? 'pt-BR' : 'en'\n // A data do dia em ISO pelo RELÓGIO LOCAL. `toISOString` daria o dia\n // anterior a partir das 21h no Brasil, e o feriado apareceria na véspera.\n const pad = (n: number) => String(n).padStart(2, '0')\n const iso = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`\n // NO MÊS O CABEÇALHO NÃO É UM DIA — é um dia da SEMANA.\n //\n // O FullCalendar passa uma data qualquer da primeira linha, e a tela vinha\n // escrevendo \"SÁB. 03/01\" acima de uma grade de setembro: uma data que não\n // existe em lugar nenhum daquele mês, repetida na coluna inteira. Aqui\n // sobra só o nome do dia; o número de cada dia já está dentro da célula,\n // que é também onde o feriado do mês aparece.\n const noMes = arg.view?.type === 'dayGridMonth'\n const feriado = noMes ? undefined : holidayByDate.get(iso)\n // Inline styles (not CSS classes) so stacking is guaranteed regardless of\n // the runtime style-injection state.\n // Hugs its label, but never wider than the column: the cushion around it\n // is a block now (see calendar-styles), which is what gives the holiday's\n // ellipsis a width to measure against — before, the name pushed the day\n // out of its column.\n const wrapStyle: React.CSSProperties = { display: 'flex', flexDirection: 'column', alignItems: 'center', lineHeight: 1.15, width: 'fit-content', maxWidth: '100%', minWidth: 0, margin: '0 auto', boxSizing: 'border-box' }\n // In a week, a day is a door to that day.\n const dayLink = String(arg.view?.type ?? '').endsWith('Week')\n ? {\n role: 'link' as const,\n tabIndex: 0,\n className: 'agenda-day-link',\n onClick: () => openDay(date),\n onKeyDown: (e: React.KeyboardEvent) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openDay(date) } },\n }\n : {}\n const dateStyle: React.CSSProperties = { fontSize: '0.65rem', opacity: 0.75 }\n if (dayHeaderCompact) {\n const letter = date.toLocaleDateString(dateLocale, { weekday: 'narrow' })\n return (\n <div style={wrapStyle} title={feriado ? feriado.names.join(' · ') : undefined} {...dayLink}>\n <span style={{ fontWeight: 600 }}>{letter}</span>\n <span style={dateStyle}>{date.getDate()}</span>\n {/* Coluna estreita não cabe o nome: fica o PONTO, e o nome no\n título. Sem ele o dia 7 de setembro seria uma terça qualquer. */}\n {feriado && (\n <span\n aria-label={feriado.names.join(' · ')}\n style={{\n width: 4, height: 4, borderRadius: 999, marginTop: 2,\n background: feriado.closes ? 'hsl(var(--destructive))' : 'hsl(var(--muted-foreground))',\n }}\n />\n )}\n </div>\n )\n }\n const weekday = date.toLocaleDateString(dateLocale, { weekday: 'short' })\n // E o NOME do dia, no mês, vem do FullCalendar e não de `arg.date`: a data\n // que ele passa no cabeçalho do mês é um representante da coluna, não o\n // dia dela, e calcular o nome a partir dela escrevia \"SÁB.\" em cima da\n // coluna de domingo — o mês inteiro rotulado com um dia de erro.\n if (noMes) return <div style={wrapStyle}><span>{arg.text}</span></div>\n // A ORDEM DO DIA E DO MÊS É DO IDIOMA, não do código.\n //\n // Estava escrito `mês/dia` na mão, e o cabeçalho saía \"sáb. 1/3\" para o\n // dia 3 de janeiro — com o dia da semana em português ao lado. Um\n // brasileiro lê 1/3 como 1º de março, e enquanto os dois números são ≤ 12\n // não há nada na tela que denuncie a troca: a agenda parecia estar noutra\n // data e concordava consigo mesma.\n //\n // `toLocaleDateString` com `day` e `month` numéricos devolve a ordem certa\n // de cada idioma — e é a mesma função que já escreve o dia da semana logo\n // acima, que estava certo o tempo todo.\n const diaMes = date.toLocaleDateString(dateLocale, { day: 'numeric', month: 'numeric' })\n return (\n <div style={wrapStyle} {...dayLink}>\n <span>{weekday}</span>\n <span style={dateStyle}>{diaMes}</span>\n {/* O NOME, não um ícone: \"feriado\" não diz se a casa fecha ou se é o\n Dia da Manicure, e quem olha a semana decide com o nome. Vermelho\n só para o que fecha — a comemorativa é legenda. */}\n {feriado && (\n <span\n title={feriado.names.join(' · ')}\n style={{\n fontSize: '0.6rem', lineHeight: 1.1, marginTop: 1, maxWidth: '100%',\n overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',\n fontWeight: feriado.closes ? 600 : 400,\n color: feriado.closes ? 'hsl(var(--destructive))' : 'hsl(var(--muted-foreground))',\n }}\n >\n {feriado.names[0]}{feriado.names.length > 1 ? ` +${feriado.names.length - 1}` : ''}\n </span>\n )}\n </div>\n )\n }, [dayHeaderCompact, currentLocale, holidayByDate, openDay])\n\n /**\n * A CÉLULA DO MÊS — o número do dia e, embaixo, o que aquele dia é.\n *\n * No mês o cabeçalho é por dia da SEMANA, então o feriado não cabe lá: é a\n * célula que sabe a data. Vermelho só para o que fecha a casa.\n */\n const dayCellContent = useCallback((arg: any) => {\n const date: Date = arg.date\n const pad = (n: number) => String(n).padStart(2, '0')\n const feriado = holidayByDate.get(`${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`)\n return (\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', maxWidth: '100%', minWidth: 0 }}>\n <span>{arg.dayNumberText}</span>\n {feriado && (\n <span\n title={feriado.names.join(' · ')}\n style={{\n fontSize: '0.6rem', lineHeight: 1.1, maxWidth: '100%',\n overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',\n fontWeight: feriado.closes ? 600 : 400,\n color: feriado.closes ? 'hsl(var(--destructive))' : 'hsl(var(--muted-foreground))',\n }}\n >\n {feriado.names[0]}{feriado.names.length > 1 ? ` +${feriado.names.length - 1}` : ''}\n </span>\n )}\n </div>\n )\n }, [holidayByDate])\n\n const resourceLabelContent = useCallback((arg: any) => {\n const { id, title, extendedProps } = arg.resource\n return (\n <div className=\"flex items-center gap-1.5 px-1.5 py-1.5 min-w-0\">\n {/* O mesmo retrato do seletor: quem escolheu a agenda na coluna da\n esquerda reconhece a coluna da grade pela mesma cara. */}\n <PersonAvatar name={title} src={extendedProps?.avatarUrl} size=\"xs\" />\n <div className=\"flex min-w-0 flex-1 items-center gap-1 overflow-hidden\">\n <PersonLink\n personId={id}\n name={abbreviatePersonName(title)}\n avatarUrl={extendedProps?.avatarUrl}\n size=\"sm\"\n tab=\"schedule\"\n profileHref={appHref(`/registry/staff/${id}/schedule`)}\n />\n {id === nextProfessionalId ? (\n <Badge className=\"shrink-0 border-foreground/10 bg-foreground px-1.5 py-0 text-[9px] leading-4 text-background\">\n Próximo\n </Badge>\n ) : null}\n </div>\n </div>\n )\n }, [nextProfessionalId])\n\n const eventContent = useCallback((arg: any) => {\n // FullCalendar renders content for background events too; the \"outside the\n // grid\" shade would otherwise print its own hours over every column.\n if (arg.event.display === 'background') return null\n // Location label events — render as a small tag\n if (arg.event.extendedProps?.isLocationLabel) {\n return (\n <div className=\"px-1.5 py-0.5 overflow-hidden\">\n <p className=\"text-[10px] font-medium truncate\">{arg.event.title}</p>\n </div>\n )\n }\n const serviceNames = arg.event.extendedProps?.serviceNames\n const start = arg.event.start\n const end = arg.event.end\n const fmt = (d: Date) => `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`\n const timeRange = start && end ? `${fmt(start)} – ${fmt(end)}` : start ? fmt(start) : ''\n const stripe = arg.event.extendedProps?.statusStripe as string | undefined\n return (\n <div className={`relative py-0.5 overflow-hidden leading-tight h-full ${stripe ? 'pl-2.5 pr-1.5' : 'px-1.5'}`}>\n {stripe && <span aria-hidden className=\"absolute inset-y-0 left-0 w-1.5\" style={{ backgroundColor: stripe }} />}\n <div className=\"flex items-start justify-between gap-1\">\n <p className=\"text-[11px] font-semibold truncate\">{arg.event.title}</p>\n {serviceNames && <p className=\"text-[10px] opacity-60 truncate shrink-0 max-w-[45%] text-right\">{serviceNames}</p>}\n </div>\n {timeRange && <p className=\"text-[9px] opacity-50\">{timeRange}</p>}\n </div>\n )\n }, [])\n\n return (\n <div ref={shellRef} className=\"flex\" style={{ height: shellHeight ?? undefined }}>\n {/* ═══ A COLUNA DA ESQUERDA ═══\n Mesmo componente das outras telas do módulo — ver AgendaFilterRail.\n Aqui só se diz O QUE ela tem; a largura, o fio entre seções, o selo\n de contagem e o \"fechada por padrão\" são dela. */}\n <AgendaRailColumn>\n <AgendaFilterRail\n // \"Agendar\" fica de fora de propósito: em toda outra tela do app a\n // ação primária mora no cabeçalho, e duplicá-la aqui ensinaria dois\n // lugares para a mesma coisa. Bloquear e Horários não tinham NENHUM.\n quickActions={[\n { id: 'block', label: t('agenda.sidebar.block'), icon: Ban, onClick: () => setBlockFor({ professionalId: null, date: null }) },\n ...(config.capabilities.professional\n ? [{ id: 'working-hours', label: t('agenda.sidebar.workingHours'), icon: Clock3, onClick: () => setSchedulesOpen(true) }]\n : []),\n ]}\n beforeMark={{ label: 'Calendário' }}\n before={<>\n <MiniCalendar selectedDate={selectedDate} onDateSelect={handleMiniDateSelect} />\n {/* O que o período PERDEU. Fica acima dos filtros, como no V1: é um\n número, não um filtro — e clicar nele liga o filtro do estado,\n que é a pergunta seguinte (\"quais foram?\"). */}\n <LostSlotsCard\n range={visibleRange}\n selectedStatuses={selectedStatuses}\n onPick={toggleStatus}\n />\n </>}\n sections={[\n {\n id: 'professionals',\n title: t('agenda.sidebar.professionals'),\n count: selectedProfIds.length,\n hidden: !config.capabilities.professional,\n // O mesmo primitivo do \"quem atende\" do agendamento, na versão de\n // marcar várias: o retrato é o que separa a Ana Caroline da Ana\n // Luiza numa coluna de 220px, onde o nome trunca antes do\n // sobrenome chegar.\n // Seis agendas ou menos: caixinhas, que se leem de uma vez. Mais\n // que isso, o campo com retrato e busca — é o que separa a Ana\n // Caroline da Ana Luiza numa coluna de 220px.\n content: pickerProfessionals.length > 0 && pickerProfessionals.length <= INLINE_FILTER_MAX && !professionalsTruncated ? (\n <AdaptiveFilter\n options={pickerProfessionals.map((p) => ({\n value: p.id,\n // Abreviado para caber, ordenado e identificado pelo inteiro.\n label: p.name,\n avatarUrl: p.avatarUrl ?? null,\n hint: scheduledProfIds.has(p.id) ? undefined : t('agenda.sidebar.noGrid'),\n }))}\n value={selectedProfIds}\n onChange={(ids) => setFilters({ professionalIds: ids })}\n allLabel={t('agenda.sidebar.allProfessionals')}\n />\n ) : (\n <PersonMultiPicker\n // Quem trabalha NESTE período primeiro — é quem a recepção\n // procura. O resto do quadro continua listado, com a dica \"sem\n // grade\": não ter grade é problema de configuração que alguém\n // precisa ENXERGAR, e é a causa nº 1 de \"abri a agenda e não\n // apareceu nada\".\n options={pickerProfessionals.map((p) => ({\n id: p.id,\n name: p.name,\n avatarUrl: p.avatarUrl,\n hint: scheduledProfIds.has(p.id) ? undefined : t('agenda.sidebar.noGrid'),\n }))}\n value={selectedProfIds}\n onChange={(ids) => setFilters({ professionalIds: ids })}\n max={MAX_SELECTED_AGENDAS}\n allLabel={t('agenda.sidebar.allProfessionals')}\n searchPlaceholder={t('agenda.sidebar.searchAgendas')}\n // Só quando o servidor avisou que truncou. Sem isto, digitar na\n // busca filtraria apenas os nomes que couberam na primeira\n // carga e diria \"não existe\" para quem ficou de fora dela.\n onSearchChange={professionalsTruncated ? setProfSearch : undefined}\n />\n ),\n },\n {\n id: 'unit',\n title: t('agenda.sidebar.unit'),\n count: selectedLocationId ? 1 : 0,\n hidden: !config.modules.locationSelection || allLocations.size <= 1,\n content: (\n <Select\n value={selectedLocationId ?? '__all__'}\n onValueChange={(v) => setFilters({ locationId: v === '__all__' ? null : v })}\n >\n <SelectTrigger className=\"h-8 text-sm\"><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__all__\">{t('agenda.sidebar.allUnits')}</SelectItem>\n {[...allLocations].map(([id, name]) => (\n <SelectItem key={id} value={id}>{name}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n ),\n },\n {\n id: 'service',\n title: t('agenda.sidebar.service'),\n count: serviceFilter.length,\n hidden: !config.capabilities.services || serviceOptions.length === 0,\n // Três serviços agendáveis viram três caixinhas; trezentos viram\n // um campo com busca. Quem chama não escolhe a forma.\n content: (\n <AdaptiveFilter\n options={serviceOptions}\n value={serviceFilter}\n onChange={setServiceFilter}\n allLabel={t('agenda.sidebar.allServices')}\n />\n ),\n },\n {\n id: 'status',\n title: t('agenda.sidebar.status'),\n count: selectedStatuses.length,\n // Fora do ar quando nenhum tipo de reserva tem fluxo de status\n // (eventMode:'simple').\n hidden: !config.capabilities.status,\n content: (\n <StatusFilterList\n statuses={config.statuses}\n selected={selectedStatuses}\n onToggle={toggleStatus}\n />\n ),\n },\n {\n id: 'week-grouping',\n title: 'Agrupar semana por',\n // Só na SEMANA: no dia existe uma data só, e um seletor que não\n // muda nada é um seletor que ensina a desconfiar dos outros.\n hidden: !config.capabilities.professional || !currentView.endsWith('Week'),\n defaultOpen: true,\n content: (\n <SegmentedControl\n size=\"sm\"\n value={weekGrouping}\n onChange={(v: string) => prefs.set('weekGrouping', v)}\n aria-label=\"Agrupar a semana por dia ou por profissional\"\n options={[\n { value: 'day', label: 'Dia' },\n { value: 'professional', label: 'Profissional' },\n ]}\n />\n ),\n },\n {\n id: 'week-days',\n title: 'Dias da semana',\n // A choice away from the automatic one is something in force.\n count: Array.isArray(weekDaysPref) ? 1 : 0,\n hidden: !currentView.endsWith('Week') || currentView.startsWith('list'),\n defaultOpen: true,\n content: (\n <div className=\"space-y-2\">\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Dias que a semana mostra\">\n {/* Monday first, as the week is read here: S T Q Q S S D. */}\n {[1, 2, 3, 4, 5, 6, 0].map((dow) => {\n const on = shownWeekDays.includes(dow)\n const name = new Date(2024, 0, 7 + dow).toLocaleDateString(currentLocale === 'pt-BR' ? 'pt-BR' : 'en', { weekday: 'long' })\n return (\n <Button variant=\"bare\" size=\"bare\"\n key={dow}\n type=\"button\"\n aria-pressed={on}\n title={name}\n aria-label={name}\n data-testid={`week-day-${dow}`}\n onClick={() => toggleWeekDay(dow)}\n className={`font-normal whitespace-normal flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium uppercase transition-colors ${on ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground hover:text-foreground'}`}\n >\n {name.charAt(0)}\n </Button>\n )\n })}\n </div>\n {Array.isArray(weekDaysPref) && (\n <Button variant=\"bare\" size=\"bare\"\n type=\"button\"\n onClick={() => prefs.set('weekDays', 'auto')}\n className=\"font-normal whitespace-normal text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline\"\n >\n Voltar ao automático\n </Button>\n )}\n </div>\n ),\n },\n {\n id: 'hide-empty',\n title: t('agenda.sidebar.hideEmptyGrids'),\n count: hideEmptyGrids ? 1 : 0,\n hidden: !config.capabilities.professional,\n content: (\n <Switch\n size=\"sm\"\n checked={hideEmptyGrids}\n onCheckedChange={setHideEmptyGrids}\n label={<span className=\"text-xs text-muted-foreground\">{t('agenda.sidebar.hideEmptyGrids')}</span>}\n />\n ),\n },\n ]}\n />\n </AgendaRailColumn>\n\n {config.capabilities.professional && (\n <ScheduleGridDialog open={schedulesOpen} professionalId={schedulesFor} onClose={() => { setSchedulesOpen(false); setSchedulesFor(null) }} />\n )}\n\n {blockFor && (\n <BlockDialog\n open\n professionalId={blockFor.professionalId}\n date={blockFor.date}\n onClose={() => setBlockFor(null)}\n onSaved={invalidateSchedules}\n />\n )}\n\n {editingBlock && (\n <BlockDialog\n open\n editing={editingBlock}\n onClose={() => setEditingBlock(null)}\n onSaved={invalidateSchedules}\n />\n )}\n\n {/* Declaradas, em qualquer largura: a shell decide onde põem — botão e\n engrenagem no header em tela grande, FAB no telefone. Desenhadas à\n mão eram outra coisa em cada largura: um botão sólido no topo da\n coluna de filtros e uma engrenagem perdida na ponta da barra de\n visões, nenhum dos dois onde o resto do app ensinou a procurar. */}\n <PageHeaderActions>\n <PageActions\n actions={[\n {\n id: 'new-booking',\n label: t('agenda.calendar.newAppointment'),\n icon: Plus,\n intent: 'primary',\n creates: true,\n onSelect: () => openModal('create'),\n },\n {\n id: 'agenda-settings',\n label: t('agenda.settings.title'),\n icon: Settings,\n // Utility, not an alternative way to book: the shell gives it\n // its own quiet circle above the \"+\" instead of hiding it in a\n // create menu.\n intent: 'utility',\n onSelect: () => { navigateApp('/settings/agenda') },\n },\n ]}\n />\n </PageHeaderActions>\n\n {/* ═══ MAIN AREA ═══ */}\n {/* `min-h-0` junto com `min-w-0`: esta coluna é item de flex da linha de\n altura definida acima, e sem ele ela pode crescer além dela — aí o\n `flex-1` da grade lá dentro resolve contra uma altura errada e sobra\n branco embaixo do calendário. A corrente só funciona se TODO nível\n declarar que pode encolher. */}\n <div className=\"flex-1 flex flex-col min-w-0 min-h-0 overflow-hidden\">\n {/* Toolbar */}\n <div className=\"shrink-0 border-b\">\n {/* Row 1 — create + date nav + title (left), desktop switcher + settings\n (right). Extra right padding on mobile clears the transparent header's\n floating profile avatar, which otherwise overlaps the settings gear. */}\n <div className={`${mobileGridActive ? 'flex' : 'hidden'} md:flex h-12 items-center justify-between pl-4 pr-4`}>\n <div className=\"flex items-center gap-3 min-w-0\">\n {/* Date navigation drives the FullCalendar api — shown on desktop and,\n on mobile, only when a grid view is active (the list paginates\n itself, so it has no grid to page through). */}\n <div className={`${mobileGridActive ? 'flex' : 'hidden'} md:flex items-center gap-3`}>\n <Button variant=\"bare\" size=\"bare\" onClick={handleToday}\n className=\"rounded-md border px-3 py-1 text-sm font-medium hover:bg-muted bg-card shadow-button active:shadow-button-inset transition-colors\">\n {t('agenda.toolbar.today')}\n </Button>\n <div className=\"flex items-center gap-0.5\">\n <Button variant=\"bare\" size=\"bare\" onClick={handlePrev} className=\"flex h-7 w-7 items-center justify-center rounded-full hover:bg-muted transition-colors\">\n <ChevronLeft className=\"h-4 w-4\" />\n </Button>\n <Button variant=\"bare\" size=\"bare\" onClick={handleNext} className=\"flex h-7 w-7 items-center justify-center rounded-full hover:bg-muted transition-colors\">\n <ChevronRight className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n {/* On a phone the shell's page bar already says \"Agenda\"; repeating\n it here cost a line and said nothing. The date range is the one\n thing that bar cannot know, so a grid view still shows it. */}\n {!(isMobile && !mobileGridActive) && (\n <h2 className=\"truncate text-base font-normal sm:text-lg\">{calendarTitle}</h2>\n )}\n </div>\n\n <div className=\"flex items-center gap-1 shrink-0\">\n <div className=\"hidden md:flex items-center gap-1\">\n {viewOptions.map((opt) => (\n <Button variant=\"bare\" size=\"bare\" key={opt.key} onClick={() => handleViewChange(opt.key)}\n className={`font-normal rounded-md px-3 py-1 text-sm transition-colors ${\n currentView === opt.key\n ? 'bg-primary/10 text-primary font-medium'\n : 'text-muted-foreground hover:bg-muted/50'\n }`}>\n {t(opt.labelKey)}\n </Button>\n ))}\n </div>\n </div>\n </div>\n\n {/* Row 2 (mobile only) — compact segmented view switcher on its own row so\n it never collides with the floating avatar. Dia/Semana/Mês mount the\n calendar; Lista returns to the thumb-friendly agenda list. */}\n <div className=\"flex md:hidden items-center gap-1 overflow-x-auto px-3 pb-2\">\n {mobileViewOptions.map((opt) => (\n <Button variant=\"bare\" size=\"bare\" key={opt.key} onClick={() => handleMobileViewChange(opt.key)}\n aria-pressed={mobileView === opt.key}\n className={`font-normal flex min-h-[2.75rem] shrink-0 items-center rounded-full px-4 text-sm transition-colors active:scale-[0.98] ${\n mobileView === opt.key\n ? 'bg-primary/10 font-medium text-primary'\n : 'text-muted-foreground hover:bg-muted/50'\n }`}>\n {t(opt.labelKey)}\n </Button>\n ))}\n </div>\n </div>\n\n {/* Mobile list view → thumb-friendly agenda list; otherwise (desktop, or a\n mobile grid view the user switched to) → FullCalendar grid.\n\n No wrapper da grade, `min-h-0`/`min-w-0` não são enfeite: um item de\n flex nasce com `min-*: auto` e não encolhe abaixo do conteúdo.\n Enquanto ali era `overflow-hidden` o recorte escondia isso; com a\n rolagem horizontal ligada a caixa passou a CRESCER com a grade e a\n empurrar a página inteira — o vazio embaixo do calendário. */}\n {isMobile && !mobileGridActive ? (\n // The mobile branch used to sit in front of the loading check, so the\n // list rendered empty while the query ran — which on this screen reads\n // as \"nothing scheduled\", the one wrong answer it must not give.\n bookingsLoading && bookings.length === 0 ? (\n <AgendaMobileListSkeleton />\n ) : (\n <AgendaMobileList\n bookings={bookings}\n statusColors={statusColors}\n currencyCode={config.currency.code}\n onSelect={(b) => openModal('edit', { bookingId: b.id })}\n onCreate={() => openModal('create')}\n />\n )\n ) : professionalsLoading && professionals.length === 0 ? (\n <CalendarSkeleton profCount={2} />\n ) : (\n <>\n {/* AGENDA VAZIA QUASE NUNCA É AGENDA SEM CLIENTE — É AGENDA SEM GRADE.\n O V1 chama isto de \"a primeira pergunta de todo suporte\": sem grade\n nenhuma no período a tela desenhava uma semana em branco, que é a\n resposta ERRADA — diz \"não há nada marcado\" quando o que há é um\n cadastro faltando, e quem lê vai procurar cliente em vez de\n configurar horário.\n\n FAIXA e não tela cheia, que é como o V1 faz. Um período sem grade\n ainda pode ter compromisso marcado — herdado de uma vigência que\n acabou —, e trocar o calendário inteiro pela mensagem esconderia\n esses agendamentos junto com o vazio. A tela desenha o que tem e\n DIZ o que falta; o botão leva ao MESMO diálogo do \"Horários\" da\n coluna, para quem chegou aqui pelo vazio não ter de procurar. */}\n {semGradeNoPeriodo && (\n <div className=\"mx-3 mb-2 flex flex-wrap items-center gap-x-3 gap-y-1.5 rounded-lg border border-warning/40 bg-warning/10 px-3 py-2\">\n <Clock3 className=\"h-4 w-4 shrink-0 text-warning-foreground\" aria-hidden />\n <span className=\"min-w-0 flex-1 text-xs text-foreground\">\n <span className=\"font-medium\">{t('agenda.calendar.noGridTitle')}</span>\n {' — '}\n {t('agenda.calendar.noGridBody')}\n </span>\n <Button variant=\"bare\" size=\"bare\"\n type=\"button\"\n onClick={() => setSchedulesOpen(true)}\n className=\"shrink-0 rounded-button border bg-card px-2.5 py-1 text-xs font-medium shadow-button transition-all hover:bg-muted active:scale-95\"\n >\n {t('agenda.calendar.noGridCta')}\n </Button>\n </div>\n )}\n <div ref={wrapperRef} className={`min-h-0 min-w-0 flex-1 overflow-x-auto overflow-y-hidden agenda-calendar${semGradeNoPeriodo ? ' agenda-unscheduled' : ''}`}>\n {/* Em fluxo e `h-full`: tirar este filho do fluxo (`absolute`) quebra a\n medição do FullCalendar, que passa a desenhar na altura natural e\n deixa o resto do contêiner vazio. `h-full` resolve porque o pai é\n um item de flex com `min-h-0` numa coluna de altura definida —\n é o `min-h-0` que torna a altura dele definida, e sem ele nada\n nesta corrente funciona. */}\n <div className=\"h-full\" style={gridMinWidth ? { minWidth: gridMinWidth } : undefined}>\n <FullCalendar\n ref={calendarRef}\n plugins={[dayGridPlugin, timeGridPlugin, resourceTimeGridPlugin, interactionPlugin, listPlugin]}\n initialView={mobileGridActive ? mobileView : effectiveInitialView}\n initialDate={urlTarget?.date}\n schedulerLicenseKey=\"CC-Attribution-NonCommercial-NoDerivatives\"\n views={weekViewOptions}\n // COLUNA NENHUMA ENQUANTO NÃO SE SABE QUAIS SÃO.\n //\n // Desenhar com o que já chegou e corrigir depois foi o que mostrou\n // oito agendas por vinte segundos antes de virarem duas. Quem lia a\n // tela via a resposta mudar debaixo do olho — e a que apareceu\n // primeiro era a errada.\n //\n // Uma lista vazia aqui é a grade sem coluna: o esqueleto por cima\n // (ver abaixo) é que diz que ela está a caminho.\n resources={resourceCapable ? (columnsSettled ? resources : []) : undefined}\n events={events}\n headerToolbar={false}\n locale={fcLocale}\n height=\"100%\"\n slotMinTime={effectiveBusinessHours.startTime + ':00'}\n slotMaxTime={effectiveBusinessHours.endTime + ':00'}\n slotDuration={{ minutes: config.slotDuration }}\n allDaySlot={false}\n nowIndicator={true}\n editable={config.modules.dragAndDrop}\n selectable={true}\n selectMirror={true}\n eventOverlap={false}\n datesSet={handleDatesSet}\n eventDidMount={handleEventDidMount}\n eventClick={handleEventClick}\n eventMouseEnter={handleEventMouseEnter}\n eventMouseLeave={handleEventMouseLeave}\n select={handleSelect}\n dateClick={handleDateClick}\n // Google Calendar no tablet: segurar o vão já pinta a seleção e\n // soltar abre o formulário. O padrão do FullCalendar é 1s — tempo\n // demais para o gesto ler como resposta. 400ms ainda deixa o\n // deslize vertical rolar a grade em vez de selecionar.\n selectLongPressDelay={400}\n eventDrop={handleEventDrop}\n resourceLabelContent={resourceLabelContent}\n dayHeaderContent={dayHeaderContent}\n dayCellContent={dayCellContent}\n eventContent={eventContent}\n resourceOrder=\"title\"\n // Weekly grid reads DATE first, agenda second: one macro group per day,\n // the professionals nested inside it. Reading a Tuesday means one\n // block, not one column per person scattered across the week.\n datesAboveResources={weekGrouping === 'day'}\n stickyHeaderDates={true}\n expandRows={false}\n eventTimeFormat={{ hour: '2-digit', minute: '2-digit', hour12: false }}\n slotLabelFormat={{ hour: '2-digit', minute: '2-digit', hour12: false }}\n />\n </div>\n </div>\n </>\n )}\n\n {/* A LEGENDA, ao pé da grade — a mesma fileira de selos do V1.\n A coluna de filtros já mostra as cores, mas ela fica do OUTRO lado\n da tela: quem está lendo um cartão amarelo no canto direito atravessa\n a janela inteira para descobrir o que amarelo quer dizer. Aqui a\n resposta está embaixo do próprio cartão.\n Só no desktop: no telefone a lista já escreve o status por extenso\n em cada linha, e a fileira viraria duas. */}\n {config.capabilities.status && !isMobile && (\n <div className=\"hidden md:flex shrink-0 flex-wrap items-center gap-x-4 gap-y-1.5 border-t px-4 py-2\">\n {config.statuses.map((status) => (\n <span key={status.value} className=\"flex items-center gap-1.5 text-[11px] text-muted-foreground\">\n <span className=\"h-2 w-2 shrink-0 rounded-full\" style={{ backgroundColor: status.color }} />\n {status.label}\n </span>\n ))}\n </div>\n )}\n </div>\n\n {/* Popover — stays mounted until animation finishes */}\n {selectedBooking && popoverAnchor && popoverVisible && (\n <AppointmentPopover booking={selectedBooking} position={popoverAnchor}\n onClose={() => {\n // Called AFTER the popover's exit animation finishes\n setPopoverVisible(false)\n setSelectedBooking(null)\n setPopoverAnchor(null)\n }}\n onEdit={(id) => {\n setPopoverVisible(false)\n setSelectedBooking(null)\n setPopoverAnchor(null)\n openModal('edit', { bookingId: id })\n }} />\n )}\n\n {/* Context Menu */}\n {contextMenu && (\n <EventContextMenu\n booking={contextMenu.booking}\n position={{ x: contextMenu.x, y: contextMenu.y }}\n onClose={() => { setContextMenuVisible(false); setContextMenu(null) }}\n onEdit={(id) => { setContextMenuVisible(false); setContextMenu(null); openModal('edit', { bookingId: id }) }}\n />\n )}\n\n {/* No-schedule confirm */}\n <ConfirmDialog\n open={!!scheduleConfirm}\n variant=\"warning\"\n title={t('agenda.calendar.noScheduleConfirm')}\n confirmLabel={t('common.confirm')}\n cancelLabel={t('common.cancel')}\n onConfirm={() => { const cb = scheduleConfirm?.onConfirm; setScheduleConfirm(null); cb?.() }}\n onCancel={() => setScheduleConfirm(null)}\n />\n\n {/* Booking form — always mounted; it shows itself in the shell's right\n column (or a sheet, where there is no column) */}\n <AppointmentModal\n open={modalState.open}\n mode={modalState.mode}\n bookingId={modalState.bookingId}\n prefill={modalState.prefill}\n initialTab={modalState.initialTab}\n externalSource={modalState.externalSource}\n onClose={closeModal}\n onCreated={(newId, source) => {\n if (config.onBookingCreated) {\n void Promise.resolve(config.onBookingCreated({ bookingId: newId, source })).catch((error: unknown) => {\n console.error('Failed to run agenda booking-created bridge', error)\n })\n }\n // After a short delay (let calendar re-render), find the event and show popover\n setTimeout(() => {\n const booking = bookings.find((b: CalendarBooking) => b.id === newId)\n if (!booking) return\n const el = document.querySelector(`[data-booking-id=\"${newId}\"]`) as HTMLElement | null\n if (el) {\n const rect = el.getBoundingClientRect()\n const popW = 320, popH = 340\n let x = rect.right + 8\n let y = rect.top + rect.height / 2 - popH / 2\n if (x + popW > window.innerWidth - 16) x = rect.left - popW - 8\n if (y + popH > window.innerHeight - 16) y = window.innerHeight - popH - 16\n if (y < 16) y = 16\n setSelectedBooking(booking)\n setPopoverAnchor({ x, y })\n setPopoverVisible(true)\n }\n }, 400)\n }} />\n </div>\n )\n}\n","import React from 'react'\nimport { usePluginRuntimeOptional } from '@fayz-ai/core'\nimport type { StoreApi } from 'zustand/vanilla'\nimport { AgendaContextProvider } from '../context'\nimport type { ResolvedAgendaConfig } from '../config'\nimport type { AgendaDataProvider } from '../data/types'\nimport type { AgendaUIState } from '../store'\nimport { CalendarView } from './CalendarView'\nimport { setAgendaTenantId } from '../lib/tenant'\n\n// ---------------------------------------------------------------------------\n// Main page — clean single-page calendar, no module nav wrapper\n// ---------------------------------------------------------------------------\n\nexport function AgendaPage({ config, provider, store, children }: {\n config: ResolvedAgendaConfig\n provider: AgendaDataProvider\n store: StoreApi<AgendaUIState>\n /**\n * A tela que vai DENTRO do módulo. Padrão: o calendário.\n *\n * Confirmações é uma tela da agenda com rota própria, e montá-la crua — só\n * `<ConfirmationsView />` na rota — a punha fora deste provider: ela quebrava\n * na primeira linha com \"useConfig must be used within AgendaPage\", e o\n * shell trocava a tela pelo cartão de erro. Uma tela do módulo entra pela\n * porta do módulo.\n */\n children?: React.ReactNode\n}) {\n const runtime = usePluginRuntimeOptional()\n const tenantId = runtime?.context.tenant?.id\n\n React.useEffect(() => {\n setAgendaTenantId(tenantId)\n return () => setAgendaTenantId(undefined)\n }, [tenantId])\n\n return (\n <AgendaContextProvider config={config} provider={provider} store={store}>\n {/* A moldura da agenda: metade do respiro do shell, e rolagem própria.\n Cada 12px que voltam para a grade é meia coluna de profissional. */}\n <div className=\"h-full min-h-0 space-y-3 overflow-y-auto p-2 md:space-y-4 md:px-3 md:pb-3 md:pt-2\">\n {children ?? <CalendarView />}\n </div>\n </AgendaContextProvider>\n )\n}\n"]}
|