@fayz-ai/plugin-agenda 0.8.1 → 0.8.4

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.
Files changed (118) hide show
  1. package/dist/{chunk-DRZF6CV2.js → chunk-Q2PAWBPR.js} +62 -3
  2. package/dist/chunk-Q2PAWBPR.js.map +1 -0
  3. package/dist/{chunk-LFUELUIT.cjs → chunk-RX2HMWXS.cjs} +62 -2
  4. package/dist/chunk-RX2HMWXS.cjs.map +1 -0
  5. package/dist/components/AgendaGeneralSettings.d.ts.map +1 -1
  6. package/dist/components/AppointmentModal.d.ts.map +1 -1
  7. package/dist/components/CalendarToolbar.d.ts.map +1 -1
  8. package/dist/data/supabase.d.ts +5 -1
  9. package/dist/data/supabase.d.ts.map +1 -1
  10. package/dist/index.cjs +1078 -768
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +921 -611
  14. package/dist/index.js.map +1 -1
  15. package/dist/integrations/google-calendar/components/CalendarColorDot.d.ts +6 -0
  16. package/dist/integrations/google-calendar/components/CalendarColorDot.d.ts.map +1 -0
  17. package/dist/integrations/google-calendar/components/ChannelMappingList.d.ts +9 -0
  18. package/dist/integrations/google-calendar/components/ChannelMappingList.d.ts.map +1 -0
  19. package/dist/integrations/google-calendar/components/ImportEventsWizard.d.ts +12 -0
  20. package/dist/integrations/google-calendar/components/ImportEventsWizard.d.ts.map +1 -0
  21. package/dist/integrations/google-calendar/components/useAgendaLookups.d.ts +26 -0
  22. package/dist/integrations/google-calendar/components/useAgendaLookups.d.ts.map +1 -0
  23. package/dist/integrations/google-calendar/connectorDef.d.ts.map +1 -1
  24. package/dist/integrations/google-calendar/data/supabase.d.ts +33 -1
  25. package/dist/integrations/google-calendar/data/supabase.d.ts.map +1 -1
  26. package/dist/integrations/google-calendar/data/tables.d.ts +6 -0
  27. package/dist/integrations/google-calendar/data/tables.d.ts.map +1 -0
  28. package/dist/integrations/google-calendar/index.d.ts +1 -1
  29. package/dist/integrations/google-calendar/index.d.ts.map +1 -1
  30. package/dist/integrations/google-calendar/mapping.d.ts +56 -4
  31. package/dist/integrations/google-calendar/mapping.d.ts.map +1 -1
  32. package/dist/integrations/google-calendar/types.d.ts +101 -0
  33. package/dist/integrations/google-calendar/types.d.ts.map +1 -1
  34. package/dist/locales/en.d.ts.map +1 -1
  35. package/dist/locales/pt-BR.d.ts.map +1 -1
  36. package/dist/migrations/index.d.ts +12 -1
  37. package/dist/migrations/index.d.ts.map +1 -1
  38. package/dist/public/BookingWidget.d.ts.map +1 -1
  39. package/dist/public/context.d.ts +3 -1
  40. package/dist/public/context.d.ts.map +1 -1
  41. package/dist/public/createPublicBookingPlugin.d.ts +7 -1
  42. package/dist/public/createPublicBookingPlugin.d.ts.map +1 -1
  43. package/dist/public/data.d.ts +6 -0
  44. package/dist/public/data.d.ts.map +1 -1
  45. package/dist/public/data.supabase.d.ts.map +1 -1
  46. package/dist/public/format.d.ts +22 -1
  47. package/dist/public/format.d.ts.map +1 -1
  48. package/dist/public/hooks.d.ts.map +1 -1
  49. package/dist/public/index.cjs +31 -63
  50. package/dist/public/index.cjs.map +1 -1
  51. package/dist/public/index.d.ts +1 -1
  52. package/dist/public/index.d.ts.map +1 -1
  53. package/dist/public/index.js +27 -61
  54. package/dist/public/index.js.map +1 -1
  55. package/dist/public/steps/ContactStep.d.ts +4 -2
  56. package/dist/public/steps/ContactStep.d.ts.map +1 -1
  57. package/dist/public/types.d.ts +16 -0
  58. package/dist/public/types.d.ts.map +1 -1
  59. package/dist/views/CalendarView.d.ts.map +1 -1
  60. package/package.json +5 -5
  61. package/src/components/AgendaGeneralSettings.tsx +38 -16
  62. package/src/components/AppointmentModal.tsx +50 -108
  63. package/src/components/CalendarToolbar.tsx +10 -7
  64. package/src/data/supabase.ts +67 -13
  65. package/src/index.ts +56 -8
  66. package/src/integrations/google-calendar/components/CalendarColorDot.tsx +23 -0
  67. package/src/integrations/google-calendar/components/ChannelMappingList.tsx +329 -0
  68. package/src/integrations/google-calendar/components/ImportEventsWizard.tsx +215 -0
  69. package/src/integrations/google-calendar/components/useAgendaLookups.ts +100 -0
  70. package/src/integrations/google-calendar/connectorDef.tsx +123 -40
  71. package/src/integrations/google-calendar/data/supabase.ts +109 -13
  72. package/src/integrations/google-calendar/data/tables.ts +12 -0
  73. package/src/integrations/google-calendar/index.ts +10 -1
  74. package/src/integrations/google-calendar/integration.test.ts +126 -1
  75. package/src/integrations/google-calendar/mapping.ts +149 -9
  76. package/src/integrations/google-calendar/migrations/001_google_calendar.sql +9 -6
  77. package/src/integrations/google-calendar/migrations/002_smart_sync.sql +517 -0
  78. package/src/integrations/google-calendar/migrations/003_plg_rename.sql +273 -0
  79. package/src/integrations/google-calendar/types.ts +111 -0
  80. package/src/locales/en.ts +1 -0
  81. package/src/locales/pt-BR.ts +1 -0
  82. package/src/migrations/001_public_booking.sql +7 -2
  83. package/src/migrations/003_public_client_kind.sql +175 -0
  84. package/src/migrations/004_public_booking_assignee.sql +176 -0
  85. package/src/migrations/005_agent_rpcs.sql +168 -0
  86. package/src/migrations/006_agent_rpc_localtime.sql +181 -0
  87. package/src/migrations/007_schedule_exception_precedence.sql +290 -0
  88. package/src/migrations/008_agent_rpc_exception_precedence.sql +172 -0
  89. package/src/migrations/009_public_booking_location.sql +162 -0
  90. package/src/migrations/010_public_service_curation.sql +31 -0
  91. package/src/migrations/011_default_assignee.sql +167 -0
  92. package/src/migrations/012_drop_legacy_booking_overload.sql +29 -0
  93. package/src/migrations/013_normalize_v_appointments.sql +199 -0
  94. package/src/migrations/index.ts +1791 -3
  95. package/src/public/BookingWidget.tsx +10 -1
  96. package/src/public/context.tsx +3 -0
  97. package/src/public/createPublicBookingPlugin.ts +14 -1
  98. package/src/public/data.supabase.ts +7 -4
  99. package/src/public/data.ts +6 -0
  100. package/src/public/format.ts +36 -1
  101. package/src/public/hooks.ts +7 -2
  102. package/src/public/index.ts +1 -0
  103. package/src/public/steps/ContactStep.tsx +10 -5
  104. package/src/public/types.ts +21 -0
  105. package/src/views/CalendarView.tsx +15 -1
  106. package/dist/chunk-3LJKZQK4.js +0 -12
  107. package/dist/chunk-3LJKZQK4.js.map +0 -1
  108. package/dist/chunk-DRZF6CV2.js.map +0 -1
  109. package/dist/chunk-LFUELUIT.cjs.map +0 -1
  110. package/dist/chunk-SYDBDI3Q.cjs +0 -15
  111. package/dist/chunk-SYDBDI3Q.cjs.map +0 -1
  112. package/dist/components/SearchCombobox.d.ts +0 -38
  113. package/dist/components/SearchCombobox.d.ts.map +0 -1
  114. package/dist/tenant-222EHYUC.cjs +0 -16
  115. package/dist/tenant-222EHYUC.cjs.map +0 -1
  116. package/dist/tenant-LAUWVUYB.js +0 -3
  117. package/dist/tenant-LAUWVUYB.js.map +0 -1
  118. package/src/components/SearchCombobox.tsx +0 -216
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var chunkLFUELUIT_cjs = require('../chunk-LFUELUIT.cjs');
3
+ var chunkRX2HMWXS_cjs = require('../chunk-RX2HMWXS.cjs');
4
4
  var react = require('react');
