@fayz-ai/plugin-agenda 0.21.0 → 0.21.3

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/index.js CHANGED
@@ -1,10 +1,8 @@
1
1
  import { createMockAgendaProvider, createSupabasePublicBookingProvider } from './chunk-A77PUFY5.js';
2
2
  export { createMockAgendaProvider } from './chunk-A77PUFY5.js';
3
- import React22, { useState, useEffect, useRef, useMemo, useCallback, useLayoutEffect } from 'react';
3
+ import React21, { useState, useEffect, useRef, useMemo, useCallback, useLayoutEffect } from 'react';
4
4
  import { tl, recordRailFields, RECORD_GROUP, activeFacet, connectionStatus, createConnectionStore, getActiveTenantId, createSafeDataProvider, todayLocal, getSupabaseClientOptional, registerTranslations, registerMessageDefaults, getActiveUnitId, assertWrote, connectorRuntimeToken, CONNECTOR_RUNTIME_TOKEN_HEADER, emitDataChanged, globalCache, usePluginRuntimeOptional, useTranslation, useActiveUnitId, emitDomainEvent, getCurrentLocale, localDateKey, useDataChanged, formatCurrency, resolveDataProvider } from '@fayz-ai/core';
5
- import { createPluginContext, fayzConnectorOAuth, setScheduleBlockConfig, getScheduleBlockConfig, registerPersonActions, UNIT_DETAIL_ZONES, PluginSettingsPanel, createArchetypeLookup, dedup, adminNavigateTo, usePluginPrefs, useTenantPluginSettings, SettingsGroup, ToggleRow, SelectRow, PermissionGate, PersonLink, PageActions, useRightRailStore, usePermissionOptional, ScheduleEditor, useLimitGuard, useLookupCreate, CrudFormPage, CrudDetailPage, ContactPicker, openEntity, PaymentStatusBadge as PaymentStatusBadge$1, RightRailPage, invalidateLimit } from '@fayz-ai/admin';
6
- import { toast, Card, CardHeader, CardTitle, CardDescription, CardContent, Skeleton, Switch, Input, Button, FilterRail, AdaptiveFilter, FilterCheckRow, TooltipProvider, ModulePage, Avatar, AvatarImage, AvatarFallback, Badge, Checkbox, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, PersonAvatar, abbreviatePersonName, INLINE_FILTER_MAX, PersonMultiPicker, SegmentedControl, MiniCalendar, PageHeaderActions, ConfirmDialog, RailWorkspace, Tooltip, TooltipTrigger, TooltipContent, SubpageHeader, ModalTask, Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, PersonPicker, Tabs, TabsList, TabsTrigger, DatePicker, TimePicker, ModalFooter, ModalTaskHost, SearchCombobox, ModalTaskHeader, Dropdown, DropdownTrigger, DropdownContent, DropdownItem, cn, normalizePhone, DotBadge } from '@fayz-ai/ui';
7
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
+ import { createPluginContext, fayzConnectorOAuth, UNIT_DETAIL_ZONES, setScheduleBlockConfig, getScheduleBlockConfig, registerPersonActions, PluginSettingsPanel, adminNavigateTo, createArchetypeLookup, dedup, usePluginPrefs, useTenantPluginSettings, SettingsGroup, ToggleRow, SelectRow, PermissionGate, PersonLink, PageActions, useRightRailStore, usePermissionOptional, ScheduleEditor, useLimitGuard, useLookupCreate, CrudFormPage, CrudDetailPage, ContactPicker, openEntity, PaymentStatusBadge as PaymentStatusBadge$1, RightRailPage, invalidateLimit } from '@fayz-ai/admin';
8
6
  import FullCalendar from '@fullcalendar/react';
9
7
  import dayGridPlugin from '@fullcalendar/daygrid';
10
8
  import timeGridPlugin from '@fullcalendar/timegrid';
@@ -13,109 +11,13 @@ import interactionPlugin from '@fullcalendar/interaction';
13
11
  import listPlugin from '@fullcalendar/list';
14
12
  import ptBrLocale from '@fullcalendar/core/locales/pt-br';
15
13
  import { CheckCircle, Stethoscope, RotateCcw, Check, CircleDashed, Layers, Users, Activity, RefreshCw, Clock3, CalendarPlus, Loader2, AlertCircle, X, CheckCircle2, Ban, Plus, Settings, ChevronLeft, ChevronRight, ChevronDown, CircleDollarSign, LogIn, CalendarDays, Play, UserRound, Package, Clock, Mic, MapPin, CalendarX, UserX, Search, CalendarOff, Pencil, Trash2, User, FileText, AlertTriangle, DollarSign, HandCoins, CheckSquare, Calendar, History, ExternalLink, DoorOpen, Briefcase, CircleDot, MessageCircle, Phone, AlarmClock, ArrowLeft, Link2, Receipt, ClipboardCheck, FileCheck, ArrowRightLeft, CreditCard, QrCode, Banknote, Sparkles } from 'lucide-react';
14
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent, Skeleton, Switch, Input, Button, toast, FilterRail, AdaptiveFilter, FilterCheckRow, TooltipProvider, ModulePage, Avatar, AvatarImage, AvatarFallback, Badge, Checkbox, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, PersonAvatar, abbreviatePersonName, INLINE_FILTER_MAX, PersonMultiPicker, SegmentedControl, MiniCalendar, PageHeaderActions, ConfirmDialog, RailWorkspace, Tooltip, TooltipTrigger, TooltipContent, SubpageHeader, ModalTask, Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, PersonPicker, Tabs, TabsList, TabsTrigger, DatePicker, TimePicker, ModalFooter, ModalTaskHost, SearchCombobox, ModalTaskHeader, Dropdown, DropdownTrigger, DropdownContent, DropdownItem, cn, normalizePhone, DotBadge } from '@fayz-ai/ui';
15
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
16
16
  import { createPortal } from 'react-dom';
17
17
  import { FormFillDialog, PersonFormsAlert } from '@fayz-ai/plugin-forms';
18
18
  import { ClientAccountModal, ClientAccountInline } from '@fayz-ai/plugin-financial';
19
19
  import { createStore } from 'zustand/vanilla';
20
20
 
