@fayz-ai/plugin-agenda 0.25.1 → 0.26.0
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/bridges/create-financial-bridge.d.ts +1 -1
- package/dist/bridges/create-financial-bridge.d.ts.map +1 -1
- package/dist/components/AgendaFilterRail.d.ts +1 -1
- package/dist/components/AgendaGeneralSettings.d.ts.map +1 -1
- package/dist/components/AgendaMessageTemplates.d.ts +3 -0
- package/dist/components/AgendaMessageTemplates.d.ts.map +1 -0
- package/dist/components/AgendaMobileList.d.ts.map +1 -1
- package/dist/components/AppointmentModal.d.ts.map +1 -1
- package/dist/components/AppointmentPopover.d.ts.map +1 -1
- package/dist/components/AttendanceRuler.d.ts.map +1 -1
- package/dist/components/AvailabilityHeaderControl.d.ts.map +1 -1
- package/dist/components/BookingPaymentPanel.d.ts.map +1 -1
- package/dist/components/BookingPrepaidPanel.d.ts.map +1 -1
- package/dist/components/CalendarSidebar.d.ts.map +1 -1
- package/dist/components/CheckinDialog.d.ts.map +1 -1
- package/dist/components/CheckinScoreboard.d.ts.map +1 -1
- package/dist/components/EventContextMenu.d.ts.map +1 -1
- package/dist/components/FilterRail.d.ts.map +1 -1
- package/dist/components/PersonAttendanceBlock.d.ts.map +1 -1
- package/dist/components/PersonAttendancesWidget.d.ts.map +1 -1
- package/dist/components/SeriesDeleteChoice.d.ts.map +1 -1
- package/dist/hooks/useZoneFilled.d.ts +3 -0
- package/dist/hooks/useZoneFilled.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +594 -349
- package/dist/index.js.map +1 -1
- package/dist/integrations/google-calendar/components/ChannelMappingList.d.ts.map +1 -1
- package/dist/integrations/google-calendar/index.d.ts +1 -1
- package/dist/integrations/google-calendar/index.d.ts.map +1 -1
- package/dist/lib/message-events.d.ts.map +1 -1
- package/dist/locales/en.d.ts.map +1 -1
- package/dist/locales/pt-BR.d.ts.map +1 -1
- package/dist/settings/v1-settings.d.ts +2 -0
- package/dist/settings/v1-settings.d.ts.map +1 -0
- package/dist/views/CalendarView.d.ts.map +1 -1
- package/dist/views/CheckinView.d.ts.map +1 -1
- package/dist/views/ConfirmationsView.d.ts.map +1 -1
- package/dist/views/turn-queue/TurnQueueReportPage.d.ts.map +1 -1
- package/package.json +7 -6
- package/dist/components/MiniCalendar.d.ts +0 -2
- package/dist/components/MiniCalendar.d.ts.map +0 -1
- package/dist/data/index.d.ts +0 -5
- package/dist/data/index.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createMockAgendaProvider, createSupabasePublicBookingProvider } from './chunk-A77PUFY5.js';
|
|
2
2
|
export { createMockAgendaProvider } from './chunk-A77PUFY5.js';
|
|
3
3
|
import React23, { useState, useEffect, useRef, useMemo, useCallback, useLayoutEffect } from 'react';
|
|
4
|
-
import { tl, recordRailFields, RECORD_GROUP, activeFacet, connectionStatus, createConnectionStore, getActiveTenantId, createSafeDataProvider, todayLocal, getSupabaseClientOptional, registerTranslations, registerMessageDefaults, connectorRuntimeToken, CONNECTOR_RUNTIME_TOKEN_HEADER, getActiveUnitId, assertWrote, emitDataChanged, globalCache, usePluginRuntimeOptional, useTranslation, useActiveUnitId, emitDomainEvent, getCurrentLocale, localDateKey, useDataChanged, resolveDataProvider, describeError,
|
|
5
|
-
import { createPluginContext, fayzConnectorOAuth, UNIT_DETAIL_ZONES, setScheduleBlockConfig, getScheduleBlockConfig, registerPersonActions, PluginSettingsPanel, adminNavigateTo, createArchetypeLookup, dedup, usePluginPrefs, PersonLink,
|
|
4
|
+
import { tl, recordRailFields, RECORD_GROUP, activeFacet, connectionStatus, createConnectionStore, getActiveTenantId, createSafeDataProvider, todayLocal, getSupabaseClientOptional, registerTranslations, registerMessageDefaults, connectorRuntimeToken, CONNECTOR_RUNTIME_TOKEN_HEADER, getActiveUnitId, assertWrote, emitDataChanged, globalCache, usePluginRuntimeOptional, useTranslation, formatCurrency, useActiveUnitId, emitDomainEvent, getCurrentLocale, localDateKey, useDataChanged, resolveDataProvider, describeError, getWidgetsForZone } from '@fayz-ai/core';
|
|
5
|
+
import { createPluginContext, defineSettingsTab, attendanceSettingsParent, fayzConnectorOAuth, UNIT_DETAIL_ZONES, setScheduleBlockConfig, getScheduleBlockConfig, registerPersonActions, PluginSettingsPanel, adminNavigateTo, createArchetypeLookup, dedup, usePluginPrefs, PersonLink, SettingsGroup, MessageTemplateRow, useTenantPluginSettings, ToggleRow, SelectRow, usePermissionOptional, useAdminPath, PageActions, useRightRailStore, useFieldRules, deriveEntityKey, WidgetSlot, openEntity, ScheduleEditor, useLimitGuard, useLookupCreate, CrudFormPage, CrudDetailPage, ContactPicker, PaymentStatusBadge as PaymentStatusBadge$1, RightRailPage, CrudRecordModal, invalidateLimit } from '@fayz-ai/admin';
|
|
6
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
7
|
import FullCalendar from '@fullcalendar/react';
|
|
7
8
|
import dayGridPlugin from '@fullcalendar/daygrid';
|
|
8
9
|
import timeGridPlugin from '@fullcalendar/timegrid';
|
|
@@ -11,12 +12,12 @@ import interactionPlugin from '@fullcalendar/interaction';
|
|
|
11
12
|
import listPlugin from '@fullcalendar/list';
|
|
12
13
|
import ptBrLocale from '@fullcalendar/core/locales/pt-br';
|
|
13
14
|
import { CheckCircle, Stethoscope, RotateCcw, Check, CircleDashed, Layers, ArrowRight, Play, Radio, Monitor, BarChart3, SlidersHorizontal, Download, Loader2, LogIn, Coffee, Undo2, CheckCircle2, LogOut, AlertCircle, RefreshCw, CalendarPlus, X, Ban, Clock3, Plus, Settings, ChevronLeft, ChevronRight, ChevronDown, CircleDollarSign, CalendarDays, UserRound, Package, Clock, Mic, BellRing, UserPlus, History, ArrowUp, ArrowDown, Trash2, Sparkles, CalendarX, UserX, Search, CalendarOff, Pencil, User, MapPin, FileText, AlertTriangle, DollarSign, HandCoins, CheckSquare, Calendar, ExternalLink, Users, DoorOpen, Briefcase, CircleDot, MessageCircle, Phone, AlarmClock, ArrowLeft, Link2, Receipt, ClipboardCheck, MoreVertical, ArrowUpToLine, Info, FileCheck, ArrowRightLeft, CreditCard, QrCode, Banknote, PackageCheck, Maximize2 } from 'lucide-react';
|
|
14
|
-
import { Card, CardHeader, CardTitle, CardDescription, CardContent, Skeleton, Switch,
|
|
15
|
-
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
15
|
+
import { Card, CardHeader, CardTitle, CardDescription, CardContent, Skeleton, Switch, Button, Input, toast, FilterRail, AdaptiveFilter, FilterCheckRow, TooltipProvider, Badge, ModulePage, Modal, ModalContent, ModalHeader, ModalTitle, ModalDescription, ModalBody, ModalFooter, SubpageHeader, DatePicker, MultiSelect, DataTable, Dropdown, DropdownTrigger, DropdownContent, DropdownLabel, DropdownSub, DropdownSubTrigger, DropdownSubContent, DropdownItem, DropdownSeparator, Checkbox, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, PersonAvatar, abbreviatePersonName, INLINE_FILTER_MAX, PersonMultiPicker, SegmentedControl, MiniCalendar, PageHeaderActions, ConfirmDialog, RailWorkspace, Tooltip, TooltipTrigger, TooltipContent, ModalTask, cn, Tabs, TabsList, TabsTrigger, TabsContent, createXlsxReport, PersonPicker, Textarea, TimePicker, ModalTaskHost, SearchCombobox, ModalTaskHeader, normalizePhone, DotBadge } from '@fayz-ai/ui';
|
|
16
16
|
import { createPortal } from 'react-dom';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
17
|
+
import { FORMS_ZONES } from '@fayz-ai/forms/views/zones';
|
|
18
|
+
import { FINANCIAL_ZONES } from '@fayz-ai/financial/views/zones';
|
|
19
19
|
import { createStore } from 'zustand/vanilla';
|
|
20
|
+
import { listAttendanceContracts, ensureAttendanceContracts, ContractSignPane } from '@fayz-ai/plugin-forms';
|
|
20
21
|
|
|
21
22
|
// src/lib/message-events.ts
|
|
22
23
|
var BOOKING_FIELDS = [
|
|
@@ -92,6 +93,17 @@ function buildAgendaDomainEvents() {
|
|
|
92
93
|
description: "O hor\xE1rio foi perdido",
|
|
93
94
|
trigger: "Quando o agendamento \xE9 marcado como falta",
|
|
94
95
|
fields: BOOKING_FIELDS
|
|
96
|
+
},
|
|
97
|
+
// V1 "Confirmação manual": the reception asks a client to confirm by hand.
|
|
98
|
+
// Declared so its text is one template in the catalog; nothing emits it yet.
|
|
99
|
+
{
|
|
100
|
+
name: "agenda.confirmation_requested",
|
|
101
|
+
title: "Confirma\xE7\xE3o manual",
|
|
102
|
+
icon: "MessageSquareText",
|
|
103
|
+
audit: false,
|
|
104
|
+
description: "A recep\xE7\xE3o pediu a confirma\xE7\xE3o do hor\xE1rio",
|
|
105
|
+
trigger: "Quando algu\xE9m pede a confirma\xE7\xE3o manualmente na agenda",
|
|
106
|
+
fields: BOOKING_FIELDS
|
|
95
107
|
}
|
|
96
108
|
];
|
|
97
109
|
}
|
|
@@ -201,9 +213,43 @@ function buildAgendaMessageDefaults() {
|
|
|
201
213
|
body: "Oi {{customer_name}}, senti sua falta no hor\xE1rio de {{booking_date}} \u{1F614}\n\nAconteceu alguma coisa? Se quiser, j\xE1 deixo outro hor\xE1rio separado para voc\xEA aqui na {{business_name}}, \xE9 s\xF3 responder."
|
|
202
214
|
}
|
|
203
215
|
}
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
eventKey: "agenda.confirmation_requested",
|
|
219
|
+
kind: "transactional",
|
|
220
|
+
channels: ["whatsapp"],
|
|
221
|
+
defaults: {
|
|
222
|
+
whatsapp: {
|
|
223
|
+
// V1's default text, with the catalog's placeholders.
|
|
224
|
+
body: "Ol\xE1 {{customer_name}}! Passando para confirmar seu agendamento: {{booking_date}} \xE0s {{booking_time}}. Responda SIM para confirmar.",
|
|
225
|
+
actions: CONFIRM_OR_CANCEL
|
|
226
|
+
}
|
|
227
|
+
}
|
|
204
228
|
}
|
|
205
229
|
];
|
|
206
230
|
}
|
|
231
|
+
var MESSAGES = [
|
|
232
|
+
{ eventKey: "agenda.confirmation_requested", label: ["Manual confirmation", "Confirma\xE7\xE3o manual"], pending: true },
|
|
233
|
+
{ eventKey: "agenda.booking_created", label: ["Booking created", "Agendamento criado"] },
|
|
234
|
+
{ eventKey: "agenda.booking_reminder", label: ["Reminder", "Lembrete de v\xE9spera"] },
|
|
235
|
+
{ eventKey: "agenda.booking_rescheduled", label: ["Rescheduled", "Hor\xE1rio remarcado"] },
|
|
236
|
+
{ eventKey: "agenda.booking_cancelled", label: ["Cancelled", "Agendamento cancelado"] },
|
|
237
|
+
{ eventKey: "agenda.booking_completed", label: ["After the visit", "Depois do atendimento"] },
|
|
238
|
+
{ eventKey: "agenda.booking_no_show", label: ["No-show", "Falta"] }
|
|
239
|
+
];
|
|
240
|
+
function AgendaMessageTemplates() {
|
|
241
|
+
return /* @__PURE__ */ jsx(
|
|
242
|
+
SettingsGroup,
|
|
243
|
+
{
|
|
244
|
+
title: tl("Message templates", "Templates de mensagem"),
|
|
245
|
+
description: tl(
|
|
246
|
+
"Each text is edited once, in Automations \u203A Messages, and used wherever it is sent.",
|
|
247
|
+
"Cada texto \xE9 editado uma vez, em Automa\xE7\xF5es \u203A Mensagens, e vale onde ele for enviado."
|
|
248
|
+
),
|
|
249
|
+
children: MESSAGES.map((m) => /* @__PURE__ */ jsx(MessageTemplateRow, { eventKey: m.eventKey, label: tl(...m.label), pending: m.pending }, m.eventKey))
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
}
|
|
207
253
|
var DEFAULT_LABELS = {
|
|
208
254
|
pageTitle: "Agenda",
|
|
209
255
|
pageSubtitle: "Calendar and appointment management",
|
|
@@ -932,12 +978,12 @@ function BlockDialog({
|
|
|
932
978
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
933
979
|
/* @__PURE__ */ jsx("label", { className: "mb-1 block text-xs font-medium text-muted-foreground", children: "Descri\xE7\xE3o" }),
|
|
934
980
|
/* @__PURE__ */ jsx(
|
|
935
|
-
|
|
981
|
+
Textarea,
|
|
936
982
|
{
|
|
937
983
|
value: description,
|
|
938
984
|
onChange: (e) => setDescription(e.target.value),
|
|
939
985
|
rows: 2,
|
|
940
|
-
className: "
|
|
986
|
+
className: "min-h-0"
|
|
941
987
|
}
|
|
942
988
|
)
|
|
943
989
|
] }),
|
|
@@ -954,12 +1000,14 @@ function BlockDialog({
|
|
|
954
1000
|
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: DIAS.map((d) => {
|
|
955
1001
|
const on = days2.includes(d.v);
|
|
956
1002
|
return /* @__PURE__ */ jsx(
|
|
957
|
-
|
|
1003
|
+
Button,
|
|
958
1004
|
{
|
|
1005
|
+
variant: "bare",
|
|
1006
|
+
size: "bare",
|
|
959
1007
|
type: "button",
|
|
960
1008
|
onClick: () => toggleDay(d.v),
|
|
961
1009
|
"aria-pressed": on,
|
|
962
|
-
className: "rounded-button border px-2.5 py-1 text-xs transition-colors " + (on ? "border-primary bg-primary/10 font-medium text-foreground" : "border-input text-muted-foreground hover:bg-muted"),
|
|
1010
|
+
className: "rounded-button border px-2.5 py-1 text-xs transition-colors " + (on ? "border-primary bg-primary/10 font-medium text-foreground" : "border-input font-normal text-muted-foreground hover:bg-muted"),
|
|
963
1011
|
children: d.label
|
|
964
1012
|
},
|
|
965
1013
|
d.v
|
|
@@ -1002,8 +1050,10 @@ function BlockDialog({
|
|
|
1002
1050
|
] }),
|
|
1003
1051
|
/* @__PURE__ */ jsxs(ModalFooter, { className: "items-center", children: [
|
|
1004
1052
|
editing && /* @__PURE__ */ jsx(
|
|
1005
|
-
|
|
1053
|
+
Button,
|
|
1006
1054
|
{
|
|
1055
|
+
variant: "bare",
|
|
1056
|
+
size: "bare",
|
|
1007
1057
|
type: "button",
|
|
1008
1058
|
disabled: saving,
|
|
1009
1059
|
onClick: async () => {
|
|
@@ -1071,12 +1121,14 @@ function LostSlotsCard({ range, selectedStatuses, onPick }) {
|
|
|
1071
1121
|
linhas.map(({ status, label, n, Icon, tone }) => {
|
|
1072
1122
|
const on = selectedStatuses.includes(status);
|
|
1073
1123
|
return /* @__PURE__ */ jsxs(
|
|
1074
|
-
|
|
1124
|
+
Button,
|
|
1075
1125
|
{
|
|
1126
|
+
variant: "bare",
|
|
1127
|
+
size: "bare",
|
|
1076
1128
|
type: "button",
|
|
1077
1129
|
onClick: () => onPick(status),
|
|
1078
1130
|
"aria-pressed": on,
|
|
1079
|
-
className: "flex w-full items-center gap-2 rounded-md px-1.5 py-1.5 text-left text-xs transition-colors " + (on ? "bg-muted font-medium text-foreground" : "text-muted-foreground hover:bg-muted/50"),
|
|
1131
|
+
className: "flex w-full items-center justify-start gap-2 rounded-md px-1.5 py-1.5 text-left text-xs transition-colors " + (on ? "bg-muted font-medium text-foreground" : "font-normal text-muted-foreground hover:bg-muted/50"),
|
|
1080
1132
|
children: [
|
|
1081
1133
|
/* @__PURE__ */ jsx(Icon, { className: `h-3.5 w-3.5 shrink-0 ${tone}`, "aria-hidden": true }),
|
|
1082
1134
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: label }),
|
|
@@ -1117,20 +1169,22 @@ function ScheduleGridDialog({ open, onClose, professionalId }) {
|
|
|
1117
1169
|
/* @__PURE__ */ jsxs("div", { className: "relative p-2", children: [
|
|
1118
1170
|
/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-4 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" }),
|
|
1119
1171
|
/* @__PURE__ */ jsx(
|
|
1120
|
-
|
|
1172
|
+
Input,
|
|
1121
1173
|
{
|
|
1122
1174
|
type: "search",
|
|
1123
1175
|
value: search,
|
|
1124
1176
|
onChange: (e) => setSearch(e.target.value),
|
|
1125
1177
|
placeholder: t2("agenda.schedules.searchProfessional"),
|
|
1126
|
-
className: "
|
|
1178
|
+
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"
|
|
1127
1179
|
}
|
|
1128
1180
|
)
|
|
1129
1181
|
] }),
|
|
1130
1182
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto pb-2", children: [
|
|
1131
1183
|
shown.map((prof) => /* @__PURE__ */ jsxs(
|
|
1132
|
-
|
|
1184
|
+
Button,
|
|
1133
1185
|
{
|
|
1186
|
+
variant: "bare",
|
|
1187
|
+
size: "bare",
|
|
1134
1188
|
ref: selectedId === prof.id ? selectedRef : void 0,
|
|
1135
1189
|
type: "button",
|
|
1136
1190
|
onClick: () => setSelectedId(prof.id),
|
|
@@ -1144,7 +1198,7 @@ function ScheduleGridDialog({ open, onClose, professionalId }) {
|
|
|
1144
1198
|
// fundo claro é o texto que ninguém lê. A cor identifica a
|
|
1145
1199
|
// linha (fundo e barra); quem carrega a informação é o
|
|
1146
1200
|
// nome, e ele precisa de contraste.
|
|
1147
|
-
"flex w-full items-center gap-2 border-l-2 px-3 py-2 text-left text-sm transition-colors " + (selectedId === prof.id ? "border-primary bg-primary/10 font-semibold text-foreground" : "border-transparent text-muted-foreground hover:bg-muted/50 hover:text-foreground")
|
|
1201
|
+
"flex w-full items-center justify-start gap-2 border-l-2 px-3 py-2 text-left text-sm transition-colors " + (selectedId === prof.id ? "border-primary bg-primary/10 font-semibold text-foreground" : "border-transparent font-normal text-muted-foreground hover:bg-muted/50 hover:text-foreground")
|
|
1148
1202
|
),
|
|
1149
1203
|
children: [
|
|
1150
1204
|
/* @__PURE__ */ jsx(PersonAvatar, { name: prof.name, src: prof.avatarUrl, size: "sm" }),
|
|
@@ -1316,7 +1370,7 @@ var ICON_COLORS = {
|
|
|
1316
1370
|
bank_transfer: "text-warning",
|
|
1317
1371
|
check: "text-muted-foreground"
|
|
1318
1372
|
};
|
|
1319
|
-
function BookingPaymentPanel({ orderId, orderTotal, services, onClose, onPaymentChange, formatCurrency:
|
|
1373
|
+
function BookingPaymentPanel({ orderId, orderTotal, services, onClose, onPaymentChange, formatCurrency: formatCurrency9, inline }) {
|
|
1320
1374
|
const t2 = useTranslation();
|
|
1321
1375
|
const config = useAgendaConfig();
|
|
1322
1376
|
const bridge = config.financialBridge;
|
|
@@ -1398,7 +1452,7 @@ function BookingPaymentPanel({ orderId, orderTotal, services, onClose, onPayment
|
|
|
1398
1452
|
!loading && isPaid && justPaid && /* @__PURE__ */ jsxs("div", { className: "text-center py-8 space-y-2 animate-in fade-in zoom-in-95 duration-300", children: [
|
|
1399
1453
|
/* @__PURE__ */ jsx("div", { className: "flex h-14 w-14 mx-auto items-center justify-center rounded-full bg-success/10 animate-bounce", style: { animationDuration: "600ms", animationIterationCount: "2" }, children: /* @__PURE__ */ jsx(Check, { className: "h-7 w-7 text-success" }) }),
|
|
1400
1454
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-success", children: t2("agenda.payment.checkoutComplete") }),
|
|
1401
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children:
|
|
1455
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: formatCurrency9(detail.totalAmount) })
|
|
1402
1456
|
] }),
|
|
1403
1457
|
!loading && detail && detail.status !== "none" && !justPaid && /* @__PURE__ */ jsxs("div", { className: "space-y-3 animate-in fade-in duration-300", children: [
|
|
1404
1458
|
detail.movements.length > 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: detail.movements.map((mov) => {
|
|
@@ -1430,21 +1484,21 @@ function BookingPaymentPanel({ orderId, orderTotal, services, onClose, onPayment
|
|
|
1430
1484
|
] }),
|
|
1431
1485
|
isPartial && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-warning/10 px-2 py-0.5 text-[10px] font-medium text-warning", children: [
|
|
1432
1486
|
"! ",
|
|
1433
|
-
|
|
1487
|
+
formatCurrency9(mov.paidAmount),
|
|
1434
1488
|
"/",
|
|
1435
|
-
|
|
1489
|
+
formatCurrency9(mov.amount)
|
|
1436
1490
|
] }),
|
|
1437
1491
|
isOverdue && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-destructive/10 px-2 py-0.5 text-[10px] font-medium text-destructive", children: [
|
|
1438
1492
|
"! ",
|
|
1439
1493
|
t2("agenda.payment.overdue")
|
|
1440
1494
|
] }),
|
|
1441
1495
|
mov.status === "pending" && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: t2("agenda.payment.pending") }),
|
|
1442
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children:
|
|
1496
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: formatCurrency9(mov.paidAmount || mov.amount) })
|
|
1443
1497
|
] })
|
|
1444
1498
|
] }, mov.id);
|
|
1445
1499
|
}) }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm px-1", children: [
|
|
1446
1500
|
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: t2("agenda.payment.total") }),
|
|
1447
|
-
/* @__PURE__ */ jsx("span", { className: "font-semibold", children:
|
|
1501
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold", children: formatCurrency9(detail.totalAmount) })
|
|
1448
1502
|
] }),
|
|
1449
1503
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1450
1504
|
detail.referenceNumber && /* @__PURE__ */ jsxs("span", { className: "text-[10px] font-mono text-muted-foreground", children: [
|
|
@@ -1469,12 +1523,12 @@ function BookingPaymentPanel({ orderId, orderTotal, services, onClose, onPayment
|
|
|
1469
1523
|
/* @__PURE__ */ jsx("p", { className: "text-[11px] font-medium text-muted-foreground mb-2", children: t2("agenda.payment.serviceSummary") }),
|
|
1470
1524
|
/* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: services.map((svc, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm py-1", children: [
|
|
1471
1525
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: svc.name }),
|
|
1472
|
-
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children:
|
|
1526
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: formatCurrency9(svc.price) })
|
|
1473
1527
|
] }, i)) })
|
|
1474
1528
|
] }),
|
|
1475
1529
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm font-semibold pt-2 border-t", children: [
|
|
1476
1530
|
/* @__PURE__ */ jsx("span", { children: t2("agenda.payment.total") }),
|
|
1477
|
-
/* @__PURE__ */ jsx("span", { children:
|
|
1531
|
+
/* @__PURE__ */ jsx("span", { children: formatCurrency9(orderTotal) })
|
|
1478
1532
|
] }),
|
|
1479
1533
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1480
1534
|
/* @__PURE__ */ jsx("p", { className: "text-[11px] font-medium text-muted-foreground mb-2", children: t2("agenda.payment.paymentMethod") }),
|
|
@@ -1491,12 +1545,14 @@ function BookingPaymentPanel({ orderId, orderTotal, services, onClose, onPayment
|
|
|
1491
1545
|
const iconColor = ICON_COLORS[ptTx] ?? ICON_COLORS.cash;
|
|
1492
1546
|
const isActive = selectedTypeId === pt.id;
|
|
1493
1547
|
return /* @__PURE__ */ jsxs(
|
|
1494
|
-
|
|
1548
|
+
Button,
|
|
1495
1549
|
{
|
|
1550
|
+
variant: "bare",
|
|
1551
|
+
size: "bare",
|
|
1496
1552
|
type: "button",
|
|
1497
1553
|
"data-active": isActive,
|
|
1498
1554
|
onClick: () => handleSelectType(pt.id),
|
|
1499
|
-
className: `flex flex-col items-center gap-1 rounded-lg border p-2.5 text-[10px] font-medium transition-all ${colorClass}`,
|
|
1555
|
+
className: `flex flex-col items-center justify-start gap-1 rounded-lg border p-2.5 text-[10px] font-medium transition-all ${colorClass}`,
|
|
1500
1556
|
children: [
|
|
1501
1557
|
/* @__PURE__ */ jsx(Icon, { className: `h-4 w-4 ${iconColor}` }),
|
|
1502
1558
|
/* @__PURE__ */ jsx("span", { className: "truncate w-full text-center", children: pt.name })
|
|
@@ -1509,76 +1565,49 @@ function BookingPaymentPanel({ orderId, orderTotal, services, onClose, onPayment
|
|
|
1509
1565
|
selectedTypeId && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
1510
1566
|
filteredMethods.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
1511
1567
|
/* @__PURE__ */ jsx("label", { className: "text-[11px] font-medium text-muted-foreground", children: needsCard ? t2("agenda.payment.card") : t2("agenda.payment.method") }),
|
|
1512
|
-
/* @__PURE__ */ jsxs(
|
|
1513
|
-
"select",
|
|
1514
|
-
{
|
|
1515
|
-
|
|
1516
|
-
onChange: (e) => setPaymentMethodId(e.target.value),
|
|
1517
|
-
className: "w-full mt-1 rounded-input border border-input bg-card shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] px-2.5 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring",
|
|
1518
|
-
children: [
|
|
1519
|
-
/* @__PURE__ */ jsx("option", { value: "", children: t2("agenda.payment.select") }),
|
|
1520
|
-
filteredMethods.map((m) => /* @__PURE__ */ jsx("option", { value: m.id, children: m.name }, m.id))
|
|
1521
|
-
]
|
|
1522
|
-
}
|
|
1523
|
-
)
|
|
1568
|
+
/* @__PURE__ */ jsxs(Select, { value: paymentMethodId, onValueChange: setPaymentMethodId, children: [
|
|
1569
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "mt-1 bg-card px-2.5", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t2("agenda.payment.select") }) }),
|
|
1570
|
+
/* @__PURE__ */ jsx(SelectContent, { children: filteredMethods.map((m) => /* @__PURE__ */ jsx(SelectItem, { value: m.id, children: m.name }, m.id)) })
|
|
1571
|
+
] })
|
|
1524
1572
|
] }),
|
|
1525
1573
|
needsCard && /* @__PURE__ */ jsxs("div", { className: `grid gap-2.5 ${needsCardInstallments ? "grid-cols-2" : "grid-cols-1"}`, children: [
|
|
1526
1574
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1527
1575
|
/* @__PURE__ */ jsx("label", { className: "text-[11px] font-medium text-muted-foreground", children: t2("agenda.payment.cardBrand") }),
|
|
1528
|
-
/* @__PURE__ */ jsxs(
|
|
1529
|
-
"
|
|
1530
|
-
{
|
|
1531
|
-
|
|
1532
|
-
onChange: (e) => setCardBrand(e.target.value),
|
|
1533
|
-
className: "w-full mt-1 rounded-input border border-input bg-card shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] px-2.5 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring",
|
|
1534
|
-
children: [
|
|
1535
|
-
/* @__PURE__ */ jsx("option", { value: "", children: t2("agenda.payment.selectBrand") }),
|
|
1536
|
-
["Visa", "Mastercard", "American Express", "Elo", "Hipercard", "Diners Club"].map((b) => /* @__PURE__ */ jsx("option", { value: b, children: b }, b))
|
|
1537
|
-
]
|
|
1538
|
-
}
|
|
1539
|
-
)
|
|
1576
|
+
/* @__PURE__ */ jsxs(Select, { value: cardBrand, onValueChange: setCardBrand, children: [
|
|
1577
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "mt-1 bg-card px-2.5", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t2("agenda.payment.selectBrand") }) }),
|
|
1578
|
+
/* @__PURE__ */ jsx(SelectContent, { children: ["Visa", "Mastercard", "American Express", "Elo", "Hipercard", "Diners Club"].map((b) => /* @__PURE__ */ jsx(SelectItem, { value: b, children: b }, b)) })
|
|
1579
|
+
] })
|
|
1540
1580
|
] }),
|
|
1541
1581
|
needsCardInstallments && /* @__PURE__ */ jsxs("div", { children: [
|
|
1542
1582
|
/* @__PURE__ */ jsx("label", { className: "text-[11px] font-medium text-muted-foreground", children: t2("agenda.payment.cardInstallments") }),
|
|
1543
|
-
/* @__PURE__ */
|
|
1544
|
-
"
|
|
1545
|
-
{
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
"x ",
|
|
1552
|
-
n > 1 ? formatCurrency2(orderTotal / n) : ""
|
|
1553
|
-
] }, n))
|
|
1554
|
-
}
|
|
1555
|
-
)
|
|
1583
|
+
/* @__PURE__ */ jsxs(Select, { value: String(cardInstallments), onValueChange: (v) => setCardInstallments(Number(v)), children: [
|
|
1584
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "mt-1 bg-card px-2.5", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
1585
|
+
/* @__PURE__ */ jsx(SelectContent, { children: Array.from({ length: 12 }, (_, i) => i + 1).map((n) => /* @__PURE__ */ jsxs(SelectItem, { value: String(n), children: [
|
|
1586
|
+
n,
|
|
1587
|
+
"x ",
|
|
1588
|
+
n > 1 ? formatCurrency9(orderTotal / n) : ""
|
|
1589
|
+
] }, n)) })
|
|
1590
|
+
] })
|
|
1556
1591
|
] })
|
|
1557
1592
|
] }),
|
|
1558
1593
|
needsBank && bankAccounts.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
1559
1594
|
/* @__PURE__ */ jsx("label", { className: "text-[11px] font-medium text-muted-foreground", children: t2("agenda.payment.bankAccount") }),
|
|
1560
|
-
/* @__PURE__ */ jsxs(
|
|
1561
|
-
"
|
|
1562
|
-
{
|
|
1563
|
-
|
|
1564
|
-
onChange: (e) => setSelectedBankId(e.target.value),
|
|
1565
|
-
className: "w-full mt-1 rounded-input border border-input bg-card shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] px-2.5 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring",
|
|
1566
|
-
children: [
|
|
1567
|
-
/* @__PURE__ */ jsx("option", { value: "", children: t2("agenda.payment.selectAccount") }),
|
|
1568
|
-
bankAccounts.map((a) => /* @__PURE__ */ jsx("option", { value: a.id, children: a.name }, a.id))
|
|
1569
|
-
]
|
|
1570
|
-
}
|
|
1571
|
-
)
|
|
1595
|
+
/* @__PURE__ */ jsxs(Select, { value: selectedBankId, onValueChange: setSelectedBankId, children: [
|
|
1596
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "mt-1 bg-card px-2.5", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t2("agenda.payment.selectAccount") }) }),
|
|
1597
|
+
/* @__PURE__ */ jsx(SelectContent, { children: bankAccounts.map((a) => /* @__PURE__ */ jsx(SelectItem, { value: a.id, children: a.name }, a.id)) })
|
|
1598
|
+
] })
|
|
1572
1599
|
] })
|
|
1573
1600
|
] }),
|
|
1574
1601
|
/* @__PURE__ */ jsx(
|
|
1575
|
-
|
|
1602
|
+
Button,
|
|
1576
1603
|
{
|
|
1604
|
+
variant: "bare",
|
|
1605
|
+
size: "bare",
|
|
1577
1606
|
type: "button",
|
|
1578
1607
|
onClick: handleCheckout,
|
|
1579
1608
|
disabled: processing || !selectedTypeId,
|
|
1580
|
-
className: "w-full rounded-lg bg-primary border border-primary py-2.5 text-sm font-medium text-primary-foreground hover:bg-primary/90 shadow-button-primary active:shadow-button-inset disabled:opacity-40 transition-colors",
|
|
1581
|
-
children: processing ? t2("agenda.payment.checkingOut") : `${t2("agenda.payment.checkout")} ${
|
|
1609
|
+
className: "whitespace-normal w-full rounded-lg bg-primary border border-primary py-2.5 text-sm font-medium text-primary-foreground hover:bg-primary/90 shadow-button-primary active:shadow-button-inset disabled:opacity-40 transition-colors",
|
|
1610
|
+
children: processing ? t2("agenda.payment.checkingOut") : `${t2("agenda.payment.checkout")} ${formatCurrency9(orderTotal)}`
|
|
1582
1611
|
}
|
|
1583
1612
|
)
|
|
1584
1613
|
] })
|
|
@@ -1600,7 +1629,7 @@ function BookingPaymentPanel({ orderId, orderTotal, services, onClose, onPayment
|
|
|
1600
1629
|
children: [
|
|
1601
1630
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-5 py-4 border-b sticky top-0 bg-card z-10", children: [
|
|
1602
1631
|
/* @__PURE__ */ jsx("h3", { className: "text-base font-semibold", children: t2("agenda.payment.title") }),
|
|
1603
|
-
/* @__PURE__ */ jsx("
|
|
1632
|
+
/* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", onClick: handleClose, className: "p-1 text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }) })
|
|
1604
1633
|
] }),
|
|
1605
1634
|
content
|
|
1606
1635
|
]
|
|
@@ -1652,11 +1681,13 @@ function ClientContactButton({ phone, compact }) {
|
|
|
1652
1681
|
),
|
|
1653
1682
|
/* @__PURE__ */ jsxs(Dropdown, { children: [
|
|
1654
1683
|
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
1655
|
-
|
|
1684
|
+
Button,
|
|
1656
1685
|
{
|
|
1686
|
+
variant: "bare",
|
|
1687
|
+
size: "bare",
|
|
1657
1688
|
type: "button",
|
|
1658
1689
|
"aria-label": t2("agenda.confirmations.otherChannels"),
|
|
1659
|
-
className: "flex h-8 w-6 items-center justify-center border-l border-black/10 bg-[#25D366] text-white transition-all hover:brightness-105 active:scale-95",
|
|
1690
|
+
className: "rounded-none flex h-8 w-6 items-center justify-center border-l border-black/10 bg-[#25D366] text-white transition-all hover:brightness-105 active:scale-95",
|
|
1660
1691
|
children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5" })
|
|
1661
1692
|
}
|
|
1662
1693
|
) }),
|
|
@@ -1684,11 +1715,11 @@ function BookingCard({
|
|
|
1684
1715
|
style,
|
|
1685
1716
|
hideClient,
|
|
1686
1717
|
showMoney = true,
|
|
1687
|
-
formatCurrency:
|
|
1718
|
+
formatCurrency: formatCurrency9
|
|
1688
1719
|
}) {
|
|
1689
1720
|
const t2 = useTranslation();
|
|
1690
1721
|
const services = (booking.services ?? []).map((s) => s.name).join(", ");
|
|
1691
|
-
const fmt =
|
|
1722
|
+
const fmt = formatCurrency9 ?? ((v) => formatCurrency(v, "BRL"));
|
|
1692
1723
|
const money = showMoney && booking.orderTotal != null ? fmt(booking.orderTotal) : null;
|
|
1693
1724
|
const nome = booking.clientName ?? t2("agenda.confirmations.unknownClient");
|
|
1694
1725
|
return /* @__PURE__ */ jsxs(
|
|
@@ -1759,7 +1790,7 @@ function BookingCard({
|
|
|
1759
1790
|
}
|
|
1760
1791
|
);
|
|
1761
1792
|
}
|
|
1762
|
-
function ClientHistoryPanel({ clientId, currentBookingId, formatCurrency:
|
|
1793
|
+
function ClientHistoryPanel({ clientId, currentBookingId, formatCurrency: formatCurrency9 }) {
|
|
1763
1794
|
const t2 = useTranslation();
|
|
1764
1795
|
const config = useAgendaConfig();
|
|
1765
1796
|
const provider2 = useAgendaProvider();
|
|
@@ -1806,7 +1837,7 @@ function ClientHistoryPanel({ clientId, currentBookingId, formatCurrency: format
|
|
|
1806
1837
|
booking,
|
|
1807
1838
|
hideClient: true,
|
|
1808
1839
|
showDate: true,
|
|
1809
|
-
formatCurrency:
|
|
1840
|
+
formatCurrency: formatCurrency9,
|
|
1810
1841
|
className: isCurrent ? "border-primary/40 bg-primary/5" : "",
|
|
1811
1842
|
badge: config.capabilities.status ? /* @__PURE__ */ jsx(StatusBadge, { status: booking.status }) : void 0
|
|
1812
1843
|
},
|
|
@@ -1893,8 +1924,10 @@ function BookingInterestsPanel({ clientId, bookingId, value, onChange }) {
|
|
|
1893
1924
|
i.name,
|
|
1894
1925
|
!i.interestId && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-primary", children: "novo" }),
|
|
1895
1926
|
/* @__PURE__ */ jsx(
|
|
1896
|
-
|
|
1927
|
+
Button,
|
|
1897
1928
|
{
|
|
1929
|
+
variant: "bare",
|
|
1930
|
+
size: "bare",
|
|
1898
1931
|
type: "button",
|
|
1899
1932
|
onClick: () => remove(i.key),
|
|
1900
1933
|
"aria-label": `Remover ${i.name} deste agendamento`,
|
|
@@ -1908,8 +1941,10 @@ function BookingInterestsPanel({ clientId, bookingId, value, onChange }) {
|
|
|
1908
1941
|
removedCrm.map((i) => /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-border px-2 py-0.5 text-xs opacity-70", children: [
|
|
1909
1942
|
i.name,
|
|
1910
1943
|
/* @__PURE__ */ jsx(
|
|
1911
|
-
|
|
1944
|
+
Button,
|
|
1912
1945
|
{
|
|
1946
|
+
variant: "bare",
|
|
1947
|
+
size: "bare",
|
|
1913
1948
|
type: "button",
|
|
1914
1949
|
onClick: () => addBack(i),
|
|
1915
1950
|
"aria-label": `Vincular ${i.name} a este agendamento`,
|
|
@@ -1971,12 +2006,14 @@ function BookingPrepaidPanel({ clientId, addedServiceIds, onAdd }) {
|
|
|
1971
2006
|
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: [...grouped.values()].map(({ item, count }) => {
|
|
1972
2007
|
const added = addedServiceIds.includes(item.serviceId);
|
|
1973
2008
|
return /* @__PURE__ */ jsxs(
|
|
1974
|
-
|
|
2009
|
+
Button,
|
|
1975
2010
|
{
|
|
2011
|
+
variant: "bare",
|
|
2012
|
+
size: "bare",
|
|
1976
2013
|
type: "button",
|
|
1977
2014
|
disabled: added,
|
|
1978
2015
|
onClick: () => onAdd(item),
|
|
1979
|
-
className: `inline-flex items-center gap-1 rounded-full border px-2.5 py-0.5 text-xs transition-colors ${added ? "border-primary/40 bg-card text-muted-foreground" : "border-transparent bg-card hover:border-primary/40"}`,
|
|
2016
|
+
className: `font-normal ${`inline-flex items-center gap-1 rounded-full border px-2.5 py-0.5 text-xs transition-colors ${added ? "border-primary/40 bg-card text-muted-foreground" : "border-transparent bg-card hover:border-primary/40"}`}`,
|
|
1980
2017
|
children: [
|
|
1981
2018
|
added ? /* @__PURE__ */ jsx(Check, { className: "h-3 w-3 text-primary", "aria-hidden": true }) : /* @__PURE__ */ jsx(Plus, { className: "h-3 w-3", "aria-hidden": true }),
|
|
1982
2019
|
item.serviceName,
|
|
@@ -2035,8 +2072,10 @@ function BookingRevisionPanel({ clientId, value, onChange, onState }) {
|
|
|
2035
2072
|
/* @__PURE__ */ jsx("ul", { className: "space-y-1", role: "radiogroup", "aria-label": "Servi\xE7o revisado", children: rows.map((c) => {
|
|
2036
2073
|
const on = value?.sessionId === c.sessionId;
|
|
2037
2074
|
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
2038
|
-
|
|
2075
|
+
Button,
|
|
2039
2076
|
{
|
|
2077
|
+
variant: "bare",
|
|
2078
|
+
size: "bare",
|
|
2040
2079
|
type: "button",
|
|
2041
2080
|
role: "radio",
|
|
2042
2081
|
"aria-checked": on,
|
|
@@ -2045,7 +2084,7 @@ function BookingRevisionPanel({ clientId, value, onChange, onState }) {
|
|
|
2045
2084
|
revisionNumber: c.nextRevisionNumber,
|
|
2046
2085
|
serviceName: c.serviceName
|
|
2047
2086
|
}),
|
|
2048
|
-
className: `flex w-full items-center gap-2 rounded-md border px-2.5 py-1.5 text-left text-xs transition-colors ${on ? "border-primary bg-card" : "border-transparent bg-card/60 hover:bg-card"}`,
|
|
2087
|
+
className: `font-normal whitespace-normal justify-start ${`flex w-full items-center gap-2 rounded-md border px-2.5 py-1.5 text-left text-xs transition-colors ${on ? "border-primary bg-card" : "border-transparent bg-card/60 hover:bg-card"}`}`,
|
|
2049
2088
|
children: [
|
|
2050
2089
|
/* @__PURE__ */ jsx("span", { className: `flex h-4 w-4 shrink-0 items-center justify-center rounded-full border ${on ? "border-primary bg-primary text-primary-foreground" : "border-muted-foreground/40"}`, children: on && /* @__PURE__ */ jsx(Check, { className: "h-3 w-3", "aria-hidden": true }) }),
|
|
2051
2090
|
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
@@ -2081,9 +2120,6 @@ var BOOKING_TYPE_ICONS = {
|
|
|
2081
2120
|
CheckSquare,
|
|
2082
2121
|
Ban
|
|
2083
2122
|
};
|
|
2084
|
-
function fmtCurrency(amount, locale, code) {
|
|
2085
|
-
return new Intl.NumberFormat(locale, { style: "currency", currency: code }).format(amount);
|
|
2086
|
-
}
|
|
2087
2123
|
function formatCompactDate(dateStr, locale) {
|
|
2088
2124
|
const d = /* @__PURE__ */ new Date(dateStr + "T00:00:00");
|
|
2089
2125
|
return d.toLocaleDateString(locale === "pt-BR" ? "pt-BR" : "en-US", {
|
|
@@ -2110,8 +2146,8 @@ function InlineNumber({ value, onChange, min = 0, step = 1, className, disabled,
|
|
|
2110
2146
|
setDraft(String(value));
|
|
2111
2147
|
}
|
|
2112
2148
|
}
|
|
2113
|
-
const input = /* @__PURE__ */ jsx(
|
|
2114
|
-
|
|
2149
|
+
const input = /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(
|
|
2150
|
+
Input,
|
|
2115
2151
|
{
|
|
2116
2152
|
type: "text",
|
|
2117
2153
|
inputMode: "decimal",
|
|
@@ -2129,12 +2165,9 @@ function InlineNumber({ value, onChange, min = 0, step = 1, className, disabled,
|
|
|
2129
2165
|
}
|
|
2130
2166
|
},
|
|
2131
2167
|
disabled,
|
|
2132
|
-
className:
|
|
2133
|
-
"text-right text-[11px] text-muted-foreground bg-transparent border-b border-transparent hover:border-muted-foreground/40 focus:border-foreground focus:outline-none tabular-nums",
|
|
2134
|
-
className
|
|
2135
|
-
)
|
|
2168
|
+
className: "h-auto rounded-none border-0 border-b border-transparent bg-transparent p-0 text-right text-[11px] text-muted-foreground tabular-nums shadow-none hover:border-muted-foreground/40 focus:border-foreground focus-visible:ring-0 focus-visible:ring-offset-0"
|
|
2136
2169
|
}
|
|
2137
|
-
);
|
|
2170
|
+
) });
|
|
2138
2171
|
if (!tooltip) return input;
|
|
2139
2172
|
return /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 400, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
2140
2173
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: input }),
|
|
@@ -2165,12 +2198,14 @@ function StatusSelect({ value, onChange, statuses, bookingDate }) {
|
|
|
2165
2198
|
}
|
|
2166
2199
|
return /* @__PURE__ */ jsxs("div", { ref, className: "relative flex-1", children: [
|
|
2167
2200
|
/* @__PURE__ */ jsxs(
|
|
2168
|
-
|
|
2201
|
+
Button,
|
|
2169
2202
|
{
|
|
2203
|
+
variant: "bare",
|
|
2204
|
+
size: "bare",
|
|
2170
2205
|
ref: btnRef,
|
|
2171
2206
|
type: "button",
|
|
2172
2207
|
onClick: handleOpen,
|
|
2173
|
-
className: "flex items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-muted/30 transition-colors text-left w-full",
|
|
2208
|
+
className: "font-normal justify-start whitespace-normal flex items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-muted/30 transition-colors text-left w-full",
|
|
2174
2209
|
children: [
|
|
2175
2210
|
current && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2176
2211
|
/* @__PURE__ */ jsx("span", { className: "h-2 w-2 rounded-full shrink-0", style: { backgroundColor: current.color } }),
|
|
@@ -2191,8 +2226,10 @@ function StatusSelect({ value, onChange, statuses, bookingDate }) {
|
|
|
2191
2226
|
children: statuses.map((s) => {
|
|
2192
2227
|
const available = !bookingDate || isStatusAvailable(s, bookingDate);
|
|
2193
2228
|
return /* @__PURE__ */ jsxs(
|
|
2194
|
-
|
|
2229
|
+
Button,
|
|
2195
2230
|
{
|
|
2231
|
+
variant: "bare",
|
|
2232
|
+
size: "bare",
|
|
2196
2233
|
type: "button",
|
|
2197
2234
|
disabled: !available,
|
|
2198
2235
|
onClick: () => {
|
|
@@ -2201,7 +2238,7 @@ function StatusSelect({ value, onChange, statuses, bookingDate }) {
|
|
|
2201
2238
|
setOpen(false);
|
|
2202
2239
|
}
|
|
2203
2240
|
},
|
|
2204
|
-
className: `flex w-full items-center gap-2.5 px-3 py-1.5 text-sm transition-colors ${!available ? "
|
|
2241
|
+
className: `font-normal justify-start whitespace-normal flex w-full items-center gap-2.5 px-3 py-1.5 text-sm transition-colors ${!available ? "disabled:pointer-events-auto disabled:cursor-not-allowed disabled:opacity-30" : s.value === value ? "bg-muted/30" : "hover:bg-muted/50"}`,
|
|
2205
2242
|
children: [
|
|
2206
2243
|
/* @__PURE__ */ jsx("span", { className: "h-2 w-2 rounded-full shrink-0", style: { backgroundColor: s.color } }),
|
|
2207
2244
|
/* @__PURE__ */ jsx("span", { children: s.label })
|
|
@@ -2251,11 +2288,13 @@ function LocationSelect({ value, onChange, locations, placeholder }) {
|
|
|
2251
2288
|
}, [open]);
|
|
2252
2289
|
return /* @__PURE__ */ jsxs("div", { ref, className: "relative flex-1", children: [
|
|
2253
2290
|
/* @__PURE__ */ jsxs(
|
|
2254
|
-
|
|
2291
|
+
Button,
|
|
2255
2292
|
{
|
|
2293
|
+
variant: "bare",
|
|
2294
|
+
size: "bare",
|
|
2256
2295
|
type: "button",
|
|
2257
2296
|
onClick: () => setOpen((p) => !p),
|
|
2258
|
-
className: "flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-muted/30 transition-colors text-left",
|
|
2297
|
+
className: "font-normal justify-start whitespace-normal flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-muted/30 transition-colors text-left",
|
|
2259
2298
|
children: [
|
|
2260
2299
|
current ? /* @__PURE__ */ jsx("span", { children: current.name }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder ?? t2("agenda.appointment.selectLocation") }),
|
|
2261
2300
|
/* @__PURE__ */ jsx("svg", { className: "ml-auto h-3 w-3 text-muted-foreground shrink-0", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
@@ -2263,14 +2302,16 @@ function LocationSelect({ value, onChange, locations, placeholder }) {
|
|
|
2263
2302
|
}
|
|
2264
2303
|
),
|
|
2265
2304
|
open && /* @__PURE__ */ jsx("div", { className: "fayz-glass-surface absolute top-full left-0 right-0 z-50 mt-1 rounded-lg border bg-popover shadow-lg py-1 animate-in fade-in zoom-in-95 duration-100 max-h-48 overflow-y-auto", children: locations.map((l) => /* @__PURE__ */ jsx(
|
|
2266
|
-
|
|
2305
|
+
Button,
|
|
2267
2306
|
{
|
|
2307
|
+
variant: "bare",
|
|
2308
|
+
size: "bare",
|
|
2268
2309
|
type: "button",
|
|
2269
2310
|
onClick: () => {
|
|
2270
2311
|
onChange(l.id);
|
|
2271
2312
|
setOpen(false);
|
|
2272
2313
|
},
|
|
2273
|
-
className: `flex w-full items-center gap-2 px-3 py-1.5 text-sm hover:bg-muted/50 transition-colors ${l.id === value ? "bg-muted/30" : ""}`,
|
|
2314
|
+
className: `font-normal justify-start rounded-none whitespace-normal flex w-full items-center gap-2 px-3 py-1.5 text-sm hover:bg-muted/50 transition-colors ${l.id === value ? "bg-muted/30" : ""}`,
|
|
2274
2315
|
children: /* @__PURE__ */ jsx("span", { children: l.name })
|
|
2275
2316
|
},
|
|
2276
2317
|
l.id
|
|
@@ -2893,8 +2934,9 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
2893
2934
|
hint: clientSearch || void 0,
|
|
2894
2935
|
onClose: () => setPreenchendoForm(null),
|
|
2895
2936
|
children: /* @__PURE__ */ jsx(
|
|
2896
|
-
|
|
2937
|
+
WidgetSlot,
|
|
2897
2938
|
{
|
|
2939
|
+
zone: FORMS_ZONES.formFill,
|
|
2898
2940
|
frame: "inline",
|
|
2899
2941
|
templateId: preenchendoForm,
|
|
2900
2942
|
personId: clientId,
|
|
@@ -2912,8 +2954,10 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
2912
2954
|
const isActive = bookingType === bt.id;
|
|
2913
2955
|
const BtIcon = BOOKING_TYPE_ICONS[bt.icon] ?? Calendar;
|
|
2914
2956
|
return /* @__PURE__ */ jsxs(
|
|
2915
|
-
|
|
2957
|
+
Button,
|
|
2916
2958
|
{
|
|
2959
|
+
variant: "bare",
|
|
2960
|
+
size: "bare",
|
|
2917
2961
|
type: "button",
|
|
2918
2962
|
onClick: () => setBookingType(bt.id),
|
|
2919
2963
|
className: `relative flex items-center gap-1.5 pb-2 px-2 text-xs font-medium transition-colors ${isActive ? "text-foreground" : "text-muted-foreground hover:text-foreground"}`,
|
|
@@ -2937,8 +2981,10 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
2937
2981
|
].filter((tab) => tab.show).map((tab) => {
|
|
2938
2982
|
const isActive = modalTab === tab.id;
|
|
2939
2983
|
return /* @__PURE__ */ jsxs(
|
|
2940
|
-
|
|
2984
|
+
Button,
|
|
2941
2985
|
{
|
|
2986
|
+
variant: "bare",
|
|
2987
|
+
size: "bare",
|
|
2942
2988
|
type: "button",
|
|
2943
2989
|
onClick: () => setModalTab(tab.id),
|
|
2944
2990
|
className: `relative flex items-center gap-1.5 pb-2 px-2 text-xs font-medium transition-colors ${isActive ? "text-foreground" : "text-muted-foreground hover:text-foreground"}`,
|
|
@@ -2979,27 +3025,29 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
2979
3025
|
setEditingTime(true);
|
|
2980
3026
|
},
|
|
2981
3027
|
children: [
|
|
2982
|
-
editingDate ? /* @__PURE__ */ jsx(
|
|
2983
|
-
|
|
3028
|
+
editingDate ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsx(
|
|
3029
|
+
Input,
|
|
2984
3030
|
{
|
|
2985
3031
|
type: "date",
|
|
2986
3032
|
value: date,
|
|
2987
3033
|
autoFocus: true,
|
|
2988
3034
|
onChange: (e) => setDate(e.target.value),
|
|
2989
3035
|
onBlur: () => setEditingDate(false),
|
|
2990
|
-
className: "w-auto
|
|
3036
|
+
className: "h-auto w-auto rounded-none border-0 border-b border-foreground bg-transparent p-0 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 font-medium"
|
|
2991
3037
|
}
|
|
2992
|
-
) : /* @__PURE__ */ jsx(
|
|
2993
|
-
|
|
3038
|
+
) }) : /* @__PURE__ */ jsx(
|
|
3039
|
+
Button,
|
|
2994
3040
|
{
|
|
3041
|
+
variant: "bare",
|
|
3042
|
+
size: "bare",
|
|
2995
3043
|
type: "button",
|
|
2996
3044
|
onClick: () => setEditingDate(true),
|
|
2997
|
-
className: "shrink-0 border-b border-transparent px-0.5 py-0.5 font-medium transition-colors hover:border-foreground",
|
|
3045
|
+
className: "rounded-none shrink-0 border-b border-transparent px-0.5 py-0.5 font-medium transition-colors hover:border-foreground",
|
|
2998
3046
|
children: formatCompactDate(date, locale)
|
|
2999
3047
|
}
|
|
3000
3048
|
),
|
|
3001
|
-
editingTime ? /* @__PURE__ */ jsx(
|
|
3002
|
-
|
|
3049
|
+
editingTime ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsx(
|
|
3050
|
+
Input,
|
|
3003
3051
|
{
|
|
3004
3052
|
type: "time",
|
|
3005
3053
|
value: startTime,
|
|
@@ -3008,20 +3056,22 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3008
3056
|
if (e.target.value) setStartTime(e.target.value);
|
|
3009
3057
|
},
|
|
3010
3058
|
onBlur: () => setEditingTime(false),
|
|
3011
|
-
className: "w-auto
|
|
3059
|
+
className: "h-auto w-auto rounded-none border-0 border-b border-foreground bg-transparent p-0 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 text-xs text-muted-foreground"
|
|
3012
3060
|
}
|
|
3013
|
-
) : /* @__PURE__ */ jsx(
|
|
3014
|
-
|
|
3061
|
+
) }) : /* @__PURE__ */ jsx(
|
|
3062
|
+
Button,
|
|
3015
3063
|
{
|
|
3064
|
+
variant: "bare",
|
|
3065
|
+
size: "bare",
|
|
3016
3066
|
type: "button",
|
|
3017
3067
|
onClick: () => setEditingTime(true),
|
|
3018
|
-
className: "shrink-0 border-b border-transparent px-0.5 py-0.5 text-xs text-muted-foreground transition-colors hover:border-foreground",
|
|
3068
|
+
className: "font-normal rounded-none shrink-0 border-b border-transparent px-0.5 py-0.5 text-xs text-muted-foreground transition-colors hover:border-foreground",
|
|
3019
3069
|
children: startTime
|
|
3020
3070
|
}
|
|
3021
3071
|
),
|
|
3022
3072
|
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground/60", children: "\u2014" }),
|
|
3023
|
-
editingEnd ? /* @__PURE__ */ jsx(
|
|
3024
|
-
|
|
3073
|
+
editingEnd ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsx(
|
|
3074
|
+
Input,
|
|
3025
3075
|
{
|
|
3026
3076
|
type: "time",
|
|
3027
3077
|
value: endDraft ?? endTime,
|
|
@@ -3035,15 +3085,17 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3035
3085
|
setEndDraft(null);
|
|
3036
3086
|
setEditingEnd(false);
|
|
3037
3087
|
},
|
|
3038
|
-
className: "w-auto
|
|
3088
|
+
className: "h-auto w-auto rounded-none border-0 border-b border-foreground bg-transparent p-0 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 text-xs text-muted-foreground"
|
|
3039
3089
|
}
|
|
3040
|
-
) : /* @__PURE__ */ jsx(
|
|
3041
|
-
|
|
3090
|
+
) }) : /* @__PURE__ */ jsx(
|
|
3091
|
+
Button,
|
|
3042
3092
|
{
|
|
3093
|
+
variant: "bare",
|
|
3094
|
+
size: "bare",
|
|
3043
3095
|
type: "button",
|
|
3044
3096
|
onClick: () => setEditingEnd(true),
|
|
3045
3097
|
"aria-label": t2("agenda.appointment.endTime"),
|
|
3046
|
-
className: "shrink-0 border-b border-transparent px-0.5 py-0.5 text-xs text-muted-foreground transition-colors hover:border-foreground",
|
|
3098
|
+
className: "font-normal shrink-0 border-b border-transparent px-0.5 py-0.5 text-xs text-muted-foreground transition-colors hover:border-foreground",
|
|
3047
3099
|
children: endTime
|
|
3048
3100
|
}
|
|
3049
3101
|
),
|
|
@@ -3079,8 +3131,8 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3079
3131
|
] })
|
|
3080
3132
|
] }),
|
|
3081
3133
|
recurrenceEndMode === "count" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3082
|
-
/* @__PURE__ */ jsx(
|
|
3083
|
-
|
|
3134
|
+
/* @__PURE__ */ jsx("div", { className: "w-10 shrink-0", children: /* @__PURE__ */ jsx(
|
|
3135
|
+
Input,
|
|
3084
3136
|
{
|
|
3085
3137
|
type: "number",
|
|
3086
3138
|
min: 1,
|
|
@@ -3088,9 +3140,9 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3088
3140
|
value: recurrenceCount,
|
|
3089
3141
|
onChange: (e) => setRecurrenceCount(Number(e.target.value) || 1),
|
|
3090
3142
|
"aria-label": t2("agenda.recurrence.countLabel"),
|
|
3091
|
-
className: "
|
|
3143
|
+
className: "h-auto rounded-none border-0 border-b border-foreground bg-transparent p-0 text-center text-xs shadow-none focus-visible:ring-0 focus-visible:ring-offset-0"
|
|
3092
3144
|
}
|
|
3093
|
-
),
|
|
3145
|
+
) }),
|
|
3094
3146
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t2("agenda.recurrence.times") })
|
|
3095
3147
|
] }) : /* @__PURE__ */ jsx(DatePicker, { value: recurrenceUntil, onChange: setRecurrenceUntil })
|
|
3096
3148
|
] })
|
|
@@ -3175,12 +3227,13 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3175
3227
|
{
|
|
3176
3228
|
clientId,
|
|
3177
3229
|
currentBookingId: bookingId,
|
|
3178
|
-
formatCurrency: (v) =>
|
|
3230
|
+
formatCurrency: (v) => formatCurrency(v, currency.code)
|
|
3179
3231
|
}
|
|
3180
3232
|
) }),
|
|
3181
3233
|
modalTab === "financial" && clientId && /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto px-5 py-4", children: /* @__PURE__ */ jsx(
|
|
3182
|
-
|
|
3234
|
+
WidgetSlot,
|
|
3183
3235
|
{
|
|
3236
|
+
zone: FINANCIAL_ZONES.clientAccountInline,
|
|
3184
3237
|
personId: clientId,
|
|
3185
3238
|
orderId: editOrderId,
|
|
3186
3239
|
clientName: clientSearch || void 0,
|
|
@@ -3224,7 +3277,7 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3224
3277
|
orderId: editOrderId,
|
|
3225
3278
|
orderTotal: editOrderTotal,
|
|
3226
3279
|
services: services.map((s) => ({ name: s.name, price: s.price, durationMinutes: s.durationMinutes })),
|
|
3227
|
-
formatCurrency: (v) =>
|
|
3280
|
+
formatCurrency: (v) => formatCurrency(v, currency.code),
|
|
3228
3281
|
inline: true,
|
|
3229
3282
|
onClose: () => setModalTab("appointment"),
|
|
3230
3283
|
onPaymentChange: () => {
|
|
@@ -3248,8 +3301,8 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3248
3301
|
!loading && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3249
3302
|
activeType.fields.title && /* @__PURE__ */ jsxs("div", { className: `${ROW_CENTER} py-1`, children: [
|
|
3250
3303
|
/* @__PURE__ */ jsx(Calendar, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
|
|
3251
|
-
/* @__PURE__ */ jsx(
|
|
3252
|
-
|
|
3304
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
3305
|
+
Input,
|
|
3253
3306
|
{
|
|
3254
3307
|
type: "text",
|
|
3255
3308
|
value: title,
|
|
@@ -3257,9 +3310,9 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3257
3310
|
placeholder: t2("agenda.appointment.addTitle"),
|
|
3258
3311
|
autoFocus: mode === "create",
|
|
3259
3312
|
"aria-required": true,
|
|
3260
|
-
className: "
|
|
3313
|
+
className: "px-2.5 font-medium"
|
|
3261
3314
|
}
|
|
3262
|
-
)
|
|
3315
|
+
) })
|
|
3263
3316
|
] }),
|
|
3264
3317
|
activeType.fields.client && /* @__PURE__ */ jsxs("div", { className: `${ROW_CENTER} py-1`, children: [
|
|
3265
3318
|
/* @__PURE__ */ jsx(User, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
|
|
@@ -3284,7 +3337,7 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3284
3337
|
) })
|
|
3285
3338
|
] }),
|
|
3286
3339
|
activeType.fields.client && clientId && /* @__PURE__ */ jsxs("div", { className: "pl-7", children: [
|
|
3287
|
-
/* @__PURE__ */ jsx(
|
|
3340
|
+
/* @__PURE__ */ jsx(WidgetSlot, { zone: FORMS_ZONES.personChecklist, personId: clientId, version: formsVersao, onFill: (t3) => setPreenchendoForm(t3) }),
|
|
3288
3341
|
activeType.fields.services && /* @__PURE__ */ jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsx(
|
|
3289
3342
|
BookingPrepaidPanel,
|
|
3290
3343
|
{
|
|
@@ -3307,8 +3360,10 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3307
3360
|
children: [
|
|
3308
3361
|
a.name,
|
|
3309
3362
|
/* @__PURE__ */ jsx(
|
|
3310
|
-
|
|
3363
|
+
Button,
|
|
3311
3364
|
{
|
|
3365
|
+
variant: "bare",
|
|
3366
|
+
size: "bare",
|
|
3312
3367
|
type: "button",
|
|
3313
3368
|
"aria-label": t2("agenda.attendees.remove"),
|
|
3314
3369
|
onClick: () => setAttendees((p) => p.filter((x) => x.personId !== a.personId)),
|
|
@@ -3397,7 +3452,7 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3397
3452
|
}
|
|
3398
3453
|
)
|
|
3399
3454
|
] }),
|
|
3400
|
-
!isPaidBooking && /* @__PURE__ */ jsx("
|
|
3455
|
+
!isPaidBooking && /* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", type: "button", onClick: () => removeService(idx), className: "p-0.5 ml-2 text-muted-foreground hover:text-destructive shrink-0", children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" }) })
|
|
3401
3456
|
] }, idx)) }),
|
|
3402
3457
|
serviceCreate.creating && serviceCreate.form,
|
|
3403
3458
|
!isPaidBooking && !serviceCreate.creating && /* @__PURE__ */ jsx(
|
|
@@ -3418,7 +3473,7 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3418
3473
|
const hasPrice = opt.price != null;
|
|
3419
3474
|
if (!hasPrice && !dur) return null;
|
|
3420
3475
|
return /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground text-xs whitespace-nowrap", children: [
|
|
3421
|
-
hasPrice &&
|
|
3476
|
+
hasPrice && formatCurrency(opt.price, currency.code),
|
|
3422
3477
|
hasPrice && dur > 0 && " \xB7 ",
|
|
3423
3478
|
dur > 0 && `${dur}min`
|
|
3424
3479
|
] });
|
|
@@ -3461,31 +3516,29 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3461
3516
|
/* @__PURE__ */ jsx(Ban, { className: "h-4 w-4 mt-2 text-muted-foreground shrink-0" }),
|
|
3462
3517
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
|
|
3463
3518
|
/* @__PURE__ */ jsxs(
|
|
3464
|
-
|
|
3519
|
+
Select,
|
|
3465
3520
|
{
|
|
3466
3521
|
value: cancellationReasonId,
|
|
3467
|
-
|
|
3522
|
+
onValueChange: setCancellationReasonId,
|
|
3468
3523
|
disabled: cancellationReasonsLoading,
|
|
3469
|
-
"aria-required": true,
|
|
3470
|
-
className: "w-full rounded-input border border-input bg-card px-2.5 py-1.5 text-sm shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] focus:outline-none focus:ring-2 focus:ring-ring",
|
|
3471
3524
|
children: [
|
|
3472
|
-
/* @__PURE__ */ jsx(
|
|
3473
|
-
cancellationReasons.map((reason) => /* @__PURE__ */ jsxs(
|
|
3525
|
+
/* @__PURE__ */ jsx(SelectTrigger, { "aria-required": true, className: "bg-card px-2.5", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: cancellationReasonsLoading ? t2("agenda.cancellation.loadingReasons") : t2("agenda.cancellation.selectReason") }) }),
|
|
3526
|
+
/* @__PURE__ */ jsx(SelectContent, { children: cancellationReasons.map((reason) => /* @__PURE__ */ jsxs(SelectItem, { value: reason.id, children: [
|
|
3474
3527
|
reason.label,
|
|
3475
3528
|
reason.requiresNotes ? " *" : ""
|
|
3476
|
-
] }, reason.id))
|
|
3529
|
+
] }, reason.id)) })
|
|
3477
3530
|
]
|
|
3478
3531
|
}
|
|
3479
3532
|
),
|
|
3480
3533
|
/* @__PURE__ */ jsx(
|
|
3481
|
-
|
|
3534
|
+
Textarea,
|
|
3482
3535
|
{
|
|
3483
3536
|
value: cancellationNotes,
|
|
3484
3537
|
onChange: (event) => setCancellationNotes(event.target.value),
|
|
3485
3538
|
placeholder: needsCancellationNotes ? t2("agenda.cancellation.notesRequired") : t2("agenda.cancellation.notesOptional"),
|
|
3486
3539
|
rows: 2,
|
|
3487
3540
|
"aria-required": needsCancellationNotes || void 0,
|
|
3488
|
-
className: "
|
|
3541
|
+
className: "resize-none px-2.5 py-1.5"
|
|
3489
3542
|
}
|
|
3490
3543
|
)
|
|
3491
3544
|
] })
|
|
@@ -3493,27 +3546,29 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3493
3546
|
!showNotes ? /* @__PURE__ */ jsxs("div", { className: `${ROW_CENTER} py-1`, children: [
|
|
3494
3547
|
/* @__PURE__ */ jsx(FileText, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
|
|
3495
3548
|
/* @__PURE__ */ jsx(
|
|
3496
|
-
|
|
3549
|
+
Button,
|
|
3497
3550
|
{
|
|
3551
|
+
variant: "bare",
|
|
3552
|
+
size: "bare",
|
|
3498
3553
|
type: "button",
|
|
3499
3554
|
onClick: () => setShowNotes(true),
|
|
3500
|
-
className: "text-sm text-muted-foreground hover:text-foreground transition-colors text-left py-1.5 pl-2",
|
|
3555
|
+
className: "font-normal whitespace-normal text-sm text-muted-foreground hover:text-foreground transition-colors text-left py-1.5 pl-2",
|
|
3501
3556
|
children: t2("agenda.appointment.addNotes")
|
|
3502
3557
|
}
|
|
3503
3558
|
)
|
|
3504
3559
|
] }) : /* @__PURE__ */ jsxs("div", { className: `${ROW_TOP} py-1`, children: [
|
|
3505
3560
|
/* @__PURE__ */ jsx(FileText, { className: "h-4 w-4 mt-2 text-muted-foreground shrink-0" }),
|
|
3506
|
-
/* @__PURE__ */ jsx(
|
|
3507
|
-
|
|
3561
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
3562
|
+
Textarea,
|
|
3508
3563
|
{
|
|
3509
3564
|
value: notes,
|
|
3510
3565
|
onChange: (e) => setNotes(e.target.value),
|
|
3511
3566
|
placeholder: t2("agenda.appointment.addDescription"),
|
|
3512
3567
|
rows: 2,
|
|
3513
3568
|
autoFocus: true,
|
|
3514
|
-
className: "
|
|
3569
|
+
className: "min-h-0 resize-none px-2.5 py-1.5"
|
|
3515
3570
|
}
|
|
3516
|
-
)
|
|
3571
|
+
) })
|
|
3517
3572
|
] })
|
|
3518
3573
|
] })
|
|
3519
3574
|
] }),
|
|
@@ -3525,14 +3580,16 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3525
3580
|
] })
|
|
3526
3581
|
] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
3527
3582
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
3528
|
-
mode === "edit" && /* @__PURE__ */ jsx("
|
|
3583
|
+
mode === "edit" && /* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", type: "button", onClick: () => setConfirmingDelete(true), className: "text-xs text-destructive font-medium hover:underline", children: t2("agenda.appointment.delete") }),
|
|
3529
3584
|
services.length > 0 && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
3530
3585
|
/* @__PURE__ */ jsx(Clock, { className: "h-3 w-3" }),
|
|
3531
3586
|
totalDuration,
|
|
3532
3587
|
"min",
|
|
3533
3588
|
config.modules.financial && totalPrice > 0 && mode === "edit" ? paymentStatusLoading ? /* @__PURE__ */ jsx("span", { className: "h-4 w-16 rounded-full bg-muted animate-pulse" }) : isPaidBooking ? /* @__PURE__ */ jsxs(
|
|
3534
|
-
|
|
3589
|
+
Button,
|
|
3535
3590
|
{
|
|
3591
|
+
variant: "bare",
|
|
3592
|
+
size: "bare",
|
|
3536
3593
|
type: "button",
|
|
3537
3594
|
onClick: (e) => {
|
|
3538
3595
|
e.stopPropagation();
|
|
@@ -3541,14 +3598,16 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3541
3598
|
className: "inline-flex items-center gap-1 rounded-full bg-success/10 px-2 py-0.5 text-[10px] font-medium text-success hover:bg-success/20 transition-colors",
|
|
3542
3599
|
children: [
|
|
3543
3600
|
/* @__PURE__ */ jsx(Check, { className: "h-2.5 w-2.5" }),
|
|
3544
|
-
|
|
3601
|
+
formatCurrency(totalPrice, currency.code),
|
|
3545
3602
|
" \xB7 ",
|
|
3546
3603
|
t2("agenda.payment.paid")
|
|
3547
3604
|
]
|
|
3548
3605
|
}
|
|
3549
3606
|
) : date <= todayLocal() ? /* @__PURE__ */ jsxs(
|
|
3550
|
-
|
|
3607
|
+
Button,
|
|
3551
3608
|
{
|
|
3609
|
+
variant: "bare",
|
|
3610
|
+
size: "bare",
|
|
3552
3611
|
type: "button",
|
|
3553
3612
|
onClick: (e) => {
|
|
3554
3613
|
e.stopPropagation();
|
|
@@ -3557,24 +3616,26 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3557
3616
|
className: "inline-flex items-center gap-1 rounded-full bg-warning/10 px-2 py-0.5 text-[10px] font-medium text-warning hover:bg-warning/20 transition-colors",
|
|
3558
3617
|
children: [
|
|
3559
3618
|
/* @__PURE__ */ jsx(HandCoins, { className: "h-3 w-3" }),
|
|
3560
|
-
|
|
3619
|
+
formatCurrency(totalPrice, currency.code),
|
|
3561
3620
|
" \xB7 ",
|
|
3562
3621
|
t2("agenda.payment.collect")
|
|
3563
3622
|
]
|
|
3564
3623
|
}
|
|
3565
3624
|
) : /* @__PURE__ */ jsxs("span", { children: [
|
|
3566
3625
|
"\xB7 ",
|
|
3567
|
-
|
|
3626
|
+
formatCurrency(totalPrice, currency.code)
|
|
3568
3627
|
] }) : /* @__PURE__ */ jsxs("span", { children: [
|
|
3569
3628
|
"\xB7 ",
|
|
3570
|
-
|
|
3629
|
+
formatCurrency(totalPrice, currency.code)
|
|
3571
3630
|
] })
|
|
3572
3631
|
] })
|
|
3573
3632
|
] }),
|
|
3574
3633
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3575
3634
|
mode === "edit" && date === todayLocal() && (status === "scheduled" || status === "confirmed") && bookingId && /* @__PURE__ */ jsxs(
|
|
3576
|
-
|
|
3635
|
+
Button,
|
|
3577
3636
|
{
|
|
3637
|
+
variant: "bare",
|
|
3638
|
+
size: "bare",
|
|
3578
3639
|
type: "button",
|
|
3579
3640
|
disabled: markingWaiting,
|
|
3580
3641
|
onClick: async () => {
|
|
@@ -3598,8 +3659,10 @@ function AppointmentModal({ open, mode, bookingId, prefill, initialTab, external
|
|
|
3598
3659
|
] }) })
|
|
3599
3660
|
] }),
|
|
3600
3661
|
modalTab !== "appointment" && !clientEditing && /* @__PURE__ */ jsx("div", { className: "px-5 py-2.5 pb-[calc(0.625rem+env(safe-area-inset-bottom))] sm:pb-2.5 border-t fayz-glass-divider bg-transparent shrink-0", children: /* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxs(
|
|
3601
|
-
|
|
3662
|
+
Button,
|
|
3602
3663
|
{
|
|
3664
|
+
variant: "bare",
|
|
3665
|
+
size: "bare",
|
|
3603
3666
|
type: "button",
|
|
3604
3667
|
onClick: () => {
|
|
3605
3668
|
setModalTab("appointment");
|
|
@@ -3770,13 +3833,15 @@ function useSeriesDelete(booking, enabled, onDone) {
|
|
|
3770
3833
|
function SeriesDeleteChoice({ seriesSize, deleting, onPick, onCancel }) {
|
|
3771
3834
|
const t2 = useTranslation();
|
|
3772
3835
|
const allLabel = t2("agenda.recurrence.scopeSeriesShort").replace("{{count}}", seriesSize ? String(seriesSize) : "\u2026");
|
|
3773
|
-
const btn = "flex-1 min-w-0 rounded border border-destructive/30 px-2 py-1 text-center text-[11px] font-medium text-destructive hover:bg-destructive/10 disabled:opacity-40 transition-colors";
|
|
3836
|
+
const btn = "flex-1 min-w-0 whitespace-normal rounded border border-destructive/30 px-2 py-1 text-center text-[11px] font-medium text-destructive hover:bg-destructive/10 disabled:opacity-40 transition-colors";
|
|
3774
3837
|
return /* @__PURE__ */ jsxs("div", { className: "px-3 py-2 space-y-1.5", children: [
|
|
3775
3838
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
3776
3839
|
/* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-destructive", children: t2("agenda.recurrence.scopeDeleteTitle") }),
|
|
3777
3840
|
/* @__PURE__ */ jsx(
|
|
3778
|
-
|
|
3841
|
+
Button,
|
|
3779
3842
|
{
|
|
3843
|
+
variant: "bare",
|
|
3844
|
+
size: "bare",
|
|
3780
3845
|
type: "button",
|
|
3781
3846
|
onClick: onCancel,
|
|
3782
3847
|
disabled: deleting !== null,
|
|
@@ -3786,8 +3851,8 @@ function SeriesDeleteChoice({ seriesSize, deleting, onPick, onCancel }) {
|
|
|
3786
3851
|
)
|
|
3787
3852
|
] }),
|
|
3788
3853
|
/* @__PURE__ */ jsxs("div", { className: "flex items-stretch gap-1.5", children: [
|
|
3789
|
-
/* @__PURE__ */ jsx("
|
|
3790
|
-
/* @__PURE__ */ jsx("
|
|
3854
|
+
/* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", type: "button", className: btn, disabled: deleting !== null, onClick: () => onPick("this"), children: deleting === "this" ? t2("agenda.appointment.deleting") : t2("agenda.recurrence.scopeThisShort") }),
|
|
3855
|
+
/* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", type: "button", className: btn, disabled: deleting !== null, onClick: () => onPick("series"), children: deleting === "series" ? t2("agenda.appointment.deleting") : allLabel })
|
|
3791
3856
|
] })
|
|
3792
3857
|
] });
|
|
3793
3858
|
}
|
|
@@ -3797,9 +3862,6 @@ function fmtTime(iso) {
|
|
|
3797
3862
|
function fmtDate2(iso) {
|
|
3798
3863
|
return new Date(iso).toLocaleDateString(void 0, { weekday: "long", month: "long", day: "numeric" });
|
|
3799
3864
|
}
|
|
3800
|
-
function fmtCurrency2(amount, locale, code) {
|
|
3801
|
-
return new Intl.NumberFormat(locale, { style: "currency", currency: code }).format(amount);
|
|
3802
|
-
}
|
|
3803
3865
|
function PopoverStatusSelect({ value, statuses, bookingStartsAt, onChange }) {
|
|
3804
3866
|
const [open, setOpen] = useState(false);
|
|
3805
3867
|
const ref = useRef(null);
|
|
@@ -3814,8 +3876,10 @@ function PopoverStatusSelect({ value, statuses, bookingStartsAt, onChange }) {
|
|
|
3814
3876
|
}, [open]);
|
|
3815
3877
|
return /* @__PURE__ */ jsxs("div", { ref, className: "relative inline-block", children: [
|
|
3816
3878
|
/* @__PURE__ */ jsxs(
|
|
3817
|
-
|
|
3879
|
+
Button,
|
|
3818
3880
|
{
|
|
3881
|
+
variant: "bare",
|
|
3882
|
+
size: "bare",
|
|
3819
3883
|
type: "button",
|
|
3820
3884
|
onClick: () => setOpen((p) => !p),
|
|
3821
3885
|
className: "inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-[11px] font-medium transition-colors hover:opacity-80",
|
|
@@ -3830,8 +3894,10 @@ function PopoverStatusSelect({ value, statuses, bookingStartsAt, onChange }) {
|
|
|
3830
3894
|
open && /* @__PURE__ */ jsx("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]", children: statuses.map((s) => {
|
|
3831
3895
|
const available = isStatusAvailable(s, bookingStartsAt);
|
|
3832
3896
|
return /* @__PURE__ */ jsxs(
|
|
3833
|
-
|
|
3897
|
+
Button,
|
|
3834
3898
|
{
|
|
3899
|
+
variant: "bare",
|
|
3900
|
+
size: "bare",
|
|
3835
3901
|
type: "button",
|
|
3836
3902
|
disabled: !available,
|
|
3837
3903
|
onClick: () => {
|
|
@@ -3840,7 +3906,7 @@ function PopoverStatusSelect({ value, statuses, bookingStartsAt, onChange }) {
|
|
|
3840
3906
|
setOpen(false);
|
|
3841
3907
|
}
|
|
3842
3908
|
},
|
|
3843
|
-
className: `flex w-full items-center gap-2 px-3 py-1.5 text-xs transition-colors ${!available ? "
|
|
3909
|
+
className: `font-normal justify-start whitespace-normal flex w-full items-center gap-2 px-3 py-1.5 text-xs transition-colors ${!available ? "disabled:pointer-events-auto disabled:cursor-not-allowed disabled:opacity-30" : s.value === value ? "bg-muted/30" : "hover:bg-muted/50"}`,
|
|
3844
3910
|
children: [
|
|
3845
3911
|
/* @__PURE__ */ jsx("span", { className: "h-2 w-2 rounded-full shrink-0", style: { backgroundColor: s.color } }),
|
|
3846
3912
|
/* @__PURE__ */ jsx("span", { children: s.label })
|
|
@@ -3876,16 +3942,20 @@ function AppointmentPopover({ booking, position: position2, onClose, onEdit }) {
|
|
|
3876
3942
|
) }) : confirmingDelete ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3877
3943
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-destructive font-medium mr-auto pl-1", children: t2("agenda.appointment.deleteConfirm") }),
|
|
3878
3944
|
/* @__PURE__ */ jsx(
|
|
3879
|
-
|
|
3945
|
+
Button,
|
|
3880
3946
|
{
|
|
3947
|
+
variant: "bare",
|
|
3948
|
+
size: "bare",
|
|
3881
3949
|
onClick: () => setConfirmingDelete(false),
|
|
3882
3950
|
className: "rounded px-2 py-0.5 text-[11px] font-medium hover:bg-muted/50 transition-colors",
|
|
3883
3951
|
children: t2("agenda.appointment.cancel")
|
|
3884
3952
|
}
|
|
3885
3953
|
),
|
|
3886
3954
|
/* @__PURE__ */ jsx(
|
|
3887
|
-
|
|
3955
|
+
Button,
|
|
3888
3956
|
{
|
|
3957
|
+
variant: "bare",
|
|
3958
|
+
size: "bare",
|
|
3889
3959
|
onClick: () => {
|
|
3890
3960
|
void series.remove("this");
|
|
3891
3961
|
},
|
|
@@ -3896,8 +3966,10 @@ function AppointmentPopover({ booking, position: position2, onClose, onEdit }) {
|
|
|
3896
3966
|
)
|
|
3897
3967
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3898
3968
|
/* @__PURE__ */ jsx(
|
|
3899
|
-
|
|
3969
|
+
Button,
|
|
3900
3970
|
{
|
|
3971
|
+
variant: "bare",
|
|
3972
|
+
size: "bare",
|
|
3901
3973
|
onClick: () => panel.expandThen(() => onEdit(booking.id)),
|
|
3902
3974
|
className: "p-1.5 rounded-full hover:bg-muted transition-colors",
|
|
3903
3975
|
title: t2("common.edit"),
|
|
@@ -3905,15 +3977,17 @@ function AppointmentPopover({ booking, position: position2, onClose, onEdit }) {
|
|
|
3905
3977
|
}
|
|
3906
3978
|
),
|
|
3907
3979
|
/* @__PURE__ */ jsx(
|
|
3908
|
-
|
|
3980
|
+
Button,
|
|
3909
3981
|
{
|
|
3982
|
+
variant: "bare",
|
|
3983
|
+
size: "bare",
|
|
3910
3984
|
onClick: () => setConfirmingDelete(true),
|
|
3911
3985
|
className: "p-1.5 rounded-full hover:bg-destructive/10 transition-colors",
|
|
3912
3986
|
title: t2("common.delete"),
|
|
3913
3987
|
children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4 text-muted-foreground hover:text-destructive" })
|
|
3914
3988
|
}
|
|
3915
3989
|
),
|
|
3916
|
-
/* @__PURE__ */ jsx("
|
|
3990
|
+
/* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", onClick: panel.dismiss, className: "p-1.5 rounded-full hover:bg-muted transition-colors", children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4 text-muted-foreground" }) })
|
|
3917
3991
|
] }) }),
|
|
3918
3992
|
/* @__PURE__ */ jsxs("div", { className: "px-5 pb-5 space-y-3", children: [
|
|
3919
3993
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
|
|
@@ -3952,7 +4026,7 @@ function AppointmentPopover({ booking, position: position2, onClose, onEdit }) {
|
|
|
3952
4026
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: booking.notes })
|
|
3953
4027
|
] }),
|
|
3954
4028
|
booking.orderTotal != null && booking.orderTotal > 0 && (() => {
|
|
3955
|
-
const total =
|
|
4029
|
+
const total = formatCurrency(booking.orderTotal, config.currency.code);
|
|
3956
4030
|
const ps = booking.paymentStatus ?? "none";
|
|
3957
4031
|
const hasFinancial = config.modules.financial && booking.orderId;
|
|
3958
4032
|
if (!hasFinancial) {
|
|
@@ -3974,8 +4048,10 @@ function AppointmentPopover({ booking, position: position2, onClose, onEdit }) {
|
|
|
3974
4048
|
return /* @__PURE__ */ jsxs("div", { className: "pt-2 border-t fayz-glass-divider flex items-center justify-between", children: [
|
|
3975
4049
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t2("agenda.appointment.total") }),
|
|
3976
4050
|
/* @__PURE__ */ jsxs(
|
|
3977
|
-
|
|
4051
|
+
Button,
|
|
3978
4052
|
{
|
|
4053
|
+
variant: "bare",
|
|
4054
|
+
size: "bare",
|
|
3979
4055
|
type: "button",
|
|
3980
4056
|
onClick: () => {
|
|
3981
4057
|
onClose();
|
|
@@ -4024,8 +4100,10 @@ function StatusDot({ color, label, isActive, disabled, onClick }) {
|
|
|
4024
4100
|
const [rect, setRect] = useState(null);
|
|
4025
4101
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4026
4102
|
/* @__PURE__ */ jsx(
|
|
4027
|
-
|
|
4103
|
+
Button,
|
|
4028
4104
|
{
|
|
4105
|
+
variant: "bare",
|
|
4106
|
+
size: "bare",
|
|
4029
4107
|
ref: btnRef,
|
|
4030
4108
|
type: "button",
|
|
4031
4109
|
onClick: disabled ? void 0 : onClick,
|
|
@@ -4035,7 +4113,7 @@ function StatusDot({ color, label, isActive, disabled, onClick }) {
|
|
|
4035
4113
|
if (btnRef.current) setRect(btnRef.current.getBoundingClientRect());
|
|
4036
4114
|
},
|
|
4037
4115
|
onMouseLeave: () => setHover(false),
|
|
4038
|
-
className: `flex h-7 w-7 items-center justify-center rounded-full transition-all ${disabled ? "
|
|
4116
|
+
className: `flex h-7 w-7 items-center justify-center rounded-full transition-all ${disabled ? "disabled:pointer-events-auto disabled:cursor-not-allowed disabled:opacity-25" : isActive ? "ring-2 ring-offset-2 ring-offset-popover" : "hover:scale-110"}`,
|
|
4039
4117
|
style: { backgroundColor: color, ["--tw-ring-color"]: isActive ? color : void 0 },
|
|
4040
4118
|
children: isActive && /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-white", strokeWidth: 2.5 })
|
|
4041
4119
|
}
|
|
@@ -4053,10 +4131,12 @@ function EventContextMenu({ booking, position: position2, onClose, onEdit }) {
|
|
|
4053
4131
|
return /* @__PURE__ */ jsx(FloatingPanel, { position: position2, width: 230, height: 180, offset: { x: 4, y: 4 }, onClose, zIndex: 110, children: (panel) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4054
4132
|
/* @__PURE__ */ jsxs("div", { className: "py-1", children: [
|
|
4055
4133
|
/* @__PURE__ */ jsxs(
|
|
4056
|
-
|
|
4134
|
+
Button,
|
|
4057
4135
|
{
|
|
4136
|
+
variant: "bare",
|
|
4137
|
+
size: "bare",
|
|
4058
4138
|
onClick: () => panel.expandThen(() => onEdit(booking.id)),
|
|
4059
|
-
className: "flex w-full items-center gap-3 px-4 py-2 text-sm hover:bg-muted/50 transition-colors",
|
|
4139
|
+
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",
|
|
4060
4140
|
children: [
|
|
4061
4141
|
/* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4 text-muted-foreground" }),
|
|
4062
4142
|
" ",
|
|
@@ -4078,16 +4158,20 @@ function EventContextMenu({ booking, position: position2, onClose, onEdit }) {
|
|
|
4078
4158
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-destructive font-medium", children: t2("agenda.appointment.deleteConfirm") }),
|
|
4079
4159
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
4080
4160
|
/* @__PURE__ */ jsx(
|
|
4081
|
-
|
|
4161
|
+
Button,
|
|
4082
4162
|
{
|
|
4163
|
+
variant: "bare",
|
|
4164
|
+
size: "bare",
|
|
4083
4165
|
onClick: () => setConfirming(false),
|
|
4084
4166
|
className: "rounded px-2 py-0.5 text-[11px] font-medium hover:bg-muted/50 transition-colors",
|
|
4085
4167
|
children: t2("agenda.appointment.cancel")
|
|
4086
4168
|
}
|
|
4087
4169
|
),
|
|
4088
4170
|
/* @__PURE__ */ jsx(
|
|
4089
|
-
|
|
4171
|
+
Button,
|
|
4090
4172
|
{
|
|
4173
|
+
variant: "bare",
|
|
4174
|
+
size: "bare",
|
|
4091
4175
|
onClick: () => {
|
|
4092
4176
|
void series.remove("this");
|
|
4093
4177
|
},
|
|
@@ -4098,10 +4182,12 @@ function EventContextMenu({ booking, position: position2, onClose, onEdit }) {
|
|
|
4098
4182
|
)
|
|
4099
4183
|
] })
|
|
4100
4184
|
] }) : /* @__PURE__ */ jsxs(
|
|
4101
|
-
|
|
4185
|
+
Button,
|
|
4102
4186
|
{
|
|
4187
|
+
variant: "bare",
|
|
4188
|
+
size: "bare",
|
|
4103
4189
|
onClick: () => setConfirming(true),
|
|
4104
|
-
className: "flex w-full items-center gap-3 px-4 py-2 text-sm hover:bg-muted/50 transition-colors text-destructive",
|
|
4190
|
+
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",
|
|
4105
4191
|
children: [
|
|
4106
4192
|
/* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" }),
|
|
4107
4193
|
" ",
|
|
@@ -4184,8 +4270,10 @@ function AgendaMobileList({ bookings, statusColors, currencyCode, onSelect, onCr
|
|
|
4184
4270
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col items-center justify-center gap-4 px-6 py-16 text-center", children: [
|
|
4185
4271
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t2("agenda.list.empty") }),
|
|
4186
4272
|
onCreate && /* @__PURE__ */ jsx(
|
|
4187
|
-
|
|
4273
|
+
Button,
|
|
4188
4274
|
{
|
|
4275
|
+
variant: "bare",
|
|
4276
|
+
size: "bare",
|
|
4189
4277
|
type: "button",
|
|
4190
4278
|
onClick: onCreate,
|
|
4191
4279
|
className: "fz-tap inline-flex items-center rounded-full bg-primary px-5 text-sm font-medium text-primary-foreground active:scale-[0.98]",
|
|
@@ -4200,10 +4288,12 @@ function AgendaMobileList({ bookings, statusColors, currencyCode, onSelect, onCr
|
|
|
4200
4288
|
const color = statusColors[b.status] ?? "#6b7280";
|
|
4201
4289
|
const hasAmount = typeof b.orderTotal === "number" && b.orderTotal > 0;
|
|
4202
4290
|
return /* @__PURE__ */ jsxs(
|
|
4203
|
-
|
|
4291
|
+
Button,
|
|
4204
4292
|
{
|
|
4293
|
+
variant: "bare",
|
|
4294
|
+
size: "bare",
|
|
4205
4295
|
onClick: () => onSelect(b),
|
|
4206
|
-
className: "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",
|
|
4296
|
+
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",
|
|
4207
4297
|
children: [
|
|
4208
4298
|
/* @__PURE__ */ jsx("span", { className: "h-2.5 w-2.5 shrink-0 rounded-full", style: { backgroundColor: color } }),
|
|
4209
4299
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
@@ -5695,26 +5785,30 @@ function CalendarView() {
|
|
|
5695
5785
|
const on = shownWeekDays.includes(dow2);
|
|
5696
5786
|
const name = new Date(2024, 0, 7 + dow2).toLocaleDateString(currentLocale === "pt-BR" ? "pt-BR" : "en", { weekday: "long" });
|
|
5697
5787
|
return /* @__PURE__ */ jsx(
|
|
5698
|
-
|
|
5788
|
+
Button,
|
|
5699
5789
|
{
|
|
5790
|
+
variant: "bare",
|
|
5791
|
+
size: "bare",
|
|
5700
5792
|
type: "button",
|
|
5701
5793
|
"aria-pressed": on,
|
|
5702
5794
|
title: name,
|
|
5703
5795
|
"aria-label": name,
|
|
5704
5796
|
"data-testid": `week-day-${dow2}`,
|
|
5705
5797
|
onClick: () => toggleWeekDay(dow2),
|
|
5706
|
-
className: `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"}`,
|
|
5798
|
+
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"}`,
|
|
5707
5799
|
children: name.charAt(0)
|
|
5708
5800
|
},
|
|
5709
5801
|
dow2
|
|
5710
5802
|
);
|
|
5711
5803
|
}) }),
|
|
5712
5804
|
Array.isArray(weekDaysPref) && /* @__PURE__ */ jsx(
|
|
5713
|
-
|
|
5805
|
+
Button,
|
|
5714
5806
|
{
|
|
5807
|
+
variant: "bare",
|
|
5808
|
+
size: "bare",
|
|
5715
5809
|
type: "button",
|
|
5716
5810
|
onClick: () => prefs.set("weekDays", "auto"),
|
|
5717
|
-
className: "text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline",
|
|
5811
|
+
className: "font-normal whitespace-normal text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline",
|
|
5718
5812
|
children: "Voltar ao autom\xE1tico"
|
|
5719
5813
|
}
|
|
5720
5814
|
)
|
|
@@ -5794,36 +5888,42 @@ function CalendarView() {
|
|
|
5794
5888
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
5795
5889
|
/* @__PURE__ */ jsxs("div", { className: `${mobileGridActive ? "flex" : "hidden"} md:flex items-center gap-3`, children: [
|
|
5796
5890
|
/* @__PURE__ */ jsx(
|
|
5797
|
-
|
|
5891
|
+
Button,
|
|
5798
5892
|
{
|
|
5893
|
+
variant: "bare",
|
|
5894
|
+
size: "bare",
|
|
5799
5895
|
onClick: handleToday,
|
|
5800
5896
|
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",
|
|
5801
5897
|
children: t2("agenda.toolbar.today")
|
|
5802
5898
|
}
|
|
5803
5899
|
),
|
|
5804
5900
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
5805
|
-
/* @__PURE__ */ jsx("
|
|
5806
|
-
/* @__PURE__ */ jsx("
|
|
5901
|
+
/* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", onClick: handlePrev, className: "flex h-7 w-7 items-center justify-center rounded-full hover:bg-muted transition-colors", children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" }) }),
|
|
5902
|
+
/* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", onClick: handleNext, className: "flex h-7 w-7 items-center justify-center rounded-full hover:bg-muted transition-colors", children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" }) })
|
|
5807
5903
|
] })
|
|
5808
5904
|
] }),
|
|
5809
5905
|
!(isMobile && !mobileGridActive) && /* @__PURE__ */ jsx("h2", { className: "truncate text-base font-normal sm:text-lg", children: calendarTitle })
|
|
5810
5906
|
] }),
|
|
5811
5907
|
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 shrink-0", children: /* @__PURE__ */ jsx("div", { className: "hidden md:flex items-center gap-1", children: viewOptions.map((opt) => /* @__PURE__ */ jsx(
|
|
5812
|
-
|
|
5908
|
+
Button,
|
|
5813
5909
|
{
|
|
5910
|
+
variant: "bare",
|
|
5911
|
+
size: "bare",
|
|
5814
5912
|
onClick: () => handleViewChange(opt.key),
|
|
5815
|
-
className: `rounded-md px-3 py-1 text-sm transition-colors ${currentView === opt.key ? "bg-primary/10 text-primary font-medium" : "text-muted-foreground hover:bg-muted/50"}`,
|
|
5913
|
+
className: `font-normal rounded-md px-3 py-1 text-sm transition-colors ${currentView === opt.key ? "bg-primary/10 text-primary font-medium" : "text-muted-foreground hover:bg-muted/50"}`,
|
|
5816
5914
|
children: t2(opt.labelKey)
|
|
5817
5915
|
},
|
|
5818
5916
|
opt.key
|
|
5819
5917
|
)) }) })
|
|
5820
5918
|
] }),
|
|
5821
5919
|
/* @__PURE__ */ jsx("div", { className: "flex md:hidden items-center gap-1 overflow-x-auto px-3 pb-2", children: mobileViewOptions.map((opt) => /* @__PURE__ */ jsx(
|
|
5822
|
-
|
|
5920
|
+
Button,
|
|
5823
5921
|
{
|
|
5922
|
+
variant: "bare",
|
|
5923
|
+
size: "bare",
|
|
5824
5924
|
onClick: () => handleMobileViewChange(opt.key),
|
|
5825
5925
|
"aria-pressed": mobileView === opt.key,
|
|
5826
|
-
className: `flex min-h-[2.75rem] shrink-0 items-center rounded-full px-4 text-sm transition-colors active:scale-[0.98] ${mobileView === opt.key ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-muted/50"}`,
|
|
5926
|
+
className: `font-normal flex min-h-[2.75rem] shrink-0 items-center rounded-full px-4 text-sm transition-colors active:scale-[0.98] ${mobileView === opt.key ? "bg-primary/10 font-medium text-primary" : "text-muted-foreground hover:bg-muted/50"}`,
|
|
5827
5927
|
children: t2(opt.labelKey)
|
|
5828
5928
|
},
|
|
5829
5929
|
opt.key
|
|
@@ -5852,8 +5952,10 @@ function CalendarView() {
|
|
|
5852
5952
|
t2("agenda.calendar.noGridBody")
|
|
5853
5953
|
] }),
|
|
5854
5954
|
/* @__PURE__ */ jsx(
|
|
5855
|
-
|
|
5955
|
+
Button,
|
|
5856
5956
|
{
|
|
5957
|
+
variant: "bare",
|
|
5958
|
+
size: "bare",
|
|
5857
5959
|
type: "button",
|
|
5858
5960
|
onClick: () => setSchedulesOpen(true),
|
|
5859
5961
|
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",
|
|
@@ -6034,7 +6136,11 @@ function missingRequiredFields(fields, row, skip = ["name"]) {
|
|
|
6034
6136
|
}
|
|
6035
6137
|
return out;
|
|
6036
6138
|
}
|
|
6037
|
-
|
|
6139
|
+
function useZoneFilled(zone) {
|
|
6140
|
+
const runtime = usePluginRuntimeOptional();
|
|
6141
|
+
return runtime ? getWidgetsForZone(runtime, zone).length > 0 : false;
|
|
6142
|
+
}
|
|
6143
|
+
var brl = (n) => formatCurrency(n, "BRL");
|
|
6038
6144
|
function CheckinDialog({
|
|
6039
6145
|
booking,
|
|
6040
6146
|
statusLabel,
|
|
@@ -6043,7 +6149,7 @@ function CheckinDialog({
|
|
|
6043
6149
|
onConfirm,
|
|
6044
6150
|
clientRecord,
|
|
6045
6151
|
onClose,
|
|
6046
|
-
formatCurrency:
|
|
6152
|
+
formatCurrency: formatCurrency9 = brl
|
|
6047
6153
|
}) {
|
|
6048
6154
|
const canCompleteInline = !!clientRecord && requirements.some((r) => r.field);
|
|
6049
6155
|
const [completing, setCompleting] = React23.useState(false);
|
|
@@ -6052,6 +6158,14 @@ function CheckinDialog({
|
|
|
6052
6158
|
const [preenchidos, setPreenchidos] = React23.useState(0);
|
|
6053
6159
|
const [pendencias, setPendencias] = React23.useState([]);
|
|
6054
6160
|
const blocking = requirements.filter((r) => r.blocking);
|
|
6161
|
+
const checklistFilled = useZoneFilled(FORMS_ZONES.personChecklist);
|
|
6162
|
+
const registrationChecks = React23.useMemo(() => requirements.length === 0 ? [{ id: "cadastro", label: "Dados obrigat\xF3rios", state: "done", detail: "completos" }] : requirements.map((r) => ({
|
|
6163
|
+
id: `cadastro:${r.label}`,
|
|
6164
|
+
label: r.label,
|
|
6165
|
+
state: r.blocking ? "late" : "todo",
|
|
6166
|
+
detail: r.detail,
|
|
6167
|
+
action: r.field && canCompleteInline ? { label: "Completar cadastro", onClick: () => setCompleting(true) } : r.action
|
|
6168
|
+
})), [requirements, canCompleteInline]);
|
|
6055
6169
|
const paid = booking.paymentStatus === "paid";
|
|
6056
6170
|
const hasBill = !!booking.paymentStatus && booking.paymentStatus !== "none";
|
|
6057
6171
|
const when = new Date(booking.startsAt).toLocaleString("pt-BR", {
|
|
@@ -6085,22 +6199,21 @@ function CheckinDialog({
|
|
|
6085
6199
|
/* @__PURE__ */ jsxs("section", { className: "rounded-xl border px-3 py-2", children: [
|
|
6086
6200
|
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-medium uppercase text-muted-foreground", children: "Cadastro do cliente" }),
|
|
6087
6201
|
/* @__PURE__ */ jsx(
|
|
6088
|
-
|
|
6202
|
+
WidgetSlot,
|
|
6089
6203
|
{
|
|
6204
|
+
zone: FORMS_ZONES.personChecklist,
|
|
6090
6205
|
version: preenchidos,
|
|
6091
6206
|
personId: booking.clientId,
|
|
6092
6207
|
className: "mt-2",
|
|
6093
|
-
extras:
|
|
6094
|
-
id: `cadastro:${r.label}`,
|
|
6095
|
-
label: r.label,
|
|
6096
|
-
state: r.blocking ? "late" : "todo",
|
|
6097
|
-
detail: r.detail,
|
|
6098
|
-
action: r.field && canCompleteInline ? { label: "Completar cadastro", onClick: () => setCompleting(true) } : r.action
|
|
6099
|
-
})),
|
|
6208
|
+
extras: registrationChecks,
|
|
6100
6209
|
onPending: setPendencias,
|
|
6101
6210
|
onFill: (templateId) => setPreenchendo(templateId)
|
|
6102
6211
|
}
|
|
6103
6212
|
),
|
|
6213
|
+
!checklistFilled && /* @__PURE__ */ jsx("ul", { className: "mt-2 space-y-0.5 text-xs", children: registrationChecks.map((c) => /* @__PURE__ */ jsxs("li", { className: c.state === "done" ? "text-muted-foreground" : "font-medium text-foreground", children: [
|
|
6214
|
+
c.label,
|
|
6215
|
+
c.detail ? ` \u2014 ${c.detail}` : ""
|
|
6216
|
+
] }, c.id)) }),
|
|
6104
6217
|
canCompleteInline && /* @__PURE__ */ jsx(
|
|
6105
6218
|
CrudRecordModal,
|
|
6106
6219
|
{
|
|
@@ -6115,8 +6228,10 @@ function CheckinDialog({
|
|
|
6115
6228
|
}
|
|
6116
6229
|
),
|
|
6117
6230
|
preenchendo && booking.clientId && /* @__PURE__ */ jsx(
|
|
6118
|
-
|
|
6231
|
+
WidgetSlot,
|
|
6119
6232
|
{
|
|
6233
|
+
zone: FORMS_ZONES.formFill,
|
|
6234
|
+
frame: "inline",
|
|
6120
6235
|
templateId: preenchendo,
|
|
6121
6236
|
personId: booking.clientId,
|
|
6122
6237
|
personName: booking.clientName,
|
|
@@ -6128,10 +6243,12 @@ function CheckinDialog({
|
|
|
6128
6243
|
/* @__PURE__ */ jsxs("section", { className: "rounded-xl border px-3 py-2", children: [
|
|
6129
6244
|
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-medium uppercase text-muted-foreground", children: "Pagamento" }),
|
|
6130
6245
|
/* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center justify-between gap-2", children: [
|
|
6131
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: paid ? "Este atendimento j\xE1 est\xE1 pago." : hasBill ? `Em aberto${booking.orderTotal ? ` \xB7 ${
|
|
6246
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: paid ? "Este atendimento j\xE1 est\xE1 pago." : hasBill ? `Em aberto${booking.orderTotal ? ` \xB7 ${formatCurrency9(booking.orderTotal)}` : ""}.` : "Nenhuma fatura vinculada a este agendamento." }),
|
|
6132
6247
|
onReceive && !paid && /* @__PURE__ */ jsxs(
|
|
6133
|
-
|
|
6248
|
+
Button,
|
|
6134
6249
|
{
|
|
6250
|
+
variant: "bare",
|
|
6251
|
+
size: "bare",
|
|
6135
6252
|
onClick: () => onReceive(booking),
|
|
6136
6253
|
className: "inline-flex shrink-0 items-center gap-1.5 rounded-button border border-input px-3 py-1.5 text-xs font-medium hover:bg-muted",
|
|
6137
6254
|
children: [
|
|
@@ -6146,8 +6263,10 @@ function CheckinDialog({
|
|
|
6146
6263
|
onConfirm ? /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center justify-between gap-2 border-t px-4 py-3", children: [
|
|
6147
6264
|
/* @__PURE__ */ jsx("p", { className: "text-[11px] text-muted-foreground", children: pendencias.length ? `Falta ${pendencias.join(", ")}.` : "" }),
|
|
6148
6265
|
/* @__PURE__ */ jsxs(
|
|
6149
|
-
|
|
6266
|
+
Button,
|
|
6150
6267
|
{
|
|
6268
|
+
variant: "bare",
|
|
6269
|
+
size: "bare",
|
|
6151
6270
|
disabled: busy || blocking.length > 0 || pendencias.length > 0,
|
|
6152
6271
|
title: pendencias.length ? `Falta ${pendencias.join(", ")}` : void 0,
|
|
6153
6272
|
onClick: async () => {
|
|
@@ -6158,7 +6277,7 @@ function CheckinDialog({
|
|
|
6158
6277
|
setBusy(false);
|
|
6159
6278
|
}
|
|
6160
6279
|
},
|
|
6161
|
-
className: "inline-flex shrink-0 items-center gap-1.5 rounded-button bg-primary border border-primary px-4 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50",
|
|
6280
|
+
className: "inline-flex shrink-0 items-center gap-1.5 rounded-button bg-primary border border-primary px-4 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:pointer-events-auto disabled:opacity-50",
|
|
6162
6281
|
children: [
|
|
6163
6282
|
/* @__PURE__ */ jsx(User, { className: "h-3.5 w-3.5" }),
|
|
6164
6283
|
" ",
|
|
@@ -6188,7 +6307,7 @@ function CheckinScoreboard({
|
|
|
6188
6307
|
bookings,
|
|
6189
6308
|
noShow = 0,
|
|
6190
6309
|
openAmount = 0,
|
|
6191
|
-
formatCurrency:
|
|
6310
|
+
formatCurrency: formatCurrency9,
|
|
6192
6311
|
selectedStatuses,
|
|
6193
6312
|
onPickStatus
|
|
6194
6313
|
}) {
|
|
@@ -6256,7 +6375,7 @@ function CheckinScoreboard({
|
|
|
6256
6375
|
] }),
|
|
6257
6376
|
openAmount > 0 && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
6258
6377
|
/* @__PURE__ */ jsx(CircleDollarSign, { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": true }),
|
|
6259
|
-
/* @__PURE__ */ jsx("span", { className: "tabular-nums font-medium text-foreground", children:
|
|
6378
|
+
/* @__PURE__ */ jsx("span", { className: "tabular-nums font-medium text-foreground", children: formatCurrency9(openAmount) }),
|
|
6260
6379
|
" ",
|
|
6261
6380
|
"a receber hoje"
|
|
6262
6381
|
] })
|
|
@@ -6288,12 +6407,14 @@ function CheckinScoreboard({
|
|
|
6288
6407
|
] });
|
|
6289
6408
|
const base = `inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs ${tone}`;
|
|
6290
6409
|
return status ? /* @__PURE__ */ jsx(
|
|
6291
|
-
|
|
6410
|
+
Button,
|
|
6292
6411
|
{
|
|
6412
|
+
variant: "bare",
|
|
6413
|
+
size: "bare",
|
|
6293
6414
|
type: "button",
|
|
6294
6415
|
onClick: () => onPickStatus(status),
|
|
6295
6416
|
"aria-pressed": ligado,
|
|
6296
|
-
className:
|
|
6417
|
+
className: `font-normal ${base} transition-all hover:brightness-95 active:scale-95 ${ligado ? "ring-1 ring-current" : ""}`,
|
|
6297
6418
|
children: conteudo
|
|
6298
6419
|
},
|
|
6299
6420
|
key
|
|
@@ -6402,7 +6523,8 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
|
|
|
6402
6523
|
const setEditing = (b) => setPanel(b ? { kind: "edit", booking: b } : null);
|
|
6403
6524
|
const setCharging = (b) => setPanel(b ? { kind: "charge", booking: b } : null);
|
|
6404
6525
|
const can = usePermissionOptional();
|
|
6405
|
-
const
|
|
6526
|
+
const accountMounted = useZoneFilled(FINANCIAL_ZONES.clientAccount);
|
|
6527
|
+
const canReceive = accountMounted && (can("financial", "create") || can("financial.receivables", "create"));
|
|
6406
6528
|
React23.useEffect(() => {
|
|
6407
6529
|
void fetchBookings(todayRange(), [...CHECKIN_STATUSES]);
|
|
6408
6530
|
}, [fetchBookings]);
|
|
@@ -6436,7 +6558,7 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
|
|
|
6436
6558
|
if (!b.services?.length) out.push({ label: "Servi\xE7o", detail: "nada a executar nem a cobrar" });
|
|
6437
6559
|
return out;
|
|
6438
6560
|
}
|
|
6439
|
-
const money = (n) => n
|
|
6561
|
+
const money = (n) => formatCurrency(n, "BRL");
|
|
6440
6562
|
const [lost, setLost] = React23.useState({ cancelled: 0, noShow: 0 });
|
|
6441
6563
|
React23.useEffect(() => {
|
|
6442
6564
|
if (!provider2.getLostCounts) return;
|
|
@@ -6662,9 +6784,11 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
|
|
|
6662
6784
|
})()
|
|
6663
6785
|
] })
|
|
6664
6786
|
] }),
|
|
6665
|
-
b.orderTotal != null && b.orderTotal > 0 && /* @__PURE__ */ jsx(
|
|
6666
|
-
|
|
6787
|
+
accountMounted && b.orderTotal != null && b.orderTotal > 0 && /* @__PURE__ */ jsx(
|
|
6788
|
+
Button,
|
|
6667
6789
|
{
|
|
6790
|
+
variant: "bare",
|
|
6791
|
+
size: "bare",
|
|
6668
6792
|
type: "button",
|
|
6669
6793
|
onClick: () => setCharging(b),
|
|
6670
6794
|
className: "shrink-0 rounded-button border border-input px-2.5 py-1.5 text-xs font-medium hover:bg-muted",
|
|
@@ -6680,8 +6804,10 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
|
|
|
6680
6804
|
] });
|
|
6681
6805
|
}
|
|
6682
6806
|
return /* @__PURE__ */ jsx(
|
|
6683
|
-
|
|
6807
|
+
Button,
|
|
6684
6808
|
{
|
|
6809
|
+
variant: "bare",
|
|
6810
|
+
size: "bare",
|
|
6685
6811
|
type: "button",
|
|
6686
6812
|
disabled: conferindo === b.id,
|
|
6687
6813
|
onClick: () => concluirCheckout(b),
|
|
@@ -6695,7 +6821,7 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
|
|
|
6695
6821
|
})(),
|
|
6696
6822
|
startRefusal && /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 rounded-lg bg-warning/10 px-3 py-2 text-xs text-warning-foreground", children: [
|
|
6697
6823
|
/* @__PURE__ */ jsx("span", { className: "flex-1", children: startRefusal }),
|
|
6698
|
-
/* @__PURE__ */ jsx("
|
|
6824
|
+
/* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", type: "button", onClick: () => setStartRefusal(null), className: "shrink-0 text-xs font-medium hover:underline", children: "Fechar" })
|
|
6699
6825
|
] }),
|
|
6700
6826
|
loading && cards.length === 0 ? (
|
|
6701
6827
|
/* Esqueleto com a FORMA da linha: a fila não salta quando os dados
|
|
@@ -6756,8 +6882,10 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
|
|
|
6756
6882
|
actions: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6757
6883
|
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
6758
6884
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
6759
|
-
|
|
6885
|
+
Button,
|
|
6760
6886
|
{
|
|
6887
|
+
variant: "bare",
|
|
6888
|
+
size: "bare",
|
|
6761
6889
|
type: "button",
|
|
6762
6890
|
onClick: () => onOpenBooking ? onOpenBooking(b) : setEditing(b),
|
|
6763
6891
|
"aria-label": "Abrir agendamento",
|
|
@@ -6769,13 +6897,15 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
|
|
|
6769
6897
|
] }),
|
|
6770
6898
|
b.clientPhone && /* @__PURE__ */ jsx(ClientContactButton, { phone: b.clientPhone, compact: true }),
|
|
6771
6899
|
arrived && b.status !== "completed" && myPersonId !== void 0 && (myPersonId === null || b.professionalId === myPersonId) && /* @__PURE__ */ jsxs(
|
|
6772
|
-
|
|
6900
|
+
Button,
|
|
6773
6901
|
{
|
|
6902
|
+
variant: "bare",
|
|
6903
|
+
size: "bare",
|
|
6774
6904
|
type: "button",
|
|
6775
6905
|
disabled: myPersonId === null || busyId === b.id,
|
|
6776
6906
|
onClick: () => b.status === "in_progress" ? abrirAtendimento(b) : startAttendance(b),
|
|
6777
6907
|
title: myPersonId === null ? RECUSA.sem_ficha_de_profissional : void 0,
|
|
6778
|
-
className: "inline-flex items-center gap-1.5 rounded-button bg-foreground px-3 py-1.5 text-xs font-semibold text-background disabled:opacity-40",
|
|
6908
|
+
className: "inline-flex items-center gap-1.5 rounded-button bg-foreground px-3 py-1.5 text-xs font-semibold text-background disabled:pointer-events-auto disabled:opacity-40",
|
|
6779
6909
|
children: [
|
|
6780
6910
|
/* @__PURE__ */ jsx(Play, { className: "h-3.5 w-3.5", "aria-hidden": true }),
|
|
6781
6911
|
b.status === "in_progress" ? "Continuar" : "Iniciar atendimento"
|
|
@@ -6783,8 +6913,10 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
|
|
|
6783
6913
|
}
|
|
6784
6914
|
),
|
|
6785
6915
|
b.status === "completed" ? null : arrived ? /* @__PURE__ */ jsxs(
|
|
6786
|
-
|
|
6916
|
+
Button,
|
|
6787
6917
|
{
|
|
6918
|
+
variant: "bare",
|
|
6919
|
+
size: "bare",
|
|
6788
6920
|
type: "button",
|
|
6789
6921
|
onClick: () => setReviewing(b),
|
|
6790
6922
|
className: "inline-flex items-center gap-1.5 rounded-button border border-input px-3 py-1.5 text-xs font-medium hover:bg-muted",
|
|
@@ -6794,8 +6926,10 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
|
|
|
6794
6926
|
]
|
|
6795
6927
|
}
|
|
6796
6928
|
) : /* @__PURE__ */ jsxs(
|
|
6797
|
-
|
|
6929
|
+
Button,
|
|
6798
6930
|
{
|
|
6931
|
+
variant: "bare",
|
|
6932
|
+
size: "bare",
|
|
6799
6933
|
type: "button",
|
|
6800
6934
|
disabled: busyId === b.id,
|
|
6801
6935
|
onClick: () => setReviewing(b),
|
|
@@ -6841,8 +6975,9 @@ function CheckinView({ onReceive, onOpenBooking, onOpenAttendance }) {
|
|
|
6841
6975
|
}
|
|
6842
6976
|
),
|
|
6843
6977
|
charging?.clientId && /* @__PURE__ */ jsx(
|
|
6844
|
-
|
|
6978
|
+
WidgetSlot,
|
|
6845
6979
|
{
|
|
6980
|
+
zone: FINANCIAL_ZONES.clientAccount,
|
|
6846
6981
|
personId: charging.clientId,
|
|
6847
6982
|
orderId: charging.orderId,
|
|
6848
6983
|
clientName: charging.clientName,
|
|
@@ -6954,8 +7089,10 @@ function PersonAttendanceBlock({ personId }) {
|
|
|
6954
7089
|
] })
|
|
6955
7090
|
] }),
|
|
6956
7091
|
/* @__PURE__ */ jsx(
|
|
6957
|
-
|
|
7092
|
+
Button,
|
|
6958
7093
|
{
|
|
7094
|
+
variant: "bare",
|
|
7095
|
+
size: "bare",
|
|
6959
7096
|
type: "button",
|
|
6960
7097
|
disabled: indo,
|
|
6961
7098
|
onClick: comecar,
|
|
@@ -7020,12 +7157,14 @@ function Group({
|
|
|
7020
7157
|
const [open, setOpen] = useState(defaultOpen ?? true);
|
|
7021
7158
|
return /* @__PURE__ */ jsxs("section", { children: [
|
|
7022
7159
|
/* @__PURE__ */ jsxs(
|
|
7023
|
-
|
|
7160
|
+
Button,
|
|
7024
7161
|
{
|
|
7162
|
+
variant: "bare",
|
|
7163
|
+
size: "bare",
|
|
7025
7164
|
type: "button",
|
|
7026
7165
|
onClick: () => setOpen((p) => !p),
|
|
7027
7166
|
"aria-expanded": open,
|
|
7028
|
-
className: "mb-2 flex w-full items-center gap-2 text-left text-xs font-medium text-muted-foreground transition-colors hover:text-foreground",
|
|
7167
|
+
className: "justify-start whitespace-normal mb-2 flex w-full items-center gap-2 text-left text-xs font-medium text-muted-foreground transition-colors hover:text-foreground",
|
|
7029
7168
|
children: [
|
|
7030
7169
|
/* @__PURE__ */ jsx(ChevronDown, { className: `h-3.5 w-3.5 shrink-0 transition-transform ${open ? "" : "-rotate-90"}` }),
|
|
7031
7170
|
/* @__PURE__ */ jsx("span", { children: title }),
|
|
@@ -7140,12 +7279,14 @@ function ConfirmationsView() {
|
|
|
7140
7279
|
title: `Per\xEDodo \xB7 ${HORIZONS.find((h) => h.days === days2)?.short ?? ""}`,
|
|
7141
7280
|
defaultOpen: true,
|
|
7142
7281
|
content: /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: HORIZONS.map((h) => /* @__PURE__ */ jsx(
|
|
7143
|
-
|
|
7282
|
+
Button,
|
|
7144
7283
|
{
|
|
7284
|
+
variant: "bare",
|
|
7285
|
+
size: "bare",
|
|
7145
7286
|
type: "button",
|
|
7146
7287
|
onClick: () => prefs.set("confirmationDays", h.days),
|
|
7147
7288
|
"aria-pressed": h.days === days2,
|
|
7148
|
-
className: "flex w-full items-center gap-2 rounded-md px-1.5 py-1.5 text-left text-xs transition-colors " + (h.days === days2 ? "bg-muted font-medium text-foreground" : "text-muted-foreground hover:bg-muted/50"),
|
|
7289
|
+
className: "flex w-full items-center justify-start gap-2 rounded-md px-1.5 py-1.5 text-left text-xs transition-colors " + (h.days === days2 ? "bg-muted font-medium text-foreground" : "font-normal text-muted-foreground hover:bg-muted/50"),
|
|
7149
7290
|
children: h.label
|
|
7150
7291
|
},
|
|
7151
7292
|
h.days
|
|
@@ -7179,10 +7320,7 @@ function ConfirmationsView() {
|
|
|
7179
7320
|
const busy = busyId === booking.id;
|
|
7180
7321
|
const leaving = leavingId === booking.id;
|
|
7181
7322
|
booking.services?.map((sv) => sv.name).join(", ");
|
|
7182
|
-
booking.orderTotal != null ?
|
|
7183
|
-
style: "currency",
|
|
7184
|
-
currency: config.currency.code
|
|
7185
|
-
}).format(booking.orderTotal) : null;
|
|
7323
|
+
booking.orderTotal != null ? formatCurrency(booking.orderTotal, config.currency.code) : null;
|
|
7186
7324
|
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
7187
7325
|
BookingCard,
|
|
7188
7326
|
{
|
|
@@ -7200,8 +7338,10 @@ function ConfirmationsView() {
|
|
|
7200
7338
|
booking.clientPhone && /* @__PURE__ */ jsx(ClientContactButton, { phone: booking.clientPhone }),
|
|
7201
7339
|
/* @__PURE__ */ jsx("span", { className: "mx-0.5 h-5 w-px bg-border", "aria-hidden": true }),
|
|
7202
7340
|
booking.status !== "confirmed" && /* @__PURE__ */ jsxs(
|
|
7203
|
-
|
|
7341
|
+
Button,
|
|
7204
7342
|
{
|
|
7343
|
+
variant: "bare",
|
|
7344
|
+
size: "bare",
|
|
7205
7345
|
type: "button",
|
|
7206
7346
|
onClick: () => decide(booking.id, "confirmed"),
|
|
7207
7347
|
disabled: busy,
|
|
@@ -7214,8 +7354,10 @@ function ConfirmationsView() {
|
|
|
7214
7354
|
),
|
|
7215
7355
|
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
7216
7356
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
7217
|
-
|
|
7357
|
+
Button,
|
|
7218
7358
|
{
|
|
7359
|
+
variant: "bare",
|
|
7360
|
+
size: "bare",
|
|
7219
7361
|
type: "button",
|
|
7220
7362
|
onClick: () => decide(booking.id, "cancelled"),
|
|
7221
7363
|
disabled: busy,
|
|
@@ -9288,21 +9430,21 @@ function AgendaGeneralSettings() {
|
|
|
9288
9430
|
const s = useTenantPluginSettings("agenda", AGENDA_TOGGLE_DEFAULTS);
|
|
9289
9431
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
9290
9432
|
/* @__PURE__ */ jsxs(SettingsGroup, { title: t2("agenda.settings.scheduling"), description: t2("agenda.settings.schedulingDesc"), children: [
|
|
9291
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.conflictDetection"), description: t2("agenda.settings.conflictDetectionDesc"), checked: s.get("conflictDetection"), onChange: (v) => s.set("conflictDetection", v) }),
|
|
9292
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.dragDrop"), description: t2("agenda.settings.dragDropDesc"), checked: s.get("dragDrop"), onChange: (v) => s.set("dragDrop", v) }),
|
|
9293
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.autoCreateOrder"), description: t2("agenda.settings.autoCreateOrderDesc"), checked: s.get("autoCreateOrder"), onChange: (v) => s.set("autoCreateOrder", v) }),
|
|
9433
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.conflictDetection"), description: t2("agenda.settings.conflictDetectionDesc"), checked: s.get("conflictDetection"), onChange: (v) => s.set("conflictDetection", v) }),
|
|
9434
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.dragDrop"), description: t2("agenda.settings.dragDropDesc"), checked: s.get("dragDrop"), onChange: (v) => s.set("dragDrop", v) }),
|
|
9435
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.autoCreateOrder"), description: t2("agenda.settings.autoCreateOrderDesc"), checked: s.get("autoCreateOrder"), onChange: (v) => s.set("autoCreateOrder", v) }),
|
|
9294
9436
|
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.interestsOnBooking"), description: t2("agenda.settings.interestsOnBookingDesc"), checked: s.get("interestsOnBooking"), onChange: (v) => s.set("interestsOnBooking", v) }),
|
|
9295
9437
|
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.recurringBookings"), description: t2("agenda.settings.recurringBookingsDesc"), checked: s.get("recurringBookings"), onChange: (v) => s.set("recurringBookings", v) })
|
|
9296
9438
|
] }),
|
|
9297
|
-
/* @__PURE__ */ jsx(SettingsGroup, { title: t2("agenda.settings.locations"), description: t2("agenda.settings.locationsDesc"), children: /* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.enableLocation"), description: t2("agenda.settings.enableLocationDesc"), checked: s.get("enableLocation"), onChange: (v) => s.set("enableLocation", v) }) }),
|
|
9439
|
+
/* @__PURE__ */ jsx(SettingsGroup, { title: t2("agenda.settings.locations"), description: t2("agenda.settings.locationsDesc"), children: /* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.enableLocation"), description: t2("agenda.settings.enableLocationDesc"), checked: s.get("enableLocation"), onChange: (v) => s.set("enableLocation", v) }) }),
|
|
9298
9440
|
/* @__PURE__ */ jsxs(SettingsGroup, { title: t2("agenda.settings.workingHours"), description: t2("agenda.settings.workingHoursDesc"), children: [
|
|
9299
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.enableWorkingHours"), description: t2("agenda.settings.enableWorkingHoursDesc"), checked: s.get("enableWorkingHours"), onChange: (v) => s.set("enableWorkingHours", v) }),
|
|
9300
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.blockOutside"), description: t2("agenda.settings.blockOutsideDesc"), checked: s.get("blockOutside"), onChange: (v) => s.set("blockOutside", v) })
|
|
9441
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.enableWorkingHours"), description: t2("agenda.settings.enableWorkingHoursDesc"), checked: s.get("enableWorkingHours"), onChange: (v) => s.set("enableWorkingHours", v) }),
|
|
9442
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.blockOutside"), description: t2("agenda.settings.blockOutsideDesc"), checked: s.get("blockOutside"), onChange: (v) => s.set("blockOutside", v) })
|
|
9301
9443
|
] }),
|
|
9302
9444
|
/* @__PURE__ */ jsxs(SettingsGroup, { title: t2("agenda.settings.confirmations"), description: t2("agenda.settings.confirmationsDesc"), children: [
|
|
9303
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.enableConfirmations"), description: t2("agenda.settings.enableConfirmationsDesc"), checked: s.get("enableConfirmations"), onChange: (v) => s.set("enableConfirmations", v) }),
|
|
9304
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.autoConfirm"), description: t2("agenda.settings.autoConfirmDesc"), checked: s.get("autoConfirm"), onChange: (v) => s.set("autoConfirm", v) }),
|
|
9305
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.reminder"), description: t2("agenda.settings.reminderDesc"), checked: s.get("reminder"), onChange: (v) => s.set("reminder", v) })
|
|
9445
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.enableConfirmations"), description: t2("agenda.settings.enableConfirmationsDesc"), checked: s.get("enableConfirmations"), onChange: (v) => s.set("enableConfirmations", v) }),
|
|
9446
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.autoConfirm"), description: t2("agenda.settings.autoConfirmDesc"), checked: s.get("autoConfirm"), onChange: (v) => s.set("autoConfirm", v) }),
|
|
9447
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.reminder"), description: t2("agenda.settings.reminderDesc"), checked: s.get("reminder"), onChange: (v) => s.set("reminder", v) })
|
|
9306
9448
|
] }),
|
|
9307
9449
|
/* @__PURE__ */ jsxs(SettingsGroup, { title: t2("agenda.settings.calendarDisplay"), description: t2("agenda.settings.calendarDisplayDesc"), children: [
|
|
9308
9450
|
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.cardColorByServiceKind"), description: t2("agenda.settings.cardColorByServiceKindDesc"), checked: s.get("cardColorByServiceKind"), onChange: (v) => s.set("cardColorByServiceKind", v) }),
|
|
@@ -9326,14 +9468,14 @@ function AgendaGeneralSettings() {
|
|
|
9326
9468
|
onChange: setEndTime
|
|
9327
9469
|
}
|
|
9328
9470
|
),
|
|
9329
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.showCancelled"), description: t2("agenda.settings.showCancelledDesc"), checked: s.get("showCancelled"), onChange: (v) => s.set("showCancelled", v) }),
|
|
9330
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.showNoShow"), description: t2("agenda.settings.showNoShowDesc"), checked: s.get("showNoShow"), onChange: (v) => s.set("showNoShow", v) }),
|
|
9331
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.compact"), description: t2("agenda.settings.compactDesc"), checked: s.get("compact"), onChange: (v) => s.set("compact", v) })
|
|
9471
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.showCancelled"), description: t2("agenda.settings.showCancelledDesc"), checked: s.get("showCancelled"), onChange: (v) => s.set("showCancelled", v) }),
|
|
9472
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.showNoShow"), description: t2("agenda.settings.showNoShowDesc"), checked: s.get("showNoShow"), onChange: (v) => s.set("showNoShow", v) }),
|
|
9473
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.compact"), description: t2("agenda.settings.compactDesc"), checked: s.get("compact"), onChange: (v) => s.set("compact", v) })
|
|
9332
9474
|
] }),
|
|
9333
9475
|
/* @__PURE__ */ jsxs(SettingsGroup, { title: t2("agenda.settings.notifications"), description: t2("agenda.settings.notificationsDesc"), children: [
|
|
9334
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.newBookingNotif"), description: t2("agenda.settings.newBookingNotifDesc"), checked: s.get("newBookingNotif"), onChange: (v) => s.set("newBookingNotif", v) }),
|
|
9335
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.cancelAlerts"), description: t2("agenda.settings.cancelAlertsDesc"), checked: s.get("cancelAlerts"), onChange: (v) => s.set("cancelAlerts", v) }),
|
|
9336
|
-
/* @__PURE__ */ jsx(ToggleRow, { label: t2("agenda.settings.noShowTracking"), description: t2("agenda.settings.noShowTrackingDesc"), checked: s.get("noShowTracking"), onChange: (v) => s.set("noShowTracking", v) })
|
|
9476
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.newBookingNotif"), description: t2("agenda.settings.newBookingNotifDesc"), checked: s.get("newBookingNotif"), onChange: (v) => s.set("newBookingNotif", v) }),
|
|
9477
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.cancelAlerts"), description: t2("agenda.settings.cancelAlertsDesc"), checked: s.get("cancelAlerts"), onChange: (v) => s.set("cancelAlerts", v) }),
|
|
9478
|
+
/* @__PURE__ */ jsx(ToggleRow, { pending: true, label: t2("agenda.settings.noShowTracking"), description: t2("agenda.settings.noShowTrackingDesc"), checked: s.get("noShowTracking"), onChange: (v) => s.set("noShowTracking", v) })
|
|
9337
9479
|
] })
|
|
9338
9480
|
] });
|
|
9339
9481
|
}
|
|
@@ -9410,8 +9552,10 @@ function TarefaPane({ titulo, aoVoltar, children }) {
|
|
|
9410
9552
|
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [
|
|
9411
9553
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b px-5 py-3", children: [
|
|
9412
9554
|
/* @__PURE__ */ jsx(
|
|
9413
|
-
|
|
9555
|
+
Button,
|
|
9414
9556
|
{
|
|
9557
|
+
variant: "bare",
|
|
9558
|
+
size: "bare",
|
|
9415
9559
|
type: "button",
|
|
9416
9560
|
onClick: aoVoltar,
|
|
9417
9561
|
"aria-label": "Voltar para as etapas",
|
|
@@ -9462,6 +9606,7 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
9462
9606
|
const [assinando, setAssinando] = React23.useState(null);
|
|
9463
9607
|
const filaAssinatura = React23.useRef({ ids: [], depois: null });
|
|
9464
9608
|
const [preenchendo, setPreenchendo] = React23.useState(null);
|
|
9609
|
+
const formsFillable = useZoneFilled(FORMS_ZONES.formFill);
|
|
9465
9610
|
const [avaliando, setAvaliando] = React23.useState(false);
|
|
9466
9611
|
const [lancando, setLancando] = React23.useState(null);
|
|
9467
9612
|
const [executando, setExecutando] = React23.useState(null);
|
|
@@ -9834,12 +9979,14 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
9834
9979
|
setCandidatos(null);
|
|
9835
9980
|
}, children: [
|
|
9836
9981
|
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto px-5 py-3", children: candidatos === null ? /* @__PURE__ */ jsx("div", { className: "space-y-2", "aria-busy": "true", children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx("div", { className: "h-10 animate-pulse rounded-lg bg-muted" }, i)) }) : candidatos.length === 0 ? /* @__PURE__ */ jsx("p", { className: "py-6 text-center text-xs text-muted-foreground", children: "Este paciente ainda n\xE3o tem procedimento executado para revisar." }) : /* @__PURE__ */ jsx("ul", { className: "divide-y rounded-lg border", children: candidatos.map((c) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
9837
|
-
|
|
9982
|
+
Button,
|
|
9838
9983
|
{
|
|
9984
|
+
variant: "bare",
|
|
9985
|
+
size: "bare",
|
|
9839
9986
|
type: "button",
|
|
9840
9987
|
disabled: salvando,
|
|
9841
9988
|
onClick: () => ligarRevisao(c.sessionId),
|
|
9842
|
-
className: "flex w-full items-center gap-3 px-3 py-2 text-left hover:bg-muted disabled:opacity-40",
|
|
9989
|
+
className: "font-normal justify-start rounded-none whitespace-normal flex w-full items-center gap-3 px-3 py-2 text-left hover:bg-muted disabled:opacity-40",
|
|
9843
9990
|
children: [
|
|
9844
9991
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
9845
9992
|
/* @__PURE__ */ jsx("p", { className: "truncate text-sm", children: c.serviceName ?? "Servi\xE7o" }),
|
|
@@ -9853,8 +10000,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
9853
10000
|
}
|
|
9854
10001
|
) }, c.sessionId)) }) }),
|
|
9855
10002
|
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-end border-t px-5 py-2.5 pb-[calc(0.625rem+env(safe-area-inset-bottom))] sm:pb-2.5 shrink-0", children: /* @__PURE__ */ jsx(
|
|
9856
|
-
|
|
10003
|
+
Button,
|
|
9857
10004
|
{
|
|
10005
|
+
variant: "bare",
|
|
10006
|
+
size: "bare",
|
|
9858
10007
|
type: "button",
|
|
9859
10008
|
onClick: () => {
|
|
9860
10009
|
setVinculando(null);
|
|
@@ -9870,12 +10019,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
9870
10019
|
/* @__PURE__ */ jsx("p", { className: "pb-2 text-[11px] text-muted-foreground", children: "Marque os servi\xE7os que ser\xE3o executados agora. Os demais ficam contratados para execu\xE7\xE3o em outro atendimento." }),
|
|
9871
10020
|
/* @__PURE__ */ jsx("ul", { className: "divide-y rounded-lg border", children: executando.map((x) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-3 px-3 py-2", children: [
|
|
9872
10021
|
/* @__PURE__ */ jsx(
|
|
9873
|
-
|
|
10022
|
+
Checkbox,
|
|
9874
10023
|
{
|
|
9875
|
-
type: "checkbox",
|
|
9876
10024
|
checked: x.feito,
|
|
9877
|
-
onChange: (
|
|
9878
|
-
className: "h-4 w-4 shrink-0 rounded border-input",
|
|
10025
|
+
onChange: (feito) => setExecutando((xs) => (xs ?? []).map((y) => y.serviceId === x.serviceId ? { ...y, feito } : y)),
|
|
9879
10026
|
"aria-label": x.name
|
|
9880
10027
|
}
|
|
9881
10028
|
),
|
|
@@ -9885,8 +10032,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
9885
10032
|
] }),
|
|
9886
10033
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2 border-t px-5 py-2.5 pb-[calc(0.625rem+env(safe-area-inset-bottom))] sm:pb-2.5 shrink-0", children: [
|
|
9887
10034
|
/* @__PURE__ */ jsx(
|
|
9888
|
-
|
|
10035
|
+
Button,
|
|
9889
10036
|
{
|
|
10037
|
+
variant: "bare",
|
|
10038
|
+
size: "bare",
|
|
9890
10039
|
type: "button",
|
|
9891
10040
|
onClick: () => setExecutando(null),
|
|
9892
10041
|
className: "rounded-button px-2 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground",
|
|
@@ -9894,8 +10043,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
9894
10043
|
}
|
|
9895
10044
|
),
|
|
9896
10045
|
/* @__PURE__ */ jsx(
|
|
9897
|
-
|
|
10046
|
+
Button,
|
|
9898
10047
|
{
|
|
10048
|
+
variant: "bare",
|
|
10049
|
+
size: "bare",
|
|
9899
10050
|
type: "button",
|
|
9900
10051
|
onClick: salvarExecucao,
|
|
9901
10052
|
disabled: salvando,
|
|
@@ -9911,18 +10062,20 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
9911
10062
|
] }), aoVoltar: () => setLancando(null), children: [
|
|
9912
10063
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-5 py-3 space-y-3", children: [
|
|
9913
10064
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
9914
|
-
/* @__PURE__ */ jsx(
|
|
9915
|
-
|
|
10065
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(
|
|
10066
|
+
Input,
|
|
9916
10067
|
{
|
|
9917
10068
|
value: buscaInsumo,
|
|
9918
10069
|
onChange: (e) => setBuscaInsumo(e.target.value),
|
|
9919
10070
|
placeholder: "Buscar produto\u2026",
|
|
9920
|
-
className: "
|
|
10071
|
+
className: "h-auto px-2.5 py-1.5"
|
|
9921
10072
|
}
|
|
9922
|
-
),
|
|
10073
|
+
) }),
|
|
9923
10074
|
/* @__PURE__ */ jsx(
|
|
9924
|
-
|
|
10075
|
+
Button,
|
|
9925
10076
|
{
|
|
10077
|
+
variant: "bare",
|
|
10078
|
+
size: "bare",
|
|
9926
10079
|
type: "button",
|
|
9927
10080
|
onClick: trazerPadrao,
|
|
9928
10081
|
className: "shrink-0 rounded-button border border-input px-2.5 py-1.5 text-xs font-medium hover:bg-muted",
|
|
@@ -9932,35 +10085,39 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
9932
10085
|
] }),
|
|
9933
10086
|
usados.length > 0 && /* @__PURE__ */ jsx("ul", { className: "divide-y rounded-lg border", children: usados.map((u) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2 px-3 py-2", children: [
|
|
9934
10087
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm", children: u.name }),
|
|
9935
|
-
/* @__PURE__ */ jsx(
|
|
9936
|
-
|
|
10088
|
+
/* @__PURE__ */ jsx("div", { className: "w-16 shrink-0", children: /* @__PURE__ */ jsx(
|
|
10089
|
+
Input,
|
|
9937
10090
|
{
|
|
9938
10091
|
type: "number",
|
|
9939
10092
|
min: 0,
|
|
9940
10093
|
step: "0.01",
|
|
9941
10094
|
value: u.qtd,
|
|
9942
10095
|
onChange: (e) => setUsados((xs) => xs.map((x) => x.productId === u.productId ? { ...x, qtd: Math.max(0, Number(e.target.value) || 0) } : x)),
|
|
9943
|
-
className: "
|
|
10096
|
+
className: "h-auto px-1.5 py-1 text-center text-xs",
|
|
9944
10097
|
"aria-label": `Quantidade de ${u.name}`
|
|
9945
10098
|
}
|
|
9946
|
-
),
|
|
10099
|
+
) }),
|
|
9947
10100
|
/* @__PURE__ */ jsx(
|
|
9948
|
-
|
|
10101
|
+
Button,
|
|
9949
10102
|
{
|
|
10103
|
+
variant: "bare",
|
|
10104
|
+
size: "bare",
|
|
9950
10105
|
type: "button",
|
|
9951
10106
|
onClick: () => setUsados((xs) => xs.filter((x) => x.productId !== u.productId)),
|
|
9952
|
-
className: "shrink-0 text-xs text-destructive hover:underline",
|
|
10107
|
+
className: "font-normal shrink-0 text-xs text-destructive hover:underline",
|
|
9953
10108
|
children: "Tirar"
|
|
9954
10109
|
}
|
|
9955
10110
|
)
|
|
9956
10111
|
] }, u.productId)) }),
|
|
9957
10112
|
/* @__PURE__ */ jsxs("ul", { className: "max-h-48 space-y-0.5 overflow-y-auto", children: [
|
|
9958
10113
|
insumos.filter((i) => !usados.some((u) => u.productId === i.id)).map((i) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
9959
|
-
|
|
10114
|
+
Button,
|
|
9960
10115
|
{
|
|
10116
|
+
variant: "bare",
|
|
10117
|
+
size: "bare",
|
|
9961
10118
|
type: "button",
|
|
9962
10119
|
onClick: () => setUsados((xs) => [...xs, { productId: i.id, name: i.name, qtd: 1, unitId: null }]),
|
|
9963
|
-
className: "w-full truncate rounded-lg px-2 py-1.5 text-left text-sm hover:bg-muted",
|
|
10120
|
+
className: "font-normal block justify-start w-full truncate rounded-lg px-2 py-1.5 text-left text-sm hover:bg-muted",
|
|
9964
10121
|
children: i.name
|
|
9965
10122
|
}
|
|
9966
10123
|
) }, i.id)),
|
|
@@ -9972,8 +10129,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
9972
10129
|
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground", children: usados.length === 0 ? "Concluir sem lan\xE7ar nada \xE9 v\xE1lido." : `${usados.length} produto${usados.length > 1 ? "s" : ""}` }),
|
|
9973
10130
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
9974
10131
|
/* @__PURE__ */ jsx(
|
|
9975
|
-
|
|
10132
|
+
Button,
|
|
9976
10133
|
{
|
|
10134
|
+
variant: "bare",
|
|
10135
|
+
size: "bare",
|
|
9977
10136
|
type: "button",
|
|
9978
10137
|
onClick: () => setLancando(null),
|
|
9979
10138
|
className: "rounded-button px-2 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground",
|
|
@@ -9981,8 +10140,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
9981
10140
|
}
|
|
9982
10141
|
),
|
|
9983
10142
|
/* @__PURE__ */ jsx(
|
|
9984
|
-
|
|
10143
|
+
Button,
|
|
9985
10144
|
{
|
|
10145
|
+
variant: "bare",
|
|
10146
|
+
size: "bare",
|
|
9986
10147
|
type: "button",
|
|
9987
10148
|
onClick: concluirProdutos,
|
|
9988
10149
|
disabled: salvando,
|
|
@@ -9997,46 +10158,50 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
9997
10158
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-5 py-3 space-y-3", children: [
|
|
9998
10159
|
indicados.length > 0 && /* @__PURE__ */ jsx("ul", { className: "divide-y rounded-lg border", children: indicados.map((i) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2 px-3 py-2", children: [
|
|
9999
10160
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm", children: i.name }),
|
|
10000
|
-
/* @__PURE__ */ jsx(
|
|
10001
|
-
|
|
10161
|
+
/* @__PURE__ */ jsx("div", { className: "w-12 shrink-0", children: /* @__PURE__ */ jsx(
|
|
10162
|
+
Input,
|
|
10002
10163
|
{
|
|
10003
10164
|
type: "number",
|
|
10004
10165
|
min: 1,
|
|
10005
10166
|
value: i.qtd,
|
|
10006
10167
|
onChange: (e) => setIndicados((xs) => xs.map((x) => x.id === i.id ? { ...x, qtd: Math.max(1, Math.floor(Number(e.target.value) || 1)) } : x)),
|
|
10007
|
-
className: "
|
|
10168
|
+
className: "h-auto px-1.5 py-1 text-center text-xs",
|
|
10008
10169
|
"aria-label": `Quantidade de ${i.name}`
|
|
10009
10170
|
}
|
|
10010
|
-
),
|
|
10171
|
+
) }),
|
|
10011
10172
|
/* @__PURE__ */ jsx(
|
|
10012
|
-
|
|
10173
|
+
Button,
|
|
10013
10174
|
{
|
|
10175
|
+
variant: "bare",
|
|
10176
|
+
size: "bare",
|
|
10014
10177
|
type: "button",
|
|
10015
10178
|
onClick: () => setIndicados((xs) => xs.filter((x) => x.id !== i.id)),
|
|
10016
|
-
className: "shrink-0 text-xs text-destructive hover:underline",
|
|
10179
|
+
className: "font-normal shrink-0 text-xs text-destructive hover:underline",
|
|
10017
10180
|
children: "Tirar"
|
|
10018
10181
|
}
|
|
10019
10182
|
)
|
|
10020
10183
|
] }, i.id)) }),
|
|
10021
10184
|
/* @__PURE__ */ jsx(
|
|
10022
|
-
|
|
10185
|
+
Input,
|
|
10023
10186
|
{
|
|
10024
10187
|
value: busca,
|
|
10025
10188
|
onChange: (e) => setBusca(e.target.value),
|
|
10026
10189
|
placeholder: "Buscar servi\xE7o para indicar\u2026",
|
|
10027
|
-
className: "
|
|
10190
|
+
className: "h-auto px-2.5 py-1.5"
|
|
10028
10191
|
}
|
|
10029
10192
|
),
|
|
10030
10193
|
/* @__PURE__ */ jsxs("ul", { className: "max-h-56 space-y-0.5 overflow-y-auto", children: [
|
|
10031
10194
|
catalogo.filter((c) => !indicados.some((i) => i.id === c.id)).map((c) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
10032
|
-
|
|
10195
|
+
Button,
|
|
10033
10196
|
{
|
|
10197
|
+
variant: "bare",
|
|
10198
|
+
size: "bare",
|
|
10034
10199
|
type: "button",
|
|
10035
10200
|
onClick: () => setIndicados((xs) => [...xs, { ...c, qtd: 1 }]),
|
|
10036
|
-
className: "flex w-full items-center gap-2 rounded-lg px-2 py-1.5 text-left hover:bg-muted",
|
|
10201
|
+
className: "font-normal justify-start whitespace-normal flex w-full items-center gap-2 rounded-lg px-2 py-1.5 text-left hover:bg-muted",
|
|
10037
10202
|
children: [
|
|
10038
10203
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm", children: c.name }),
|
|
10039
|
-
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: c.price
|
|
10204
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: formatCurrency(c.price, "BRL") })
|
|
10040
10205
|
]
|
|
10041
10206
|
}
|
|
10042
10207
|
) }, c.id)),
|
|
@@ -10047,8 +10212,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10047
10212
|
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground", children: indicados.length === 0 ? "Concluir sem indicar nada \xE9 v\xE1lido." : `${indicados.length} indicado${indicados.length > 1 ? "s" : ""}` }),
|
|
10048
10213
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
10049
10214
|
/* @__PURE__ */ jsx(
|
|
10050
|
-
|
|
10215
|
+
Button,
|
|
10051
10216
|
{
|
|
10217
|
+
variant: "bare",
|
|
10218
|
+
size: "bare",
|
|
10052
10219
|
type: "button",
|
|
10053
10220
|
onClick: () => setAvaliando(false),
|
|
10054
10221
|
className: "rounded-button px-2 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground",
|
|
@@ -10056,8 +10223,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10056
10223
|
}
|
|
10057
10224
|
),
|
|
10058
10225
|
/* @__PURE__ */ jsx(
|
|
10059
|
-
|
|
10226
|
+
Button,
|
|
10060
10227
|
{
|
|
10228
|
+
variant: "bare",
|
|
10229
|
+
size: "bare",
|
|
10061
10230
|
type: "button",
|
|
10062
10231
|
onClick: concluirAvaliacao,
|
|
10063
10232
|
disabled: salvando,
|
|
@@ -10095,8 +10264,9 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10095
10264
|
titulo: /* @__PURE__ */ jsx(Fragment, { children: preenchendo.refName ?? "Formul\xE1rio" }),
|
|
10096
10265
|
aoVoltar: () => setPreenchendo(null),
|
|
10097
10266
|
children: /* @__PURE__ */ jsx(
|
|
10098
|
-
|
|
10267
|
+
WidgetSlot,
|
|
10099
10268
|
{
|
|
10269
|
+
zone: FORMS_ZONES.formFill,
|
|
10100
10270
|
frame: "inline",
|
|
10101
10271
|
templateId: preenchendo.refId,
|
|
10102
10272
|
personId: booking.clientId,
|
|
@@ -10126,8 +10296,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10126
10296
|
] }),
|
|
10127
10297
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-t px-5 py-2.5 pb-[calc(0.625rem+env(safe-area-inset-bottom))] sm:pb-2.5 shrink-0", children: [
|
|
10128
10298
|
/* @__PURE__ */ jsx(
|
|
10129
|
-
|
|
10299
|
+
Button,
|
|
10130
10300
|
{
|
|
10301
|
+
variant: "bare",
|
|
10302
|
+
size: "bare",
|
|
10131
10303
|
type: "button",
|
|
10132
10304
|
onClick: () => setConfirmando(null),
|
|
10133
10305
|
className: "rounded-button px-2 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground",
|
|
@@ -10135,8 +10307,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10135
10307
|
}
|
|
10136
10308
|
),
|
|
10137
10309
|
/* @__PURE__ */ jsx(
|
|
10138
|
-
|
|
10310
|
+
Button,
|
|
10139
10311
|
{
|
|
10312
|
+
variant: "bare",
|
|
10313
|
+
size: "bare",
|
|
10140
10314
|
type: "button",
|
|
10141
10315
|
onClick: () => finalizar(true),
|
|
10142
10316
|
disabled: encerrando,
|
|
@@ -10152,13 +10326,11 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10152
10326
|
const qtd = marcados[id] ?? 0;
|
|
10153
10327
|
return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-3 py-2.5", children: [
|
|
10154
10328
|
/* @__PURE__ */ jsx(
|
|
10155
|
-
|
|
10329
|
+
Checkbox,
|
|
10156
10330
|
{
|
|
10157
|
-
type: "checkbox",
|
|
10158
10331
|
checked: qtd > 0,
|
|
10159
10332
|
disabled: !id,
|
|
10160
|
-
onChange: (
|
|
10161
|
-
className: "h-4 w-4 shrink-0 rounded border-input",
|
|
10333
|
+
onChange: (on) => id && setMarcados((m) => ({ ...m, [id]: on ? Math.max(1, qtd) : 0 })),
|
|
10162
10334
|
"aria-label": sv.name
|
|
10163
10335
|
}
|
|
10164
10336
|
),
|
|
@@ -10173,8 +10345,8 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10173
10345
|
sv.quantity > 1 ? ` \xB7 ${sv.quantity} indicados` : ""
|
|
10174
10346
|
] })
|
|
10175
10347
|
] }),
|
|
10176
|
-
/* @__PURE__ */ jsx(
|
|
10177
|
-
|
|
10348
|
+
/* @__PURE__ */ jsx("div", { className: "w-12 shrink-0", children: /* @__PURE__ */ jsx(
|
|
10349
|
+
Input,
|
|
10178
10350
|
{
|
|
10179
10351
|
type: "number",
|
|
10180
10352
|
min: 0,
|
|
@@ -10186,17 +10358,19 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10186
10358
|
const n = Math.floor(Number(e.target.value) || 0);
|
|
10187
10359
|
setMarcados((m) => ({ ...m, [id]: Math.max(0, Math.min(sv.quantity, n)) }));
|
|
10188
10360
|
},
|
|
10189
|
-
className: "
|
|
10361
|
+
className: "h-auto px-1.5 py-1 text-center text-xs disabled:opacity-40",
|
|
10190
10362
|
"aria-label": `Quantidade de ${sv.name}`
|
|
10191
10363
|
}
|
|
10192
|
-
),
|
|
10193
|
-
/* @__PURE__ */ jsx("span", { className: "w-20 shrink-0 text-right text-xs tabular-nums", children: sv.price
|
|
10364
|
+
) }),
|
|
10365
|
+
/* @__PURE__ */ jsx("span", { className: "w-20 shrink-0 text-right text-xs tabular-nums", children: formatCurrency(sv.price, "BRL") })
|
|
10194
10366
|
] }, sv.id);
|
|
10195
10367
|
}) }) }),
|
|
10196
10368
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-t px-5 py-2.5 pb-[calc(0.625rem+env(safe-area-inset-bottom))] sm:pb-2.5 shrink-0", children: [
|
|
10197
10369
|
/* @__PURE__ */ jsx(
|
|
10198
|
-
|
|
10370
|
+
Button,
|
|
10199
10371
|
{
|
|
10372
|
+
variant: "bare",
|
|
10373
|
+
size: "bare",
|
|
10200
10374
|
type: "button",
|
|
10201
10375
|
onClick: () => setContratando(false),
|
|
10202
10376
|
className: "rounded-button px-2 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground",
|
|
@@ -10204,8 +10378,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10204
10378
|
}
|
|
10205
10379
|
),
|
|
10206
10380
|
/* @__PURE__ */ jsx(
|
|
10207
|
-
|
|
10381
|
+
Button,
|
|
10208
10382
|
{
|
|
10383
|
+
variant: "bare",
|
|
10384
|
+
size: "bare",
|
|
10209
10385
|
type: "button",
|
|
10210
10386
|
onClick: contratar,
|
|
10211
10387
|
disabled: salvando || !Object.values(marcados).some((q) => q > 0),
|
|
@@ -10213,7 +10389,7 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10213
10389
|
children: salvando ? "Contratando\u2026" : (() => {
|
|
10214
10390
|
const escolhidos = servicos.filter((sv) => sv.serviceId && (marcados[sv.serviceId] ?? 0) > 0);
|
|
10215
10391
|
const total = escolhidos.reduce((t2, sv) => t2 + sv.price * (marcados[sv.serviceId] ?? 0), 0);
|
|
10216
|
-
return `Contratar (${escolhidos.length}) \xB7 ${total
|
|
10392
|
+
return `Contratar (${escolhidos.length}) \xB7 ${formatCurrency(total, "BRL")}`;
|
|
10217
10393
|
})()
|
|
10218
10394
|
}
|
|
10219
10395
|
)
|
|
@@ -10255,7 +10431,7 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10255
10431
|
Bola,
|
|
10256
10432
|
{
|
|
10257
10433
|
r,
|
|
10258
|
-
onClick: r.kind === "form" && r.refId && r.status === "pending" && booking.clientId ? () => setPreenchendo(r) : (r.kind === "contract" || r.kind === "session_term") && r.refId ? () => {
|
|
10434
|
+
onClick: formsFillable && r.kind === "form" && r.refId && r.status === "pending" && booking.clientId ? () => setPreenchendo(r) : (r.kind === "contract" || r.kind === "session_term") && r.refId ? () => {
|
|
10259
10435
|
filaAssinatura.current = { ids: [], depois: null };
|
|
10260
10436
|
setAssinando(contratos.find((c) => c.id === r.refId) ?? null);
|
|
10261
10437
|
} : void 0
|
|
@@ -10284,7 +10460,7 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10284
10460
|
onClick: (
|
|
10285
10461
|
// Formulário pendente preenche em QUALQUER estado — antes de
|
|
10286
10462
|
// começar (a recepção) e depois de encerrar (o tardio do V1).
|
|
10287
|
-
r.kind === "form" && r.refId && r.status === "pending" && booking.clientId ? () => setPreenchendo(r) : somenteLeitura ? void 0 : r.kind === "revision_link" && r.status === "pending" ? () => setVinculando(r) : r.kind === "products" && r.status === "pending" ? () => {
|
|
10463
|
+
formsFillable && r.kind === "form" && r.refId && r.status === "pending" && booking.clientId ? () => setPreenchendo(r) : somenteLeitura ? void 0 : r.kind === "revision_link" && r.status === "pending" ? () => setVinculando(r) : r.kind === "products" && r.status === "pending" ? () => {
|
|
10288
10464
|
setUsados([]);
|
|
10289
10465
|
setLancando({ serviceId: r.serviceId ?? "", serviceName: s.nome });
|
|
10290
10466
|
} : r.kind === "evaluation" && r.status === "pending" ? () => setAvaliando(true) : r.kind === "invoice_item" && r.status === "pending" ? abrirContratacao : void 0
|
|
@@ -10299,7 +10475,7 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10299
10475
|
/* @__PURE__ */ jsx("ul", { className: "space-y-2", children: record.map((s) => /* @__PURE__ */ jsxs("li", { className: "rounded-xl border px-3 py-2.5", children: [
|
|
10300
10476
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2 gap-y-0.5", children: [
|
|
10301
10477
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: s.serviceName ?? "Servi\xE7o n\xE3o informado" }),
|
|
10302
|
-
s.price != null && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: s.price
|
|
10478
|
+
s.price != null && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: formatCurrency(s.price, "BRL") })
|
|
10303
10479
|
] }),
|
|
10304
10480
|
s.hadPerformer && /* @__PURE__ */ jsxs("p", { className: "mt-0.5 flex items-center gap-1.5 text-[11px] text-muted-foreground", children: [
|
|
10305
10481
|
/* @__PURE__ */ jsx(UserRound, { className: "h-3 w-3 shrink-0", "aria-hidden": true }),
|
|
@@ -10341,8 +10517,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10341
10517
|
return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
10342
10518
|
(recusaInicio || semFicha || deOutro) && /* @__PURE__ */ jsx("span", { className: "truncate text-[11px] text-muted-foreground", children: recusaInicio ?? (semFicha ? "Atender exige um login ligado a uma ficha de profissional." : "Este atendimento \xE9 de outro profissional.") }),
|
|
10343
10519
|
/* @__PURE__ */ jsx(
|
|
10344
|
-
|
|
10520
|
+
Button,
|
|
10345
10521
|
{
|
|
10522
|
+
variant: "bare",
|
|
10523
|
+
size: "bare",
|
|
10346
10524
|
type: "button",
|
|
10347
10525
|
disabled: semFicha || deOutro || iniciando,
|
|
10348
10526
|
onClick: async () => {
|
|
@@ -10372,8 +10550,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10372
10550
|
faltaParaTerminar.length > 1 ? ` e mais ${faltaParaTerminar.length - 1}` : ""
|
|
10373
10551
|
] }),
|
|
10374
10552
|
!somenteLeitura && /* @__PURE__ */ jsx(
|
|
10375
|
-
|
|
10553
|
+
Button,
|
|
10376
10554
|
{
|
|
10555
|
+
variant: "bare",
|
|
10556
|
+
size: "bare",
|
|
10377
10557
|
type: "button",
|
|
10378
10558
|
onClick: pedirGravacao,
|
|
10379
10559
|
"aria-label": "Gravar atendimento",
|
|
@@ -10383,8 +10563,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10383
10563
|
}
|
|
10384
10564
|
),
|
|
10385
10565
|
!somenteLeitura && /* @__PURE__ */ jsx(
|
|
10386
|
-
|
|
10566
|
+
Button,
|
|
10387
10567
|
{
|
|
10568
|
+
variant: "bare",
|
|
10569
|
+
size: "bare",
|
|
10388
10570
|
type: "button",
|
|
10389
10571
|
onClick: abrirExecucao,
|
|
10390
10572
|
className: "shrink-0 rounded-button border border-input px-2.5 py-1.5 text-xs font-medium hover:bg-muted",
|
|
@@ -10392,8 +10574,10 @@ function AttendanceRuler({ booking, open, onClose, onFinished, frame = "modal" }
|
|
|
10392
10574
|
}
|
|
10393
10575
|
),
|
|
10394
10576
|
!somenteLeitura && /* @__PURE__ */ jsx(
|
|
10395
|
-
|
|
10577
|
+
Button,
|
|
10396
10578
|
{
|
|
10579
|
+
variant: "bare",
|
|
10580
|
+
size: "bare",
|
|
10397
10581
|
type: "button",
|
|
10398
10582
|
onClick: () => finalizar(false),
|
|
10399
10583
|
disabled: encerrando || faltaParaTerminar.length > 0,
|
|
@@ -10497,14 +10681,16 @@ function PersonAttendancesWidget({ personId }) {
|
|
|
10497
10681
|
/* @__PURE__ */ jsx("ul", { className: "space-y-2", children: linhas.map((l) => {
|
|
10498
10682
|
const completo = l.totais > 0 && l.feitas === l.totais;
|
|
10499
10683
|
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
10500
|
-
|
|
10684
|
+
Button,
|
|
10501
10685
|
{
|
|
10686
|
+
variant: "bare",
|
|
10687
|
+
size: "bare",
|
|
10502
10688
|
type: "button",
|
|
10503
10689
|
onClick: async () => {
|
|
10504
10690
|
const b = await provider2.getBookingById(l.bookingId);
|
|
10505
10691
|
if (b) setAberto(b);
|
|
10506
10692
|
},
|
|
10507
|
-
className: "flex w-full items-center gap-3 rounded-xl border border-border bg-card px-3 py-2 text-left hover:bg-muted/40",
|
|
10693
|
+
className: "font-normal justify-start whitespace-normal flex w-full items-center gap-3 rounded-xl border border-border bg-card px-3 py-2 text-left hover:bg-muted/40",
|
|
10508
10694
|
children: [
|
|
10509
10695
|
/* @__PURE__ */ jsx(Stethoscope, { className: "h-4 w-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
10510
10696
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
@@ -10516,7 +10702,7 @@ function PersonAttendancesWidget({ personId }) {
|
|
|
10516
10702
|
l.quando ? new Date(l.quando).toLocaleDateString("pt-BR") : "sem data",
|
|
10517
10703
|
l.profissional ? ` \xB7 ${l.profissional}` : "",
|
|
10518
10704
|
STATUS_LABEL[l.status] ? ` \xB7 ${STATUS_LABEL[l.status]}` : "",
|
|
10519
|
-
l.total != null ? ` \xB7 ${l.total
|
|
10705
|
+
l.total != null ? ` \xB7 ${formatCurrency(l.total, "BRL")}` : ""
|
|
10520
10706
|
] })
|
|
10521
10707
|
] }),
|
|
10522
10708
|
l.totais > 0 && /* @__PURE__ */ jsxs("span", { className: `inline-flex shrink-0 items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-medium ${completo ? "bg-success/15 text-success" : "bg-warning/15 text-warning-foreground"}`, children: [
|
|
@@ -10650,8 +10836,10 @@ function MyClientsTodayWidget() {
|
|
|
10650
10836
|
] })
|
|
10651
10837
|
] }),
|
|
10652
10838
|
/* @__PURE__ */ jsx(
|
|
10653
|
-
|
|
10839
|
+
Button,
|
|
10654
10840
|
{
|
|
10841
|
+
variant: "bare",
|
|
10842
|
+
size: "bare",
|
|
10655
10843
|
type: "button",
|
|
10656
10844
|
disabled: busy === b.id,
|
|
10657
10845
|
onClick: () => start(b),
|
|
@@ -10744,6 +10932,7 @@ function PersonServicesWidget({ personId }) {
|
|
|
10744
10932
|
|
|
10745
10933
|
// src/locales/en.ts
|
|
10746
10934
|
var en = {
|
|
10935
|
+
"registry.holidays": "Holidays",
|
|
10747
10936
|
"agenda.appointment.addDescription": "Add description...",
|
|
10748
10937
|
"agenda.appointment.addService": "Add service",
|
|
10749
10938
|
"agenda.appointment.cancel": "Cancel",
|
|
@@ -11056,6 +11245,7 @@ var en = {
|
|
|
11056
11245
|
|
|
11057
11246
|
// src/locales/pt-BR.ts
|
|
11058
11247
|
var ptBR = {
|
|
11248
|
+
"registry.holidays": "Feriados",
|
|
11059
11249
|
"agenda.appointment.addDescription": "Adicionar descri\xE7\xE3o...",
|
|
11060
11250
|
"agenda.appointment.addService": "Adicionar servi\xE7o",
|
|
11061
11251
|
"agenda.appointment.cancel": "Cancelar",
|
|
@@ -18669,12 +18859,15 @@ function AreaColumn({ group, canEdit, canDelete, onAct, onCall }) {
|
|
|
18669
18859
|
] })
|
|
18670
18860
|
] }),
|
|
18671
18861
|
canEdit ? /* @__PURE__ */ jsxs(
|
|
18672
|
-
|
|
18862
|
+
Button,
|
|
18673
18863
|
{
|
|
18864
|
+
variant: "bare",
|
|
18865
|
+
size: "bare",
|
|
18674
18866
|
type: "button",
|
|
18675
18867
|
disabled: !firstAvailable,
|
|
18676
18868
|
onClick: () => onCall(group),
|
|
18677
18869
|
className: cn(
|
|
18870
|
+
"whitespace-normal",
|
|
18678
18871
|
"inline-flex h-9 w-full items-center justify-center gap-2 rounded-lg px-3 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-45",
|
|
18679
18872
|
tone.button
|
|
18680
18873
|
),
|
|
@@ -19005,6 +19198,16 @@ var COLUMNS = [
|
|
|
19005
19198
|
{ key: "ausencias", label: "Aus\xEAncias" },
|
|
19006
19199
|
{ key: "minutosAusente", label: "Minutos ausente" }
|
|
19007
19200
|
];
|
|
19201
|
+
var REPORT_COLUMNS = [
|
|
19202
|
+
{ id: "professional", header: "Profissional", cell: ({ row: { original: r } }) => /* @__PURE__ */ jsx("span", { className: "text-foreground", children: r.professionalName }) },
|
|
19203
|
+
{ id: "unit", header: "Unidade", cell: ({ row: { original: r } }) => /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: r.unitName }) },
|
|
19204
|
+
...COLUMNS.map((c) => ({
|
|
19205
|
+
id: String(c.key),
|
|
19206
|
+
header: c.label,
|
|
19207
|
+
meta: { className: "text-right tabular-nums" },
|
|
19208
|
+
cell: ({ row: { original: r } }) => Number(r[c.key])
|
|
19209
|
+
}))
|
|
19210
|
+
];
|
|
19008
19211
|
function Kpi({ label, value }) {
|
|
19009
19212
|
return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(CardContent, { className: "p-4", children: [
|
|
19010
19213
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: label }),
|
|
@@ -19108,18 +19311,14 @@ function TurnQueueReportPage({ provider: provider2 }) {
|
|
|
19108
19311
|
/* @__PURE__ */ jsx("span", { className: "text-right tabular-nums text-muted-foreground", children: r.atendimentos })
|
|
19109
19312
|
] }, `${r.unitId}:${r.professionalId}`)) })
|
|
19110
19313
|
] }) }),
|
|
19111
|
-
rows.length > 0 ? /* @__PURE__ */ jsx(
|
|
19112
|
-
|
|
19113
|
-
|
|
19114
|
-
|
|
19115
|
-
|
|
19116
|
-
|
|
19117
|
-
|
|
19118
|
-
|
|
19119
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-2 text-muted-foreground", children: r.unitName }),
|
|
19120
|
-
COLUMNS.map((c) => /* @__PURE__ */ jsx("td", { className: "px-3 py-2 text-right tabular-nums text-foreground", children: Number(r[c.key]) }, c.key))
|
|
19121
|
-
] }, `${r.unitId}:${r.professionalId}`)) })
|
|
19122
|
-
] }) }) }) : null
|
|
19314
|
+
rows.length > 0 ? /* @__PURE__ */ jsx(
|
|
19315
|
+
DataTable,
|
|
19316
|
+
{
|
|
19317
|
+
columns: REPORT_COLUMNS,
|
|
19318
|
+
data: rows,
|
|
19319
|
+
getRowId: (r) => `${r.unitId}:${r.professionalId}`
|
|
19320
|
+
}
|
|
19321
|
+
) : null
|
|
19123
19322
|
] })
|
|
19124
19323
|
] }) });
|
|
19125
19324
|
}
|
|
@@ -19196,7 +19395,7 @@ function UnitTurnQueueWidget({ item }) {
|
|
|
19196
19395
|
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
19197
19396
|
"Vem do endere\xE7o da unidade.",
|
|
19198
19397
|
" ",
|
|
19199
|
-
/* @__PURE__ */ jsx("
|
|
19398
|
+
/* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", type: "button", className: "text-xs font-normal underline decoration-dashed underline-offset-2", onClick: () => adminNavigateTo(`/settings/locations/${item?.id}/edit`), children: "Editar endere\xE7o" })
|
|
19200
19399
|
] })
|
|
19201
19400
|
] }),
|
|
19202
19401
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
@@ -19287,6 +19486,44 @@ function createAgendaTurnQueuePlugin(options = {}) {
|
|
|
19287
19486
|
}]
|
|
19288
19487
|
};
|
|
19289
19488
|
}
|
|
19489
|
+
var agendaV1SettingsTabs = [
|
|
19490
|
+
defineSettingsTab({
|
|
19491
|
+
id: "agenda-kiosks",
|
|
19492
|
+
label: tl("Kiosks", "Totens"),
|
|
19493
|
+
icon: "Smartphone",
|
|
19494
|
+
section: "operations",
|
|
19495
|
+
requiresFacet: "kiosk",
|
|
19496
|
+
pending: true,
|
|
19497
|
+
defaults: { "kiosk.amenities_enabled": true, "kiosk.walk_in_enabled": true, "kiosk.face_recognition_enabled": false, "kiosk.checkin_window_minutes": 15 },
|
|
19498
|
+
sections: [{
|
|
19499
|
+
fields: [
|
|
19500
|
+
{ key: "kiosk.walk_in_enabled", type: "boolean", scope: "unit", label: tl("Walk-ins can check in", "Aceitar encaixe no totem") },
|
|
19501
|
+
{ key: "kiosk.checkin_window_minutes", type: "number", scope: "unit", min: 0, max: 120, label: tl("Automatic check-in window (min)", "Janela de check-in autom\xE1tico (min)") },
|
|
19502
|
+
{ key: "kiosk.amenities_enabled", type: "boolean", scope: "unit", label: tl("Offer water and coffee", "Oferecer \xE1gua e caf\xE9") },
|
|
19503
|
+
{ key: "kiosk.face_recognition_enabled", type: "boolean", scope: "unit", label: tl("Face recognition", "Reconhecimento facial") },
|
|
19504
|
+
{ key: "kiosk.welcome_message", type: "string", scope: "unit", label: tl("Welcome message", "Mensagem de boas-vindas") }
|
|
19505
|
+
]
|
|
19506
|
+
}]
|
|
19507
|
+
}),
|
|
19508
|
+
defineSettingsTab({
|
|
19509
|
+
id: "agenda-attendance-steps",
|
|
19510
|
+
label: tl("Order", "Ordem"),
|
|
19511
|
+
icon: "ListOrdered",
|
|
19512
|
+
section: "operations",
|
|
19513
|
+
parent: attendanceSettingsParent(),
|
|
19514
|
+
order: 1,
|
|
19515
|
+
keywords: [tl("Attendance steps", "Ordem das etapas"), tl("Steps", "Etapas")],
|
|
19516
|
+
pending: true,
|
|
19517
|
+
defaults: { "attendance.block_finish_pending_steps": false, "attendance.footer_block_finish_pending_steps": false },
|
|
19518
|
+
sections: [{
|
|
19519
|
+
fields: [
|
|
19520
|
+
{ key: "attendance.sections_flow", type: "boolean", label: tl("Clinical attendance by sections", "Atendimento cl\xEDnico por se\xE7\xF5es") },
|
|
19521
|
+
{ key: "attendance.block_finish_pending_steps", type: "boolean", label: tl("Block finishing with a pending step (professional screen)", "Bloquear finalizar com etapa pendente (tela do profissional)") },
|
|
19522
|
+
{ key: "attendance.footer_block_finish_pending_steps", type: "boolean", label: tl("Block finishing with a pending step (footer)", "Bloquear finalizar com etapa pendente (rodap\xE9)") }
|
|
19523
|
+
]
|
|
19524
|
+
}]
|
|
19525
|
+
})
|
|
19526
|
+
];
|
|
19290
19527
|
function computeCommissionAmount(total, ratePercent) {
|
|
19291
19528
|
const base = Number(total) || 0;
|
|
19292
19529
|
const rate = Number(ratePercent) || 0;
|
|
@@ -19955,12 +20192,12 @@ function ChannelMappingList({
|
|
|
19955
20192
|
]
|
|
19956
20193
|
}
|
|
19957
20194
|
) : /* @__PURE__ */ jsx(
|
|
19958
|
-
|
|
20195
|
+
Input,
|
|
19959
20196
|
{
|
|
19960
20197
|
defaultValue: ch?.targetId ?? "",
|
|
19961
20198
|
placeholder: "uuid",
|
|
19962
20199
|
onBlur: (e) => void persist(cal, { targetId: e.target.value.trim() || null }),
|
|
19963
|
-
className: "
|
|
20200
|
+
className: "mt-1 h-8 px-2"
|
|
19964
20201
|
}
|
|
19965
20202
|
)
|
|
19966
20203
|
] }),
|
|
@@ -20059,8 +20296,10 @@ function ImportEventsWizard({
|
|
|
20059
20296
|
/* @__PURE__ */ jsx(CalendarPlus, { className: "h-4 w-4 text-muted-foreground" }),
|
|
20060
20297
|
/* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold", children: "Import future events" }),
|
|
20061
20298
|
/* @__PURE__ */ jsx(
|
|
20062
|
-
|
|
20299
|
+
Button,
|
|
20063
20300
|
{
|
|
20301
|
+
variant: "bare",
|
|
20302
|
+
size: "bare",
|
|
20064
20303
|
onClick: onClose,
|
|
20065
20304
|
className: "ml-auto rounded p-1 text-muted-foreground hover:bg-muted/50",
|
|
20066
20305
|
"aria-label": "Close",
|
|
@@ -22656,7 +22895,8 @@ function createAgendaPlugin(options) {
|
|
|
22656
22895
|
// Módulos, e é a facet resolvida (`config.facets`, ver `resolvePluginRuntime`)
|
|
22657
22896
|
// que decide se a rota e a linha de menu existem — não mais a opção.
|
|
22658
22897
|
{ id: "checkin", label: "Check-in", description: "Fila de recep\xE7\xE3o, ao lado da Agenda." },
|
|
22659
|
-
{ id: "confirmations", label: config.labels.confirmations, description: "Fila de quem falta confirmar." }
|
|
22898
|
+
{ id: "confirmations", label: config.labels.confirmations, description: "Fila de quem falta confirmar." },
|
|
22899
|
+
{ id: "kiosk", label: "Totens", description: "Check-in do cliente sozinho no totem da recep\xE7\xE3o." }
|
|
22660
22900
|
],
|
|
22661
22901
|
dependencies: [],
|
|
22662
22902
|
// Os FATOS da agenda — só expostos enquanto o módulo está ATIVO.
|
|
@@ -22961,6 +23201,7 @@ function createAgendaPlugin(options) {
|
|
|
22961
23201
|
],
|
|
22962
23202
|
registries,
|
|
22963
23203
|
settings: [
|
|
23204
|
+
...agendaV1SettingsTabs,
|
|
22964
23205
|
{
|
|
22965
23206
|
id: "agenda",
|
|
22966
23207
|
label: "Agenda",
|
|
@@ -22970,6 +23211,7 @@ function createAgendaPlugin(options) {
|
|
|
22970
23211
|
const AgendaSettingsTab = () => React23.createElement(PluginSettingsPanel, {
|
|
22971
23212
|
title: "Agenda",
|
|
22972
23213
|
generalSettings: React23.createElement(AgendaGeneralSettings),
|
|
23214
|
+
customTabs: [{ id: "messages", label: tl("Message templates", "Templates de mensagem"), icon: "MessageSquareText", content: React23.createElement(AgendaMessageTemplates) }],
|
|
22973
23215
|
registries,
|
|
22974
23216
|
hostPluginId: "agenda",
|
|
22975
23217
|
routeBase: "/settings/agenda"
|
|
@@ -22978,6 +23220,9 @@ function createAgendaPlugin(options) {
|
|
|
22978
23220
|
return AgendaSettingsTab;
|
|
22979
23221
|
})(),
|
|
22980
23222
|
order: 5,
|
|
23223
|
+
// V1's "Confirmação manual" was a line of its own; it is the first template here now.
|
|
23224
|
+
aliases: [{ id: "conversations-manual-confirmation", href: "/settings/agenda/messages" }],
|
|
23225
|
+
keywords: [tl("Manual confirmation", "Confirma\xE7\xE3o manual"), tl("Message templates", "Templates de mensagem")],
|
|
22981
23226
|
permission: { feature: "agenda", action: "read" }
|
|
22982
23227
|
}
|
|
22983
23228
|
],
|