5
5
  var lucideReact = require('lucide-react');
6
- var core = require('@fayz-ai/core');
7
6
  var jsxRuntime = require('react/jsx-runtime');
7
+ var core = require('@fayz-ai/core');
8
8
 
9
9
  // src/public/data.ts
10
10
  function createMockPublicBookingProvider(options) {
11
- const inner = chunkLFUELUIT_cjs.createMockAgendaProvider({ seed: options.seed });
11
+ const inner = chunkRX2HMWXS_cjs.createMockAgendaProvider({ seed: options.seed });
12
12
  const { services, professionalId } = options;
13
13
  return {
14
14
  async getServices() {
@@ -49,58 +49,6 @@ function createMockPublicBookingProvider(options) {
49
49
  }
50
50
  };
51
51
  }
52
- function getClient() {
53
- return core.getSupabaseClientOptional() ?? core.getFayzCloudClient();
54
- }
55
- function toPhoneDigits(phone) {
56
- return (phone ?? "").replace(/\D/g, "");
57
- }
58
- function createSupabasePublicBookingProvider(options) {
59
- const { tenantId } = options;
60
- return {
61
- async getServices() {
62
- const { data, error } = await getClient().from("v_public_services").select("id, name, description, price, currency, duration_minutes, sort_order").eq("tenant_id", tenantId).order("sort_order", { ascending: true });
63
- if (error) throw new Error(`[plugin-agenda/public] getServices: ${error.message}`);
64
- return (data ?? []).map((row) => ({
65
- id: String(row.id),
66
- name: String(row.name),
67
- description: row.description ?? void 0,
68
- price: Number(row.price ?? 0),
69
- durationMinutes: Number(row.duration_minutes ?? 30)
70
- }));
71
- },
72
- async getAvailableSlots(query) {
73
- const { data, error } = await getClient().rpc("get_available_slots", {
74
- p_tenant_id: tenantId,
75
- p_assignee_id: query.assigneeId,
76
- p_date: query.date,
77
- p_duration_minutes: query.durationMinutes,
78
- p_slot_interval: query.slotInterval
79
- });
80
- if (error) throw new Error(`[plugin-agenda/public] getAvailableSlots: ${error.message}`);
81
- return (data ?? []).map((row) => ({
82
- start: row.slot_start,
83
- end: row.slot_end
84
- }));
85
- },
86
- async createBooking(input) {
87
- const phone = toPhoneDigits(input.contact.phone);
88
- const { data, error } = await getClient().rpc("create_public_booking", {
89
- p_tenant_id: tenantId,
90
- p_service_id: input.serviceId,
91
- p_starts_at: input.startsAt,
92
- p_name: input.contact.name.trim(),
93
- p_phone: phone,
94
- p_email: input.contact.email?.trim() || null,
95
- p_notes: input.contact.notes?.trim() || null
96
- });
97
- if (error) throw new Error(`[plugin-agenda/public] createBooking: ${error.message}`);
98
- const row = Array.isArray(data) ? data[0] : data;
99
- if (!row) throw new Error("[plugin-agenda/public] createBooking: empty RPC response");
100
- return { bookingId: row.booking_id, startsAt: row.starts_at, endsAt: row.ends_at };
101
- }
102
- };
103
- }
104
52
  var PublicBookingContext = react.createContext(null);
105
53
  function BookingProvider({ base, staticServices, children }) {
106
54
  const [fetched, setFetched] = react.useState(null);
@@ -173,7 +121,7 @@ function useAvailableSlots(params) {
173
121
  return { slots, loading, error };
174
122
  }
175
123
  function useCreateBooking() {
176
- const { provider } = useBooking();
124
+ const { provider, professionalId } = useBooking();
177
125
  const [submitting, setSubmitting] = react.useState(false);
178
126
  const [error, setError] = react.useState(null);
179
127
  const [done, setDone] = react.useState(false);
@@ -181,7 +129,10 @@ function useCreateBooking() {
181
129
  setSubmitting(true);
182
130
  setError(null);
183
131
  try {
184
- const result = await provider.createBooking(input);
132
+ const result = await provider.createBooking({
133
+ ...input,
134
+ assigneeId: input.assigneeId ?? professionalId ?? null
135
+ });
185
136
  setDone(true);
186
137
  return result;
187
138
  } catch (err) {
@@ -397,6 +348,7 @@ function ContactStep({
397
348
  contact,
398
349
  onContactChange,
399
350
  contactStep,
351
+ phoneVerification,
400
352
  country,
401
353
  onCountryChange,
402
354
  code,
@@ -451,7 +403,7 @@ function ContactStep({
451
403
  }
452
404
  )
453
405
  ] }),
454
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: labels.phoneHint })
406
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: phoneVerification === "none" ? labels.phoneHintNoVerification : labels.phoneHint })
455
407
  ] }),