21
- function UnitTurnQueueWidget({ item }) {
22
- const unitId = item?.id;
23
- const [row, setRow] = React22.useState(null);
24
- const [loading, setLoading] = React22.useState(true);
25
- const [saving, setSaving] = React22.useState(false);
26
- const [radius, setRadius] = React22.useState("80");
27
- React22.useEffect(() => {
28
- if (!unitId) return;
29
- let alive = true;
30
- const supabase = getSupabaseClientOptional();
31
- void supabase?.from("plg_agenda_turn_queues").select("is_active, geofence_required, geofence_radius_meters").eq("unit_id", unitId).eq("queue_key", "walk_in").maybeSingle().then(({ data }) => {
32
- if (!alive) return;
33
- const next = data ?? { is_active: false, geofence_required: true, geofence_radius_meters: 80 };
34
- setRow(next);
35
- setRadius(String(next.geofence_radius_meters));
36
- setLoading(false);
37
- });
38
- return () => {
39
- alive = false;
40
- };
41
- }, [unitId]);
42
- const save = async (patch) => {
43
- if (!unitId || !row) return;
44
- const next = { ...row, ...patch };
45
- setSaving(true);
46
- const supabase = getSupabaseClientOptional();
47
- const { data, error } = await supabase.rpc("agenda_turn_queue_configure", {
48
- p_unit_id: unitId,
49
- p_enabled: next.is_active,
50
- p_geofence_required: next.geofence_required,
51
- p_radius_meters: next.geofence_radius_meters
52
- });
53
- setSaving(false);
54
- if (error) {
55
- toast.error("N\xE3o foi poss\xEDvel salvar a lista da vez", { description: error.message });
56
- return;
57
- }
58
- setRow({ is_active: data.is_active, geofence_required: data.geofence_required, geofence_radius_meters: data.geofence_radius_meters });
59
- toast.success("Lista da vez salva");
60
- };
61
- const radiusNumber = Number(radius);
62
- const radiusInvalid = !Number.isInteger(radiusNumber) || radiusNumber < 10 || radiusNumber > 1e3;
63
- const hasCoordinate = item?.latitude != null && item?.longitude != null;
64
- return /* @__PURE__ */ jsxs(Card, { children: [
65
- /* @__PURE__ */ jsxs(CardHeader, { children: [
66
- /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: "Lista da vez" }),
67
- /* @__PURE__ */ jsx(CardDescription, { children: "Fila de atendimento por ordem de chegada. Desligada, o item some do menu e o bot\xE3o de disponibilidade some do topo." })
68
- ] }),
69
- /* @__PURE__ */ jsx(CardContent, { className: "space-y-4", children: loading || !row ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
70
- /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" }),
71
- /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" })
72
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
73
- /* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-4 rounded-md border border-input bg-background px-3 py-2.5", children: [
74
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Ativar lista da vez nesta unidade" }),
75
- /* @__PURE__ */ jsx(Switch, { checked: row.is_active, disabled: saving, onCheckedChange: (v) => void save({ is_active: v }) })
76
- ] }),
77
- /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
78
- /* @__PURE__ */ jsxs("div", { children: [
79
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Localiza\xE7\xE3o da lista da vez" }),
80
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Valida o bot\xE3o \u201Cestou dispon\xEDvel\u201D dos profissionais pela dist\xE2ncia at\xE9 a unidade." })
81
- ] }),
82
- /* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-4 rounded-md border border-input bg-background px-3 py-2.5", children: [
83
- /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Exigir que o profissional esteja na unidade" }),
84
- /* @__PURE__ */ jsx(Switch, { checked: row.geofence_required, disabled: saving, onCheckedChange: (v) => void save({ geofence_required: v }) })
85
- ] }),
86
- /* @__PURE__ */ jsx("div", { className: "fz-container", children: /* @__PURE__ */ jsxs("div", { className: "fz-fields fz-fields-2 gap-4", children: [
87
- /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
88
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Coordenada" }),
89
- /* @__PURE__ */ jsx("p", { className: "flex h-10 items-center rounded-md border border-input bg-muted/40 px-3 text-sm tabular-nums text-muted-foreground", children: hasCoordinate ? `${Number(item.latitude).toFixed(6)}, ${Number(item.longitude).toFixed(6)}` : "Sem coordenada \u2014 preencha o endere\xE7o" }),
90
- /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
91
- "Vem do endere\xE7o da unidade.",
92
- " ",
93
- /* @__PURE__ */ jsx("button", { type: "button", className: "underline decoration-dashed underline-offset-2", onClick: () => adminNavigateTo(`/settings/locations/${item?.id}/edit`), children: "Editar endere\xE7o" })
94
- ] })
95
- ] }),
96
- /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
97
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Raio (m)" }),
98
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
99
- /* @__PURE__ */ jsx(Input, { type: "number", min: 10, max: 1e3, value: radius, onChange: (e) => setRadius(e.target.value), className: "tabular-nums" }),
100
- /* @__PURE__ */ jsx(
101
- Button,
102
- {
103
- variant: "outline",
104
- disabled: saving || radiusInvalid || radiusNumber === row.geofence_radius_meters,
105
- onClick: () => void save({ geofence_radius_meters: radiusNumber }),
106
- children: "Salvar"
107
- }
108
- )
109
- ] }),
110
- radiusInvalid && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: "Use um raio entre 10 e 1000 metros." })
111
- ] })
112
- ] }) }),
113
- row.geofence_required && !hasCoordinate && row.is_active && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: "Sem coordenada no endere\xE7o, ningu\xE9m consegue marcar \u201Cestou dispon\xEDvel\u201D nesta unidade." })
114
- ] })
115
- ] }) })
116
- ] });
117
- }
118
-
119
21
  // src/lib/message-events.ts
120
22
  var BOOKING_FIELDS = [
121
23
  { name: "customer_name", label: "Cliente", type: "string", example: "Maria Silva" },
@@ -859,20 +761,20 @@ function BlockDialog({
859
761
  }) {
860
762
  const professionals = useAgendaStore((s) => s.agendaProfessionals);
861
763
  const provider2 = useAgendaProvider();
862
- const [assigneeId, setAssigneeId] = React22.useState(prefillProfessional ?? "");
863
- const [title, setTitle] = React22.useState("");
864
- const [description, setDescription] = React22.useState("");
865
- const [mode, setMode] = React22.useState("single");
866
- const [specificDate, setSpecificDate] = React22.useState(date ?? hoje());
867
- const [allDay, setAllDay] = React22.useState(false);
868
- const [startsAt, setStartsAt] = React22.useState("12:00");
869
- const [endsAt, setEndsAt] = React22.useState("13:00");
870
- const [days2, setDays] = React22.useState([]);
871
- const [validFrom, setValidFrom] = React22.useState(date ?? hoje());
872
- const [validTo, setValidTo] = React22.useState("");
873
- const [weekInterval, setWeekInterval] = React22.useState("0");
874
- const [saving, setSaving] = React22.useState(false);
875
- React22.useEffect(() => {
764
+ const [assigneeId, setAssigneeId] = React21.useState(prefillProfessional ?? "");
765
+ const [title, setTitle] = React21.useState("");
766
+ const [description, setDescription] = React21.useState("");
767
+ const [mode, setMode] = React21.useState("single");
768
+ const [specificDate, setSpecificDate] = React21.useState(date ?? hoje());
769
+ const [allDay, setAllDay] = React21.useState(false);
770
+ const [startsAt, setStartsAt] = React21.useState("12:00");
771
+ const [endsAt, setEndsAt] = React21.useState("13:00");
772
+ const [days2, setDays] = React21.useState([]);
773
+ const [validFrom, setValidFrom] = React21.useState(date ?? hoje());
774
+ const [validTo, setValidTo] = React21.useState("");
775
+ const [weekInterval, setWeekInterval] = React21.useState("0");
776
+ const [saving, setSaving] = React21.useState(false);
777
+ React21.useEffect(() => {
876
778
  if (!open) return;
877
779
  if (editing) {
878
780
  setAssigneeId(editing.assigneeId);
@@ -1062,10 +964,10 @@ function BlockDialog({
1062
964
  }
1063
965
  function LostSlotsCard({ range, selectedStatuses, onPick }) {
1064
966
  const provider2 = useAgendaProvider();
1065
- const [counts, setCounts] = React22.useState(null);
1066
- const [falhou, setFalhou] = React22.useState(false);
967
+ const [counts, setCounts] = React21.useState(null);
968
+ const [falhou, setFalhou] = React21.useState(false);
1067
969
  const key = range ? `${range.start}|${range.end}` : null;
1068
- React22.useEffect(() => {
970
+ React21.useEffect(() => {
1069
971
  if (!range || !provider2.getLostCounts) {
1070
972
  setCounts(null);
1071
973
  return;
@@ -1122,14 +1024,14 @@ function ScheduleGridDialog({ open, onClose, professionalId }) {
1122
1024
  const t2 = useTranslation();
1123
1025
  const professionals = useAgendaStore((s) => s.professionals);
1124
1026
  const invalidateSchedules2 = useAgendaStore((s) => s.invalidateSchedules);
1125
- const [search, setSearch] = React22.useState("");
1126
- const [selectedId, setSelectedId] = React22.useState(null);
1127
- React22.useEffect(() => {
1027
+ const [search, setSearch] = React21.useState("");
1028
+ const [selectedId, setSelectedId] = React21.useState(null);
1029
+ React21.useEffect(() => {
1128
1030
  if (!open) return;
1129
1031
  setSelectedId((current) => professionalId ?? current ?? professionals[0]?.id ?? null);
1130
1032
  }, [open, professionalId, professionals]);
1131
- const selectedRef = React22.useRef(null);
1132
- React22.useEffect(() => {
1033
+ const selectedRef = React21.useRef(null);
1034
+ React21.useEffect(() => {
1133
1035
  if (!open || !selectedId) return;
1134
1036
  const id = window.setTimeout(() => {
1135
1037
  selectedRef.current?.scrollIntoView({ block: "nearest" });
@@ -1793,9 +1695,9 @@ function ClientHistoryPanel({ clientId, currentBookingId, formatCurrency: format
1793
1695
  const t2 = useTranslation();
1794
1696
  const config = useAgendaConfig();
1795
1697
  const provider2 = useAgendaProvider();
1796
- const [bookings, setBookings] = React22.useState(null);
1797
- const [failed, setFailed] = React22.useState(false);
1798
- React22.useEffect(() => {
1698
+ const [bookings, setBookings] = React21.useState(null);
1699
+ const [failed, setFailed] = React21.useState(false);
1700
+ React21.useEffect(() => {
1799
1701
  let alive = true;
1800
1702
  if (!provider2.getClientHistory) {
1801
1703
  setBookings([]);
@@ -1847,13 +1749,13 @@ function ClientHistoryPanel({ clientId, currentBookingId, formatCurrency: format
1847
1749
  }
1848
1750
  function BookingInterestsPanel({ clientId, bookingId, value, onChange }) {
1849
1751
  const provider2 = useAgendaProvider();
1850
- const [crmInterests, setCrmInterests] = React22.useState([]);
1851
- const [term, setTerm] = React22.useState("");
1852
- const [options, setOptions] = React22.useState([]);
1853
- const initializedFor = React22.useRef(null);
1854
- const onChangeRef = React22.useRef(onChange);
1752
+ const [crmInterests, setCrmInterests] = React21.useState([]);
1753
+ const [term, setTerm] = React21.useState("");
1754
+ const [options, setOptions] = React21.useState([]);
1755
+ const initializedFor = React21.useRef(null);
1756
+ const onChangeRef = React21.useRef(onChange);
1855
1757
  onChangeRef.current = onChange;
1856
- React22.useEffect(() => {
1758
+ React21.useEffect(() => {
1857
1759
  if (!clientId) {
1858
1760
  setCrmInterests([]);
1859
1761
  initializedFor.current = null;
@@ -1886,7 +1788,7 @@ function BookingInterestsPanel({ clientId, bookingId, value, onChange }) {
1886
1788
  vivo = false;
1887
1789
  };
1888
1790
  }, [clientId, bookingId, provider2]);
1889
- React22.useEffect(() => {
1791
+ React21.useEffect(() => {
1890
1792
  if (!term.trim()) {
1891
1793
  setOptions([]);
1892
1794
  return;
@@ -2241,13 +2143,13 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
2241
2143
  const [markingWaiting, setMarkingWaiting] = useState(false);
2242
2144
  const [preenchendoForm, setPreenchendoForm] = useState(null);
2243
2145
  const [formsVersao, setFormsVersao] = useState(0);
2244
- const professionalOptions = React22.useMemo(() => {
2146
+ const professionalOptions = React21.useMemo(() => {
2245
2147
  const doLocal = professionalsForLocation(professionals, locationId, professionalId);
2246
2148
  if (!professionalId || doLocal.some((p) => p.id === professionalId)) return doLocal;
2247
2149
  const nome = loadedBookings.find((b) => b.id === bookingId)?.professionalName;
2248
2150
  return [...doLocal, { id: professionalId, name: nome ?? "\u2014", avatarUrl: null }];
2249
2151
  }, [professionals, professionalId, locationId, loadedBookings, bookingId]);
2250
- React22.useEffect(() => {
2152
+ React21.useEffect(() => {
2251
2153
  const fora = shouldClearProfessional(professionals, locationId, professionalId);
2252
2154
  if (!fora) return;
2253
2155
  setProfessionalId("");
@@ -2553,7 +2455,7 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
2553
2455
  setCheckingSeries(false);
2554
2456
  };
2555
2457
  }, [open, seriesDates, professionalId, startTime, totalDuration, bookingId, activeUnitId, provider2]);
2556
- const [feriado, setFeriado] = React22.useState(null);
2458
+ const [feriado, setFeriado] = React21.useState(null);
2557
2459
  useEffect(() => {
2558
2460
  if (!open || !date || !provider2.getHolidays) {
2559
2461
  setFeriado(null);
@@ -4325,9 +4227,9 @@ function CalendarView() {
4325
4227
  const [serviceFilter, setServiceFilter] = useState([]);
4326
4228
  const [hideEmptyGrids, setHideEmptyGrids] = useState(false);
4327
4229
  const [schedulesOpen, setSchedulesOpen] = useState(false);
4328
- const [blockFor, setBlockFor] = React22.useState(null);
4329
- const [schedulesFor, setSchedulesFor] = React22.useState(null);
4330
- const [editingBlock, setEditingBlock] = React22.useState(null);
4230
+ const [blockFor, setBlockFor] = React21.useState(null);
4231
+ const [schedulesFor, setSchedulesFor] = React21.useState(null);
4232
+ const [editingBlock, setEditingBlock] = React21.useState(null);
4331
4233
  const isMobile = useIsMobile();
4332
4234
  const resourceCapable = professionals.length > 0;
4333
4235
  const viewOptions = resourceCapable ? RESOURCE_VIEW_OPTIONS : PLAIN_VIEW_OPTIONS;
@@ -5670,7 +5572,7 @@ function getAgendaTenantId() {
5670
5572
  function AgendaPage({ config, provider: provider2, store, children }) {
5671
5573
  const runtime = usePluginRuntimeOptional();
5672
5574
  const tenantId = runtime?.context.tenant?.id;
5673
- React22.useEffect(() => {
5575
+ React21.useEffect(() => {
5674
5576
  setAgendaTenantId(tenantId);
5675
5577
  return () => setAgendaTenantId(void 0);
5676
5578
  }, [tenantId]);
@@ -5686,10 +5588,10 @@ function CheckinDialog({
5686
5588
  onClose,
5687
5589
  formatCurrency: formatCurrency2 = brl
5688
5590
  }) {
5689
- const [busy, setBusy] = React22.useState(false);
5690
- const [preenchendo, setPreenchendo] = React22.useState(null);
5691
- const [preenchidos, setPreenchidos] = React22.useState(0);
5692
- const [pendencias, setPendencias] = React22.useState([]);
5591
+ const [busy, setBusy] = React21.useState(false);
5592
+ const [preenchendo, setPreenchendo] = React21.useState(null);
5593
+ const [preenchidos, setPreenchidos] = React21.useState(0);
5594
+ const [pendencias, setPendencias] = React21.useState([]);
5693
5595
  const blocking = requirements.filter((r) => r.blocking);
5694
5596
  const paid = booking.paymentStatus === "paid";
5695
5597
  const hasBill = !!booking.paymentStatus && booking.paymentStatus !== "none";
@@ -5799,7 +5701,7 @@ function CheckinDialog({
5799
5701
  }
5800
5702
  function PaymentStatusBadge(props) {
5801
5703
  const t2 = useTranslation();
5802
- const labels = React22.useMemo(() => ({
5704
+ const labels = React21.useMemo(() => ({
5803
5705
  none: t2("agenda.payment.title"),
5804
5706
  pending: t2("agenda.payment.pending"),
5805
5707
  partial: t2("agenda.payment.partial"),
@@ -5959,7 +5861,7 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
5959
5861
  const config = useAgendaConfig();
5960
5862
  const provider2 = useAgendaProvider();
5961
5863
  const statusLabel = (v) => config.statuses.find((x) => x.value === v)?.label ?? v;
5962
- const checkinStatuses = React22.useMemo(
5864
+ const checkinStatuses = React21.useMemo(
5963
5865
  () => CHECKIN_STATUSES.map((v) => config.statuses.find((x) => x.value === v)).filter((x) => !!x),
5964
5866
  [config.statuses]
5965
5867
  );
@@ -5967,14 +5869,14 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
5967
5869
  const loading = useAgendaStore((s) => s.bookingsLoading);
5968
5870
  const fetchBookings = useAgendaStore((s) => s.fetchBookings);
5969
5871
  const updateBookingStatus = useAgendaStore((s) => s.updateBookingStatus);
5970
- const [term, setTerm] = React22.useState("");
5971
- const [busyId, setBusyId] = React22.useState(null);
5972
- const [myPersonId, setMyPersonId] = React22.useState(void 0);
5973
- const [startRefusal, setStartRefusal] = React22.useState(null);
5974
- const [checkouts, setCheckouts] = React22.useState([]);
5975
- const [conferindo, setConferindo] = React22.useState(null);
5976
- const [checkoutRefusal, setCheckoutRefusal] = React22.useState(null);
5977
- const [panel, setPanel] = React22.useState(null);
5872
+ const [term, setTerm] = React21.useState("");
5873
+ const [busyId, setBusyId] = React21.useState(null);
5874
+ const [myPersonId, setMyPersonId] = React21.useState(void 0);
5875
+ const [startRefusal, setStartRefusal] = React21.useState(null);
5876
+ const [checkouts, setCheckouts] = React21.useState([]);
5877
+ const [conferindo, setConferindo] = React21.useState(null);
5878
+ const [checkoutRefusal, setCheckoutRefusal] = React21.useState(null);
5879
+ const [panel, setPanel] = React21.useState(null);
5978
5880
  const reviewing = panel?.kind === "review" ? panel.booking : null;
5979
5881
  const editing = panel?.kind === "edit" ? panel.booking : null;
5980
5882
  const charging = panel?.kind === "charge" ? panel.booking : null;
@@ -5983,17 +5885,17 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
5983
5885
  const setCharging = (b) => setPanel(b ? { kind: "charge", booking: b } : null);
5984
5886
  const can = usePermissionOptional();
5985
5887
  const canReceive = can("financial", "create") || can("financial.receivables", "create");
5986
- React22.useEffect(() => {
5888
+ React21.useEffect(() => {
5987
5889
  void fetchBookings(todayRange(), [...CHECKIN_STATUSES]);
5988
5890
  }, [fetchBookings]);
5989
- const [shownStatuses, setShownStatuses] = React22.useState([]);
5990
- const [shownPros, setShownPros] = React22.useState([]);
5991
- const prosToday = React22.useMemo(() => {
5891
+ const [shownStatuses, setShownStatuses] = React21.useState([]);
5892
+ const [shownPros, setShownPros] = React21.useState([]);
5893
+ const prosToday = React21.useMemo(() => {
5992
5894
  const seen = /* @__PURE__ */ new Map();
5993
5895
  for (const b of bookings) if (b.professionalName) seen.set(b.professionalName, b.professionalName);
5994
5896
  return [...seen.keys()].sort();
5995
5897
  }, [bookings]);
5996
- const cards = React22.useMemo(() => {
5898
+ const cards = React21.useMemo(() => {
5997
5899
  const q = term.trim().toLowerCase();
5998
5900
  return bookings.filter((b) => !shownStatuses.length || shownStatuses.includes(b.status)).filter((b) => !shownPros.length || b.professionalName && shownPros.includes(b.professionalName)).filter((b) => !q || (b.clientName ?? "").toLowerCase().includes(q) || (b.professionalName ?? "").toLowerCase().includes(q)).sort((a, b) => a.startsAt.localeCompare(b.startsAt));
5999
5901
  }, [bookings, term, shownStatuses, shownPros]);
@@ -6006,8 +5908,8 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
6006
5908
  return out;
6007
5909
  }
6008
5910
  const money = (n) => n.toLocaleString("pt-BR", { style: "currency", currency: "BRL" });
6009
- const [lost, setLost] = React22.useState({ cancelled: 0, noShow: 0 });
6010
- React22.useEffect(() => {
5911
+ const [lost, setLost] = React21.useState({ cancelled: 0, noShow: 0 });
5912
+ React21.useEffect(() => {
6011
5913
  if (!provider2.getLostCounts) return;
6012
5914
  let cancelado = false;
6013
5915
  provider2.getLostCounts(todayRange()).then((c) => {
@@ -6018,7 +5920,7 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
6018
5920
  cancelado = true;
6019
5921
  };
6020
5922
  }, [provider2]);
6021
- const openAmount = React22.useMemo(
5923
+ const openAmount = React21.useMemo(
6022
5924
  () => bookings.filter((b) => b.orderTotal && b.paymentStatus && b.paymentStatus !== "paid").reduce((soma, b) => soma + (b.orderTotal ?? 0), 0),
6023
5925
  [bookings]
6024
5926
  );
@@ -6030,7 +5932,7 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
6030
5932
  amount: m.paidAmount
6031
5933
  }));
6032
5934
  }
6033
- React22.useEffect(() => {
5935
+ React21.useEffect(() => {
6034
5936
  let vivo = true;
6035
5937
  (async () => {
6036
5938
  try {
@@ -6044,17 +5946,17 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
6044
5946
  vivo = false;
6045
5947
  };
6046
5948
  }, []);
6047
- const recarregarCheckouts = React22.useCallback(async () => {
5949
+ const recarregarCheckouts = React21.useCallback(async () => {
6048
5950
  try {
6049
5951
  setCheckouts(await provider2.getPendingCheckouts?.() ?? []);
6050
5952
  } catch {
6051
5953
  setCheckouts([]);
6052
5954
  }
6053
5955
  }, []);
6054
- React22.useEffect(() => {
5956
+ React21.useEffect(() => {
6055
5957
  void recarregarCheckouts();
6056
5958
  }, [recarregarCheckouts]);
6057
- React22.useEffect(() => {
5959
+ React21.useEffect(() => {
6058
5960
  const parar = provider2.subscribeToBookingChanges?.(() => {
6059
5961
  void recarregarCheckouts();
6060
5962
  void fetchBookings(todayRange(), [...CHECKIN_STATUSES]);
@@ -6437,7 +6339,7 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
6437
6339
  function CheckinPage({ config, provider: provider2, store, onReceive, onOpenBooking }) {
6438
6340
  const runtime = usePluginRuntimeOptional();
6439
6341
  const tenantId = runtime?.context.tenant?.id;
6440
- React22.useEffect(() => {
6342
+ React21.useEffect(() => {
6441
6343
  setAgendaTenantId(tenantId);
6442
6344
  return () => setAgendaTenantId(void 0);
6443
6345
  }, [tenantId]);
@@ -6450,11 +6352,11 @@ function hoje2() {
6450
6352
  }
6451
6353
  function PersonAttendanceBlock({ personId }) {
6452
6354
  const provider2 = useAgendaProvider();
6453
- const [pessoa, setPessoa] = React22.useState(void 0);
6454
- const [booking, setBooking] = React22.useState(null);
6455
- const [indo, setIndo] = React22.useState(false);
6456
- const [recusa, setRecusa] = React22.useState(null);
6457
- React22.useEffect(() => {
6355
+ const [pessoa, setPessoa] = React21.useState(void 0);
6356
+ const [booking, setBooking] = React21.useState(null);
6357
+ const [indo, setIndo] = React21.useState(false);
6358
+ const [recusa, setRecusa] = React21.useState(null);
6359
+ React21.useEffect(() => {
6458
6360
  let vivo = true;
6459
6361
  (async () => {
6460
6362
  const eu = await provider2.getCurrentPersonId?.() ?? null;
@@ -8915,16 +8817,16 @@ function TarefaPane({ titulo, aoVoltar, children }) {
8915
8817
  }
8916
8818
  function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }) {
8917
8819
  const provider2 = useAgendaProvider();
8918
- const [versao, setVersao] = React22.useState(0);
8919
- const [statusLocal, setStatusLocal] = React22.useState(booking.status);
8920
- React22.useEffect(() => {
8820
+ const [versao, setVersao] = React21.useState(0);
8821
+ const [statusLocal, setStatusLocal] = React21.useState(booking.status);
8822
+ React21.useEffect(() => {
8921
8823
  setStatusLocal(booking.status);
8922
8824
  }, [booking.id, booking.status]);
8923
8825
  const emCurso = statusLocal === "in_progress";
8924
8826
  const naoIniciado = statusLocal === "scheduled" || statusLocal === "confirmed" || statusLocal === "waiting";
8925
8827
  const somenteLeitura = !emCurso;
8926
- const [eu, setEu] = React22.useState(void 0);
8927
- React22.useEffect(() => {
8828
+ const [eu, setEu] = React21.useState(void 0);
8829
+ React21.useEffect(() => {
8928
8830
  if (!naoIniciado) return;
8929
8831
  let vivo = true;
8930
8832
  (async () => {
@@ -8935,31 +8837,31 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
8935
8837
  vivo = false;
8936
8838
  };
8937
8839
  }, [naoIniciado, provider2]);
8938
- const [iniciando, setIniciando] = React22.useState(false);
8939
- const [recusaInicio, setRecusaInicio] = React22.useState(null);
8940
- const [rows, setRows] = React22.useState(null);
8941
- const [record, setRecord] = React22.useState(null);
8942
- const [erro, setErro] = React22.useState(null);
8943
- const [contratando, setContratando] = React22.useState(false);
8944
- const [servicos, setServicos] = React22.useState([]);
8945
- const [marcados, setMarcados] = React22.useState({});
8946
- const [salvando, setSalvando] = React22.useState(false);
8947
- const [confirmando, setConfirmando] = React22.useState(null);
8948
- const [encerrando, setEncerrando] = React22.useState(false);
8949
- const [avisoFinal, setAvisoFinal] = React22.useState(null);
8950
- const [preenchendo, setPreenchendo] = React22.useState(null);
8951
- const [avaliando, setAvaliando] = React22.useState(false);
8952
- const [lancando, setLancando] = React22.useState(null);
8953
- const [executando, setExecutando] = React22.useState(null);
8954
- const [vinculando, setVinculando] = React22.useState(null);
8955
- const [candidatos, setCandidatos] = React22.useState(null);
8956
- const [buscaInsumo, setBuscaInsumo] = React22.useState("");
8957
- const [insumos, setInsumos] = React22.useState([]);
8958
- const [usados, setUsados] = React22.useState([]);
8959
- const [busca, setBusca] = React22.useState("");
8960
- const [catalogo, setCatalogo] = React22.useState([]);
8961
- const [indicados, setIndicados] = React22.useState([]);
8962
- React22.useEffect(() => {
8840
+ const [iniciando, setIniciando] = React21.useState(false);
8841
+ const [recusaInicio, setRecusaInicio] = React21.useState(null);
8842
+ const [rows, setRows] = React21.useState(null);
8843
+ const [record, setRecord] = React21.useState(null);
8844
+ const [erro, setErro] = React21.useState(null);
8845
+ const [contratando, setContratando] = React21.useState(false);
8846
+ const [servicos, setServicos] = React21.useState([]);
8847
+ const [marcados, setMarcados] = React21.useState({});
8848
+ const [salvando, setSalvando] = React21.useState(false);
8849
+ const [confirmando, setConfirmando] = React21.useState(null);
8850
+ const [encerrando, setEncerrando] = React21.useState(false);
8851
+ const [avisoFinal, setAvisoFinal] = React21.useState(null);
8852
+ const [preenchendo, setPreenchendo] = React21.useState(null);
8853
+ const [avaliando, setAvaliando] = React21.useState(false);
8854
+ const [lancando, setLancando] = React21.useState(null);
8855
+ const [executando, setExecutando] = React21.useState(null);
8856
+ const [vinculando, setVinculando] = React21.useState(null);
8857
+ const [candidatos, setCandidatos] = React21.useState(null);
8858
+ const [buscaInsumo, setBuscaInsumo] = React21.useState("");
8859
+ const [insumos, setInsumos] = React21.useState([]);
8860
+ const [usados, setUsados] = React21.useState([]);
8861
+ const [busca, setBusca] = React21.useState("");
8862
+ const [catalogo, setCatalogo] = React21.useState([]);
8863
+ const [indicados, setIndicados] = React21.useState([]);
8864
+ React21.useEffect(() => {
8963
8865
  if (!open) return;
8964
8866
  let vivo = true;
8965
8867
  (async () => {
@@ -9016,7 +8918,7 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
9016
8918
  const d = ORDEM.indexOf(a.kind) - ORDEM.indexOf(b.kind);
9017
8919
  return d !== 0 ? d : a.id.localeCompare(b.id);
9018
8920
  };
9019
- const doAtendimento = React22.useMemo(() => {
8921
+ const doAtendimento = React21.useMemo(() => {
9020
8922
  const m = /* @__PURE__ */ new Map();
9021
8923
  for (const r of (rows ?? []).filter((x) => x.scope === "attendance")) {
9022
8924
  const k = `${r.kind}:${r.refId ?? ""}`;
@@ -9029,7 +8931,7 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
9029
8931
  }
9030
8932
  return [...m.values()].sort(porOrdem);
9031
8933
  }, [rows]);
9032
- const porServico = React22.useMemo(() => {
8934
+ const porServico = React21.useMemo(() => {
9033
8935
  const m = /* @__PURE__ */ new Map();
9034
8936
  for (const r of rows ?? []) {
9035
8937
  if (r.scope === "attendance") continue;
@@ -9054,7 +8956,7 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
9054
8956
  }, [rows]);
9055
8957
  const faltaParaTerminar = (rows ?? []).filter((r) => r.blocksFinish && r.status === "pending");
9056
8958
  const tarefaAberta = Boolean(vinculando || executando || lancando || avaliando || confirmando || contratando || preenchendo?.refId && booking.clientId);
9057
- React22.useEffect(() => {
8959
+ React21.useEffect(() => {
9058
8960
  if (!avaliando) return;
9059
8961
  let vivo = true;
9060
8962
  const t2 = setTimeout(async () => {
@@ -9070,7 +8972,7 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
9070
8972
  clearTimeout(t2);
9071
8973
  };
9072
8974
  }, [avaliando, busca]);
9073
- React22.useEffect(() => {
8975
+ React21.useEffect(() => {
9074
8976
  if (!lancando) return;
9075
8977
  let vivo = true;
9076
8978
  const t2 = setTimeout(async () => {
@@ -9094,7 +8996,7 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
9094
8996
  return [...xs, ...kit.filter((k) => !tem.has(k.productId)).map((k) => ({ productId: k.productId, name: k.name, qtd: k.quantity, unitId: k.unitId }))];
9095
8997
  });
9096
8998
  }
9097
- React22.useEffect(() => {
8999
+ React21.useEffect(() => {
9098
9000
  if (!vinculando) return;
9099
9001
  let vivo = true;
9100
9002
  (async () => {
@@ -9810,10 +9712,10 @@ var STATUS_LABEL = {
9810
9712
  };
9811
9713
  function PersonAttendancesWidget({ personId }) {
9812
9714
  const provider2 = useAgendaProvider();
9813
- const [linhas, setLinhas] = React22.useState(null);
9814
- const [aberto, setAberto] = React22.useState(null);
9815
- const [emCurso, setEmCurso] = React22.useState(null);
9816
- const recarregar = React22.useCallback(async () => {
9715
+ const [linhas, setLinhas] = React21.useState(null);
9716
+ const [aberto, setAberto] = React21.useState(null);
9717
+ const [emCurso, setEmCurso] = React21.useState(null);
9718
+ const recarregar = React21.useCallback(async () => {
9817
9719
  try {
9818
9720
  const r = await provider2.getPersonAttendances?.(personId);
9819
9721
  setLinhas(r ?? []);
@@ -9821,10 +9723,10 @@ function PersonAttendancesWidget({ personId }) {
9821
9723
  setLinhas([]);
9822
9724
  }
9823
9725
  }, [personId, provider2]);
9824
- React22.useEffect(() => {
9726
+ React21.useEffect(() => {
9825
9727
  void recarregar();
9826
9728
  }, [recarregar]);
9827
- React22.useEffect(() => {
9729
+ React21.useEffect(() => {
9828
9730
  let vivo = true;
9829
9731
  (async () => {
9830
9732
  const eu = await provider2.getCurrentPersonId?.() ?? null;
@@ -9922,8 +9824,8 @@ function PersonAttendancesWidget({ personId }) {
9922
9824
  }
9923
9825
  function PersonServicesWidget({ personId }) {
9924
9826
  const provider2 = useAgendaProvider();
9925
- const [rows, setRows] = React22.useState(null);
9926
- React22.useEffect(() => {
9827
+ const [rows, setRows] = React21.useState(null);
9828
+ React21.useEffect(() => {
9927
9829
  let alive = true;
9928
9830
  (async () => {
9929
9831
  try {
@@ -15432,9 +15334,9 @@ function failureMessage(error) {
15432
15334
  }
15433
15335
  function AvailabilityHeaderControl({ provider: provider2 }) {
15434
15336
  const unitId = useActiveUnitId();
15435
- const [status, setStatus] = React22.useState(null);
15436
- const [busy, setBusy] = React22.useState(false);
15437
- const refresh = React22.useCallback(async () => {
15337
+ const [status, setStatus] = React21.useState(null);
15338
+ const [busy, setBusy] = React21.useState(false);
15339
+ const refresh = React21.useCallback(async () => {
15438
15340
  if (!unitId) {
15439
15341
  setStatus(null);
15440
15342
  return;
@@ -15449,7 +15351,7 @@ function AvailabilityHeaderControl({ provider: provider2 }) {
15449
15351
  setStatus(null);
15450
15352
  }
15451
15353
  }, [provider2, unitId]);
15452
- React22.useEffect(() => {
15354
+ React21.useEffect(() => {
15453
15355
  void refresh();
15454
15356
  return provider2.subscribe(() => {
15455
15357
  void refresh();
@@ -15603,12 +15505,12 @@ function EmptyUnit() {
15603
15505
  }
15604
15506
  function TurnQueuePage({ provider: provider2, agendaProvider, title, subtitle }) {
15605
15507
  const unitId = useActiveUnitId();
15606
- const [agendaProfessionals, setAgendaProfessionals] = React22.useState([]);
15607
- const [snapshot, setSnapshot] = React22.useState(null);
15608
- const [loading, setLoading] = React22.useState(false);
15609
- const [error, setError] = React22.useState(null);
15610
- const [, tick] = React22.useState(0);
15611
- const load = React22.useCallback(async () => {
15508
+ const [agendaProfessionals, setAgendaProfessionals] = React21.useState([]);
15509
+ const [snapshot, setSnapshot] = React21.useState(null);
15510
+ const [loading, setLoading] = React21.useState(false);
15511
+ const [error, setError] = React21.useState(null);
15512
+ const [, tick] = React21.useState(0);
15513
+ const load = React21.useCallback(async () => {
15612
15514
  if (!unitId) {
15613
15515
  setSnapshot(null);
15614
15516
  return;
@@ -15623,10 +15525,10 @@ function TurnQueuePage({ provider: provider2, agendaProvider, title, subtitle })
15623
15525
  setLoading(false);
15624
15526
  }
15625
15527
  }, [provider2, unitId]);
15626
- React22.useEffect(() => {
15528
+ React21.useEffect(() => {
15627
15529
  void load();
15628
15530
  }, [load]);
15629
- React22.useEffect(() => {
15531
+ React21.useEffect(() => {
15630
15532
  if (!unitId) {
15631
15533
  setAgendaProfessionals([]);
15632
15534
  return;
@@ -15641,19 +15543,19 @@ function TurnQueuePage({ provider: provider2, agendaProvider, title, subtitle })
15641
15543
  active = false;
15642
15544
  };
15643
15545
  }, [agendaProvider, unitId]);
15644
- React22.useEffect(() => provider2.subscribe(() => {
15546
+ React21.useEffect(() => provider2.subscribe(() => {
15645
15547
  void load();
15646
15548
  }), [provider2, load]);
15647
- React22.useEffect(() => {
15549
+ React21.useEffect(() => {
15648
15550
  const timer = window.setInterval(() => tick((value) => value + 1), 6e4);
15649
15551
  return () => window.clearInterval(timer);
15650
15552
  }, []);
15651
- const rows = React22.useMemo(() => [...snapshot?.entries ?? []].sort((a, b) => {
15553
+ const rows = React21.useMemo(() => [...snapshot?.entries ?? []].sort((a, b) => {
15652
15554
  const rank = { available: 0, serving: 1, unavailable: 2 };
15653
15555
  return rank[a.status] - rank[b.status] || a.position - b.position;
15654
15556
  }), [snapshot]);
15655
15557
  const queueRows = rows.filter((row) => row.status !== "unavailable");
15656
- const professionals = React22.useMemo(() => {
15558
+ const professionals = React21.useMemo(() => {
15657
15559
  const byId = /* @__PURE__ */ new Map();
15658
15560
  for (const professional of agendaProfessionals) {
15659
15561
  byId.set(professional.id, {
@@ -15676,7 +15578,7 @@ function TurnQueuePage({ provider: provider2, agendaProvider, title, subtitle })
15676
15578
  }, [agendaProfessionals, snapshot]);
15677
15579
  const available = professionals.filter((row) => row.status === "available").length;
15678
15580
  const serving = professionals.filter((row) => row.status === "serving").length;
15679
- const addWalkIn = React22.useCallback((professionalId) => {
15581
+ const addWalkIn = React21.useCallback((professionalId) => {
15680
15582
  if (!unitId) return;
15681
15583
  window.location.hash = "/agenda";
15682
15584
  window.setTimeout(() => {
@@ -15768,6 +15670,103 @@ function TurnQueuePage({ provider: provider2, agendaProvider, title, subtitle })
15768
15670
  ] })
15769
15671
  ] }) });
15770
15672
  }
15673
+ function UnitTurnQueueWidget({ item }) {
15674
+ const unitId = item?.id;
15675
+ const [row, setRow] = React21.useState(null);
15676
+ const [loading, setLoading] = React21.useState(true);
15677
+ const [saving, setSaving] = React21.useState(false);
15678
+ const [radius, setRadius] = React21.useState("80");
15679
+ React21.useEffect(() => {
15680
+ if (!unitId) return;
15681
+ let alive = true;
15682
+ const supabase = getSupabaseClientOptional();
15683
+ void supabase?.from("plg_agenda_turn_queues").select("is_active, geofence_required, geofence_radius_meters").eq("unit_id", unitId).eq("queue_key", "walk_in").maybeSingle().then(({ data }) => {
15684
+ if (!alive) return;
15685
+ const next = data ?? { is_active: false, geofence_required: true, geofence_radius_meters: 80 };
15686
+ setRow(next);
15687
+ setRadius(String(next.geofence_radius_meters));
15688
+ setLoading(false);
15689
+ });
15690
+ return () => {
15691
+ alive = false;
15692
+ };
15693
+ }, [unitId]);
15694
+ const save = async (patch) => {
15695
+ if (!unitId || !row) return;
15696
+ const next = { ...row, ...patch };
15697
+ setSaving(true);
15698
+ const supabase = getSupabaseClientOptional();
15699
+ const { data, error } = await supabase.rpc("agenda_turn_queue_configure", {
15700
+ p_unit_id: unitId,
15701
+ p_enabled: next.is_active,
15702
+ p_geofence_required: next.geofence_required,
15703
+ p_radius_meters: next.geofence_radius_meters
15704
+ });
15705
+ setSaving(false);
15706
+ if (error) {
15707
+ toast.error("N\xE3o foi poss\xEDvel salvar a lista da vez", { description: error.message });
15708
+ return;
15709
+ }
15710
+ setRow({ is_active: data.is_active, geofence_required: data.geofence_required, geofence_radius_meters: data.geofence_radius_meters });
15711
+ toast.success("Lista da vez salva");
15712
+ };
15713
+ const radiusNumber = Number(radius);
15714
+ const radiusInvalid = !Number.isInteger(radiusNumber) || radiusNumber < 10 || radiusNumber > 1e3;
15715
+ const hasCoordinate = item?.latitude != null && item?.longitude != null;
15716
+ return /* @__PURE__ */ jsxs(Card, { children: [
15717
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
15718
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: "Lista da vez" }),
15719
+ /* @__PURE__ */ jsx(CardDescription, { children: "Fila de atendimento por ordem de chegada. Desligada, o item some do menu e o bot\xE3o de disponibilidade some do topo." })
15720
+ ] }),
15721
+ /* @__PURE__ */ jsx(CardContent, { className: "space-y-4", children: loading || !row ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
15722
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" }),
15723
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" })
15724
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
15725
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-4 rounded-md border border-input bg-background px-3 py-2.5", children: [
15726
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Ativar lista da vez nesta unidade" }),
15727
+ /* @__PURE__ */ jsx(Switch, { checked: row.is_active, disabled: saving, onCheckedChange: (v) => void save({ is_active: v }) })
15728
+ ] }),
15729
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
15730
+ /* @__PURE__ */ jsxs("div", { children: [
15731
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Localiza\xE7\xE3o da lista da vez" }),
15732
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Valida o bot\xE3o \u201Cestou dispon\xEDvel\u201D dos profissionais pela dist\xE2ncia at\xE9 a unidade." })
15733
+ ] }),
15734
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-4 rounded-md border border-input bg-background px-3 py-2.5", children: [
15735
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Exigir que o profissional esteja na unidade" }),
15736
+ /* @__PURE__ */ jsx(Switch, { checked: row.geofence_required, disabled: saving, onCheckedChange: (v) => void save({ geofence_required: v }) })
15737
+ ] }),
15738
+ /* @__PURE__ */ jsx("div", { className: "fz-container", children: /* @__PURE__ */ jsxs("div", { className: "fz-fields fz-fields-2 gap-4", children: [
15739
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
15740
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Coordenada" }),
15741
+ /* @__PURE__ */ jsx("p", { className: "flex h-10 items-center rounded-md border border-input bg-muted/40 px-3 text-sm tabular-nums text-muted-foreground", children: hasCoordinate ? `${Number(item.latitude).toFixed(6)}, ${Number(item.longitude).toFixed(6)}` : "Sem coordenada \u2014 preencha o endere\xE7o" }),
15742
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
15743
+ "Vem do endere\xE7o da unidade.",
15744
+ " ",
15745
+ /* @__PURE__ */ jsx("button", { type: "button", className: "underline decoration-dashed underline-offset-2", onClick: () => adminNavigateTo(`/settings/locations/${item?.id}/edit`), children: "Editar endere\xE7o" })
15746
+ ] })
15747
+ ] }),
15748
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
15749
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Raio (m)" }),
15750
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
15751
+ /* @__PURE__ */ jsx(Input, { type: "number", min: 10, max: 1e3, value: radius, onChange: (e) => setRadius(e.target.value), className: "tabular-nums" }),
15752
+ /* @__PURE__ */ jsx(
15753
+ Button,
15754
+ {
15755
+ variant: "outline",
15756
+ disabled: saving || radiusInvalid || radiusNumber === row.geofence_radius_meters,
15757
+ onClick: () => void save({ geofence_radius_meters: radiusNumber }),
15758
+ children: "Salvar"
15759
+ }
15760
+ )
15761
+ ] }),
15762
+ radiusInvalid && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: "Use um raio entre 10 e 1000 metros." })
15763
+ ] })
15764
+ ] }) }),
15765
+ row.geofence_required && !hasCoordinate && row.is_active && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: "Sem coordenada no endere\xE7o, ningu\xE9m consegue marcar \u201Cestou dispon\xEDvel\u201D nesta unidade." })
15766
+ ] })
15767
+ ] }) })
15768
+ ] });
15769
+ }
15771
15770
 
15772
15771
  // src/lib/turn-queue-plugin.ts
15773
15772
  function createAgendaTurnQueuePlugin(options = {}) {
@@ -15782,8 +15781,8 @@ function createAgendaTurnQueuePlugin(options = {}) {
15782
15781
  const menu = options.labels?.menu ?? "Pr\xF3ximo da vez";
15783
15782
  const title = options.labels?.title ?? menu;
15784
15783
  const subtitle = options.labels?.subtitle ?? "Ordem ao vivo dos profissionais dispon\xEDveis nesta unidade";
15785
- const Page = (() => React22.createElement(TurnQueuePage, { provider: provider2, agendaProvider, title, subtitle }));
15786
- const HeaderControl = (() => React22.createElement(AvailabilityHeaderControl, { provider: provider2 }));
15784
+ const Page = (() => React21.createElement(TurnQueuePage, { provider: provider2, agendaProvider, title, subtitle }));
15785
+ const HeaderControl = (() => React21.createElement(AvailabilityHeaderControl, { provider: provider2 }));
15787
15786
  return {
15788
15787
  id: "agenda-turn-queue",
15789
15788
  name: menu,
@@ -15816,6 +15815,14 @@ function createAgendaTurnQueuePlugin(options = {}) {
15816
15815
  permission: { feature: "agenda", action: "read" },
15817
15816
  title
15818
15817
  }],
15818
+ // Lives on the add-on, not on agenda: the unit tab exists only while this
15819
+ // module is enabled in settings/modules.
15820
+ widgets: [{
15821
+ id: "agenda-unit-turn-queue",
15822
+ zone: UNIT_DETAIL_ZONES.turnQueue,
15823
+ component: UnitTurnQueueWidget,
15824
+ order: 0
15825
+ }],
15819
15826
  headerControls: [{
15820
15827
  id: "agenda-turn-queue.availability",
15821
15828
  component: HeaderControl,
@@ -19137,28 +19144,28 @@ function createAgendaPlugin(options) {
19137
19144
  }
19138
19145
  }
19139
19146
  ]);
19140
- const PageComponent = () => React22.createElement(AgendaPage, { config, provider: provider2, store });
19147
+ const PageComponent = () => React21.createElement(AgendaPage, { config, provider: provider2, store });
19141
19148
  const PersonAttendancesBound = (props) => (
19142
19149
  // O provider do PLUGIN, sem a moldura da página: dentro de uma aba a
19143
19150
  // `AgendaPage` traria a altura cheia e a rolagem própria do calendário, e a
19144
19151
  // lista passaria a rolar dentro de uma caixa que já rola.
19145
- React22.createElement(
19152
+ React21.createElement(
19146
19153
  AgendaContextProvider,
19147
19154
  { config, provider: provider2, store },
19148
- React22.createElement(PersonAttendancesWidget, { personId: props.item?.id })
19155
+ React21.createElement(PersonAttendancesWidget, { personId: props.item?.id })
19149
19156
  )
19150
19157
  );
19151
19158
  PersonAttendancesBound.displayName = "AgendaPersonAttendances";
19152
- const PersonAttendanceBlockBound = (props) => React22.createElement(
19159
+ const PersonAttendanceBlockBound = (props) => React21.createElement(
19153
19160
  AgendaContextProvider,
19154
19161
  { config, provider: provider2, store },
19155
- React22.createElement(PersonAttendanceBlock, { personId: props.item?.id })
19162
+ React21.createElement(PersonAttendanceBlock, { personId: props.item?.id })
19156
19163
  );
19157
19164
  PersonAttendanceBlockBound.displayName = "AgendaPersonAttendanceBlock";
19158
- const PersonServicesBound = (props) => React22.createElement(
19165
+ const PersonServicesBound = (props) => React21.createElement(
19159
19166
  AgendaContextProvider,
19160
19167
  { config, provider: provider2, store },
19161
- React22.createElement(PersonServicesWidget, { personId: props.item?.id })
19168
+ React21.createElement(PersonServicesWidget, { personId: props.item?.id })
19162
19169
  );
19163
19170
  PersonServicesBound.displayName = "AgendaPersonServices";
19164
19171
  return {
@@ -19314,10 +19321,10 @@ function createAgendaPlugin(options) {
19314
19321
  },
19315
19322
  {
19316
19323
  path: "/agenda/confirmations",
19317
- component: (() => React22.createElement(
19324
+ component: (() => React21.createElement(
19318
19325
  AgendaPage,
19319
19326
  { config, provider: provider2, store },
19320
- React22.createElement(ConfirmationsView)
19327
+ React21.createElement(ConfirmationsView)
19321
19328
  )),
19322
19329
  fullBleed: true,
19323
19330
  permission: { feature: "agenda", action: "read" },
@@ -19325,7 +19332,7 @@ function createAgendaPlugin(options) {
19325
19332
  },
19326
19333
  {
19327
19334
  path: "/checkin",
19328
- component: (() => React22.createElement(CheckinPage, {
19335
+ component: (() => React21.createElement(CheckinPage, {
19329
19336
  config,
19330
19337
  provider: provider2,
19331
19338
  store,
@@ -19341,12 +19348,6 @@ function createAgendaPlugin(options) {
19341
19348
  }
19342
19349
  ],
19343
19350
  widgets: [
19344
- {
19345
- id: "agenda-unit-turn-queue",
19346
- zone: UNIT_DETAIL_ZONES.turnQueue,
19347
- component: UnitTurnQueueWidget,
19348
- order: 0
19349
- },
19350
19351
  {
19351
19352
  // O HISTÓRICO DE ATENDIMENTO NA FICHA DA PESSOA.
19352
19353
  //
@@ -19483,9 +19484,9 @@ function createAgendaPlugin(options) {
19483
19484
  icon: "Calendar",
19484
19485
  // Standard layout: General | Integrations (Google Calendar addon) | Properties.
19485
19486
  component: (() => {
19486
- const AgendaSettingsTab = () => React22.createElement(PluginSettingsPanel, {
19487
+ const AgendaSettingsTab = () => React21.createElement(PluginSettingsPanel, {
19487
19488
  title: "Agenda",
19488
- generalSettings: React22.createElement(AgendaGeneralSettings),
19489
+ generalSettings: React21.createElement(AgendaGeneralSettings),
19489
19490
  registries,
19490
19491
  hostPluginId: "agenda",
19491
19492
  routeBase: "/settings/agenda"