456
408
  /* @__PURE__ */ jsxRuntime.jsx(
457
409
  "button",
@@ -459,7 +411,7 @@ function ContactStep({
459
411
  type: "submit",
460
412
  disabled: core.unmaskPhone(contact.phone).length < 8,
461
413
  className: "mt-5 w-full rounded-xl bg-primary py-3 font-semibold text-primary-foreground transition-opacity hover:opacity-90 disabled:opacity-40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
462
- children: labels.sendCodeCta
414
+ children: phoneVerification === "none" ? labels.phoneContinueCta : labels.sendCodeCta
463
415
  }
464
416
  )
465
417
  ] }) : null,
@@ -472,7 +424,7 @@ function ContactStep({
472
424
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2 text-sm text-foreground", children: [
473
425
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShieldCheck, { className: "h-4 w-4 text-primary" }),
474
426
  " ",
475
- labels.phoneVerified,
427
+ phoneVerification === "none" ? labels.phoneLabel : labels.phoneVerified,
476
428
  " \xB7 ",
477
429
  country.flag,
478
430
  " ",
@@ -809,6 +761,7 @@ function BookingWidget() {
809
761
  businessHours,
810
762
  payment,
811
763
  paymentProvider,
764
+ phoneVerification,
812
765
  onIdentityVerified,
813
766
  labels,
814
767
  brand,
@@ -905,6 +858,11 @@ function BookingWidget() {
905
858
  }
906
859
  function sendCode() {
907
860
  if (core.unmaskPhone(contact.phone).length < 8) return;
861
+ if (phoneVerification === "none") {
862
+ emitIdentity();
863
+ setContactStep("details");
864
+ return;
865
+ }
908
866
  setCode("");
909
867
  setCodeError(false);
910
868
  setContactStep("code");
@@ -1042,6 +1000,7 @@ function BookingWidget() {
1042
1000
  setCode(v);
1043
1001
  setCodeError(false);
1044
1002
  },
1003
+ phoneVerification,
1045
1004
  codeError,
1046
1005
  onSendCode: sendCode,
1047
1006
  onConfirmCode: confirmCode,
@@ -1248,6 +1207,8 @@ var DEFAULT_LABELS = {
1248
1207
  phoneLabel: "Celular",
1249
1208
  phoneHint: "Enviaremos um c\xF3digo para confirmar que o n\xFAmero de telefone \xE9 seu. Usaremos este n\xFAmero para associar as suas informa\xE7\xF5es \xE0 sua conta.",
1250
1209
  sendCodeCta: "Enviar c\xF3digo via WhatsApp",
1210
+ phoneHintNoVerification: "Usaremos este n\xFAmero para confirmar seu agendamento pelo WhatsApp.",
1211
+ phoneContinueCta: "Continuar",
1251
1212
  codeTitle: "Insira o c\xF3digo",
1252
1213
  codeBody: "Enviamos um c\xF3digo via WhatsApp para voc\xEA confirmar seu n\xFAmero.",
1253
1214
  codeInvalid: "C\xF3digo inv\xE1lido. Para testar, use 0000.",
@@ -1264,7 +1225,9 @@ var DEFAULT_LABELS = {
1264
1225
  notesPlaceholder: "Use esse espa\xE7o para deixar uma observa\xE7\xE3o sobre este agendamento",
1265
1226
  saveAndContinueCta: "Salvar e continuar",
1266
1227
  submitError: "N\xE3o foi poss\xEDvel concluir o agendamento. Tente novamente.",
1267
- noChargeNote: "Pagamento via Pix \xB7 Sem cobran\xE7a agora",
1228
+ // Rendered ONLY when the payment step is off — so it must not promise a
1229
+ // payment method the flow never shows.
1230
+ noChargeNote: "Sem cobran\xE7a agora \xB7 o pagamento \xE9 feito no atendimento",
1268
1231
  // right rail
1269
1232
  railTitle: "Passos para agendar",
1270
1233
  railWaitingPayment: "Aguardando pagamento",
@@ -1321,6 +1284,7 @@ function createPublicBookingPlugin(options) {
1321
1284
  const locale = options.locale ?? "pt-BR";
1322
1285
  const hours = options.workingHours ?? DEFAULT_HOURS;
1323
1286
  const staticServices = options.services ?? null;
1287
+ const phoneVerification = options.phoneVerification ?? "none";
1324
1288
  const payment = options.payment?.enabled ? {
1325
1289
  reservationFeePercent: options.payment.reservationFeePercent ?? 100,
1326
1290
  method: options.payment.method ?? "pix"
@@ -1342,7 +1306,7 @@ function createPublicBookingPlugin(options) {
1342
1306
  if (options.dataProvider) {
1343
1307
  provider = options.dataProvider;
1344
1308
  } else if (options.tenantId) {
1345
- provider = createSupabasePublicBookingProvider({ tenantId: options.tenantId });
1309
+ provider = chunkRX2HMWXS_cjs.createSupabasePublicBookingProvider({ tenantId: options.tenantId });
1346
1310
  } else {
1347
1311
  if (typeof console !== "undefined") {
1348
1312
  console.warn(
@@ -1360,6 +1324,7 @@ function createPublicBookingPlugin(options) {
1360
1324
  professionalId,
1361
1325
  professionalName,
1362
1326
  businessHours: hours,
1327
+ phoneVerification,
1363
1328
  payment,
1364
1329
  paymentProvider: options.paymentProvider ?? null,
1365
1330
  onIdentityVerified: options.onIdentityVerified ?? null,
@@ -1399,6 +1364,10 @@ function createPublicBookingPlugin(options) {
1399
1364
  return { manifest, Provider, dataProvider: provider };
1400
1365
  }
1401
1366
 
1367
+ Object.defineProperty(exports, "createSupabasePublicBookingProvider", {
1368
+ enumerable: true,
1369
+ get: function () { return chunkRX2HMWXS_cjs.createSupabasePublicBookingProvider; }
1370
+ });
1402
1371
  exports.BookingProvider = BookingProvider;
1403
1372
  exports.BookingWidget = BookingWidget;
1404
1373
  exports.DAY_NAMES = DAY_NAMES;
@@ -1411,7 +1380,6 @@ exports.DefaultSuccessPanel = DefaultSuccessPanel;
1411
1380
  exports.WEEK_ORDER = WEEK_ORDER;
1412
1381
  exports.createMockPublicBookingProvider = createMockPublicBookingProvider;
1413
1382
  exports.createPublicBookingPlugin = createPublicBookingPlugin;
1414
- exports.createSupabasePublicBookingProvider = createSupabasePublicBookingProvider;
1415
1383
  exports.formatSlotRange = formatSlotRange;
1416
1384
  exports.useAvailableSlots = useAvailableSlots;
1417
1385
  exports.useBooking = useBooking;