@fayz-ai/plugin-agenda 0.9.0 → 0.10.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.
Files changed (196) hide show
  1. package/README.md +3 -3
  2. package/dist/bridges/create-financial-bridge.d.ts +1 -1
  3. package/dist/bridges/create-financial-bridge.d.ts.map +1 -1
  4. package/dist/bridges/financial-bridge.d.ts.map +1 -0
  5. package/dist/{chunk-Q2PAWBPR.js → chunk-ISLJXP7O.js} +7 -2
  6. package/dist/chunk-ISLJXP7O.js.map +1 -0
  7. package/dist/components/AppointmentModal.d.ts.map +1 -1
  8. package/dist/components/PaymentStatusBadge.d.ts +1 -1
  9. package/dist/components/PaymentStatusBadge.d.ts.map +1 -1
  10. package/dist/config.d.ts +2 -2
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/{AgendaContext.d.ts → context.d.ts} +1 -1
  13. package/dist/context.d.ts.map +1 -0
  14. package/dist/data/mock.d.ts.map +1 -1
  15. package/dist/data/realtime.test.d.ts +2 -0
  16. package/dist/data/realtime.test.d.ts.map +1 -0
  17. package/dist/data/registries.d.ts.map +1 -0
  18. package/dist/data/supabase.d.ts.map +1 -1
  19. package/dist/data/types.d.ts +7 -0
  20. package/dist/data/types.d.ts.map +1 -1
  21. package/dist/index.d.ts +2 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +2515 -187
  24. package/dist/index.js.map +1 -1
  25. package/dist/integrations/google-calendar/conflict.d.ts +25 -0
  26. package/dist/integrations/google-calendar/conflict.d.ts.map +1 -0
  27. package/dist/integrations/google-calendar/connectorDef.d.ts +12 -0
  28. package/dist/integrations/google-calendar/connectorDef.d.ts.map +1 -1
  29. package/dist/integrations/google-calendar/credentials.d.ts +27 -0
  30. package/dist/integrations/google-calendar/credentials.d.ts.map +1 -0
  31. package/dist/integrations/google-calendar/data/supabase.d.ts +10 -2
  32. package/dist/integrations/google-calendar/data/supabase.d.ts.map +1 -1
  33. package/dist/integrations/google-calendar/data/tables.d.ts +2 -0
  34. package/dist/integrations/google-calendar/data/tables.d.ts.map +1 -1
  35. package/dist/integrations/google-calendar/health.d.ts +23 -0
  36. package/dist/integrations/google-calendar/health.d.ts.map +1 -0
  37. package/dist/integrations/google-calendar/health.test.d.ts +2 -0
  38. package/dist/integrations/google-calendar/health.test.d.ts.map +1 -0
  39. package/dist/integrations/google-calendar/index.d.ts +6 -0
  40. package/dist/integrations/google-calendar/index.d.ts.map +1 -1
  41. package/dist/integrations/google-calendar/migrations/index.d.ts +12 -0
  42. package/dist/integrations/google-calendar/migrations/index.d.ts.map +1 -0
  43. package/dist/integrations/google-calendar/panel-data.d.ts +26 -0
  44. package/dist/integrations/google-calendar/panel-data.d.ts.map +1 -0
  45. package/dist/integrations/google-calendar/panel-data.test.d.ts +2 -0
  46. package/dist/integrations/google-calendar/panel-data.test.d.ts.map +1 -0
  47. package/dist/integrations/google-calendar/types.d.ts +17 -0
  48. package/dist/integrations/google-calendar/types.d.ts.map +1 -1
  49. package/dist/lib/booking-events.d.ts +5 -0
  50. package/dist/lib/booking-events.d.ts.map +1 -0
  51. package/dist/lib/calendar-events.d.ts +8 -0
  52. package/dist/lib/calendar-events.d.ts.map +1 -0
  53. package/dist/lib/calendar-events.test.d.ts +2 -0
  54. package/dist/lib/calendar-events.test.d.ts.map +1 -0
  55. package/dist/lib/message-events.d.ts +12 -0
  56. package/dist/lib/message-events.d.ts.map +1 -0
  57. package/dist/locales/en.d.ts.map +1 -1
  58. package/dist/locales/pt-BR.d.ts.map +1 -1
  59. package/dist/public/{data.d.ts → data/index.d.ts} +4 -4
  60. package/dist/public/data/index.d.ts.map +1 -0
  61. package/dist/public/{data.supabase.d.ts → data/supabase.d.ts} +2 -2
  62. package/dist/public/data/supabase.d.ts.map +1 -0
  63. package/dist/public/{hooks.d.ts → hooks/index.d.ts} +4 -4
  64. package/dist/public/hooks/index.d.ts.map +1 -0
  65. package/dist/public/index.d.ts +4 -4
  66. package/dist/public/index.d.ts.map +1 -1
  67. package/dist/public/index.js +3 -3
  68. package/dist/public/index.js.map +1 -1
  69. package/dist/public/{format.d.ts → lib/format.d.ts} +1 -1
  70. package/dist/public/lib/format.d.ts.map +1 -0
  71. package/dist/public/views/BookingWidget.d.ts.map +1 -0
  72. package/dist/public/{steps → views/steps}/ContactStep.d.ts +1 -1
  73. package/dist/public/views/steps/ContactStep.d.ts.map +1 -0
  74. package/dist/public/{steps → views/steps}/DateTimeStep.d.ts +3 -3
  75. package/dist/public/views/steps/DateTimeStep.d.ts.map +1 -0
  76. package/dist/public/{steps → views/steps}/OverviewStep.d.ts +1 -1
  77. package/dist/public/views/steps/OverviewStep.d.ts.map +1 -0
  78. package/dist/public/{steps → views/steps}/PaymentStep.d.ts +1 -1
  79. package/dist/public/views/steps/PaymentStep.d.ts.map +1 -0
  80. package/dist/store.d.ts +1 -1
  81. package/dist/store.d.ts.map +1 -1
  82. package/dist/styles/calendar-styles.d.ts.map +1 -0
  83. package/dist/types.d.ts +1 -1
  84. package/dist/types.d.ts.map +1 -1
  85. package/dist/{AgendaPage.d.ts → views/AgendaPage.d.ts} +3 -3
  86. package/dist/views/AgendaPage.d.ts.map +1 -0
  87. package/dist/views/CalendarView.d.ts.map +1 -1
  88. package/package.json +9 -11
  89. package/dist/AgendaContext.d.ts.map +0 -1
  90. package/dist/AgendaPage.d.ts.map +0 -1
  91. package/dist/calendar-styles.d.ts.map +0 -1
  92. package/dist/chunk-Q2PAWBPR.js.map +0 -1
  93. package/dist/financial-bridge.d.ts.map +0 -1
  94. package/dist/integrations/google-calendar/GoogleCalendarSettings.d.ts +0 -3
  95. package/dist/integrations/google-calendar/GoogleCalendarSettings.d.ts.map +0 -1
  96. package/dist/public/BookingWidget.d.ts.map +0 -1
  97. package/dist/public/data.d.ts.map +0 -1
  98. package/dist/public/data.supabase.d.ts.map +0 -1
  99. package/dist/public/format.d.ts.map +0 -1
  100. package/dist/public/hooks.d.ts.map +0 -1
  101. package/dist/public/steps/ContactStep.d.ts.map +0 -1
  102. package/dist/public/steps/DateTimeStep.d.ts.map +0 -1
  103. package/dist/public/steps/OverviewStep.d.ts.map +0 -1
  104. package/dist/public/steps/PaymentStep.d.ts.map +0 -1
  105. package/dist/registries.d.ts.map +0 -1
  106. package/src/AgendaContext.tsx +0 -11
  107. package/src/AgendaPage.tsx +0 -33
  108. package/src/bridges/create-financial-bridge.ts +0 -296
  109. package/src/calendar-styles.css +0 -245
  110. package/src/calendar-styles.ts +0 -285
  111. package/src/components/AgendaGeneralSettings.tsx +0 -86
  112. package/src/components/AgendaMobileList.tsx +0 -103
  113. package/src/components/AppointmentModal.tsx +0 -1050
  114. package/src/components/AppointmentPopover.tsx +0 -231
  115. package/src/components/BookingPaymentPanel.tsx +0 -394
  116. package/src/components/CalendarSidebar.tsx +0 -119
  117. package/src/components/CalendarToolbar.tsx +0 -86
  118. package/src/components/EventContextMenu.tsx +0 -125
  119. package/src/components/FloatingPanel.tsx +0 -123
  120. package/src/components/MiniCalendar.tsx +0 -120
  121. package/src/components/PaymentStatusBadge.tsx +0 -62
  122. package/src/components/StatusBadge.tsx +0 -23
  123. package/src/config.ts +0 -368
  124. package/src/data/index.ts +0 -4
  125. package/src/data/mock.ts +0 -344
  126. package/src/data/supabase.ts +0 -636
  127. package/src/data/types.ts +0 -37
  128. package/src/financial-bridge.ts +0 -96
  129. package/src/hooks/useAgendaSettings.ts +0 -17
  130. package/src/index.ts +0 -297
  131. package/src/integrations/google-calendar/GoogleCalendarSettings.tsx +0 -136
  132. package/src/integrations/google-calendar/components/CalendarColorDot.tsx +0 -23
  133. package/src/integrations/google-calendar/components/ChannelMappingList.tsx +0 -329
  134. package/src/integrations/google-calendar/components/ImportEventsWizard.tsx +0 -215
  135. package/src/integrations/google-calendar/components/useAgendaLookups.ts +0 -100
  136. package/src/integrations/google-calendar/connector.ts +0 -20
  137. package/src/integrations/google-calendar/connectorDef.tsx +0 -185
  138. package/src/integrations/google-calendar/data/supabase.ts +0 -170
  139. package/src/integrations/google-calendar/data/tables.ts +0 -12
  140. package/src/integrations/google-calendar/index.ts +0 -45
  141. package/src/integrations/google-calendar/integration.test.ts +0 -199
  142. package/src/integrations/google-calendar/mapping.ts +0 -183
  143. package/src/integrations/google-calendar/migrations/001_google_calendar.sql +0 -97
  144. package/src/integrations/google-calendar/migrations/002_smart_sync.sql +0 -517
  145. package/src/integrations/google-calendar/migrations/003_plg_rename.sql +0 -273
  146. package/src/integrations/google-calendar/types.ts +0 -142
  147. package/src/lib/tenant.ts +0 -3
  148. package/src/locales/en.ts +0 -220
  149. package/src/locales/index.ts +0 -7
  150. package/src/locales/pt-BR.ts +0 -220
  151. package/src/migrations/000b_v_bookings_rename.sql +0 -21
  152. package/src/migrations/000c_dedupe_customer_phones.sql +0 -43
  153. package/src/migrations/001_public_booking.sql +0 -296
  154. package/src/migrations/002_v_bookings_compat.sql +0 -14
  155. package/src/migrations/003_public_client_kind.sql +0 -175
  156. package/src/migrations/004_public_booking_assignee.sql +0 -176
  157. package/src/migrations/005_agent_rpcs.sql +0 -168
  158. package/src/migrations/006_agent_rpc_localtime.sql +0 -181
  159. package/src/migrations/007_schedule_exception_precedence.sql +0 -290
  160. package/src/migrations/008_agent_rpc_exception_precedence.sql +0 -172
  161. package/src/migrations/009_public_booking_location.sql +0 -162
  162. package/src/migrations/010_public_service_curation.sql +0 -31
  163. package/src/migrations/011_default_assignee.sql +0 -167
  164. package/src/migrations/012_drop_legacy_booking_overload.sql +0 -29
  165. package/src/migrations/013_normalize_v_appointments.sql +0 -199
  166. package/src/migrations/014_agent_rpc_update_appointment.sql +0 -199
  167. package/src/migrations/index.ts +0 -2377
  168. package/src/public/BookingWidget.tsx +0 -324
  169. package/src/public/components/BrandHeader.tsx +0 -27
  170. package/src/public/components/ServiceCard.tsx +0 -39
  171. package/src/public/components/SidebarExtras.tsx +0 -30
  172. package/src/public/components/StepRailItem.tsx +0 -27
  173. package/src/public/components/SuccessPanel.tsx +0 -27
  174. package/src/public/components/SummaryRail.tsx +0 -90
  175. package/src/public/components/defaults.ts +0 -14
  176. package/src/public/context.tsx +0 -103
  177. package/src/public/createPublicBookingPlugin.ts +0 -281
  178. package/src/public/data.supabase.ts +0 -97
  179. package/src/public/data.ts +0 -105
  180. package/src/public/format.ts +0 -96
  181. package/src/public/hooks.ts +0 -110
  182. package/src/public/index.ts +0 -69
  183. package/src/public/steps/ContactStep.tsx +0 -184
  184. package/src/public/steps/DateTimeStep.tsx +0 -138
  185. package/src/public/steps/OverviewStep.tsx +0 -81
  186. package/src/public/steps/PaymentStep.tsx +0 -180
  187. package/src/public/types.ts +0 -250
  188. package/src/registries.ts +0 -35
  189. package/src/store.ts +0 -311
  190. package/src/types.ts +0 -273
  191. package/src/views/CalendarView.tsx +0 -1112
  192. package/src/views/ConfirmationsView.tsx +0 -155
  193. /package/dist/{financial-bridge.d.ts → bridges/financial-bridge.d.ts} +0 -0
  194. /package/dist/{registries.d.ts → data/registries.d.ts} +0 -0
  195. /package/dist/public/{BookingWidget.d.ts → views/BookingWidget.d.ts} +0 -0
  196. /package/dist/{calendar-styles.d.ts → styles/calendar-styles.d.ts} +0 -0
@@ -1,285 +0,0 @@
1
- /**
2
- * Injects agenda calendar CSS at runtime.
3
- * This ensures styles work both in symlinked dev mode and when consumed
4
- * as a built package (where CSS side-effect imports are extracted by tsup
5
- * and not automatically loaded).
6
- */
7
-
8
- const STYLE_ID = 'saas-agenda-calendar-styles'
9
-
10
- const css = /* css */ `
11
- /* Dark mode content background — uses the content token */
12
- .dark .agenda-calendar,
13
- .dark .agenda-calendar .fc,
14
- .dark .agenda-calendar .fc-view-harness,
15
- .dark .agenda-calendar .fc-timegrid,
16
- .dark .agenda-calendar .fc-scrollgrid,
17
- .dark .agenda-calendar .fc-timegrid-col,
18
- .dark .agenda-calendar .fc-daygrid-body,
19
- .dark .agenda-calendar .fc-timegrid-slot-lane {
20
- background-color: hsl(var(--content));
21
- }
22
-
23
- /* FullCalendar — Google Calendar inspired theme */
24
-
25
- .agenda-calendar {
26
- --fc-border-color: hsl(var(--border));
27
- --fc-today-bg-color: transparent;
28
- --fc-now-indicator-color: hsl(var(--destructive));
29
- --fc-highlight-color: hsl(var(--primary) / 0.06);
30
- --fc-non-business-color: hsl(var(--muted) / 0.15);
31
- --fc-neutral-bg-color: transparent;
32
- --fc-page-bg-color: transparent;
33
- --fc-event-border-color: transparent;
34
- }
35
-
36
- .agenda-calendar .fc {
37
- font-family: inherit;
38
- background: transparent;
39
- }
40
-
41
- .agenda-calendar .fc .fc-view-harness {
42
- background: transparent;
43
- }
44
-
45
- /* ── Column headers ── */
46
- .agenda-calendar .fc-col-header-cell {
47
- background: transparent;
48
- border-bottom: 1px solid var(--fc-border-color);
49
- border-left: none;
50
- border-right: none;
51
- border-top: none;
52
- }
53
-
54
- .agenda-calendar .fc-col-header-cell-cushion {
55
- padding: 8px 4px;
56
- font-weight: 400;
57
- font-size: 0.7rem;
58
- color: hsl(var(--muted-foreground));
59
- text-decoration: none;
60
- text-transform: uppercase;
61
- letter-spacing: 0.03em;
62
- }
63
-
64
- /* Today's column header */
65
- .agenda-calendar .fc-day-today .fc-col-header-cell-cushion {
66
- color: hsl(var(--primary));
67
- font-weight: 600;
68
- }
69
-
70
- /* Resource header (professional columns) */
71
- .agenda-calendar .fc .fc-resource-header {
72
- background: transparent;
73
- border-bottom: 1px solid var(--fc-border-color);
74
- }
75
-
76
- /* ── Time slots — compact ── */
77
- .agenda-calendar .fc-timegrid-slot {
78
- height: 1.5rem;
79
- border-bottom: 1px solid hsl(var(--border) / 0.4);
80
- }
81
-
82
- .agenda-calendar .fc-timegrid-slot-label {
83
- vertical-align: top;
84
- border: none;
85
- }
86
-
87
- .agenda-calendar .fc-timegrid-slot-label-cushion {
88
- font-size: 0.65rem;
89
- color: hsl(var(--muted-foreground) / 0.7);
90
- padding: 1px 8px 0 0;
91
- }
92
-
93
- /* Half-hour lines lighter */
94
- .agenda-calendar .fc-timegrid-slot-minor {
95
- border-bottom-style: none;
96
- }
97
-
98
- /* Column dividers */
99
- .agenda-calendar .fc-timegrid-col {
100
- border-right: 1px solid hsl(var(--border) / 0.5);
101
- }
102
-
103
- /* ── Events ── */
104
- .agenda-calendar .fc-event {
105
- border-radius: 6px;
106
- border-width: 0;
107
- border-left: 4px solid;
108
- cursor: pointer;
109
- transition: opacity 0.15s, box-shadow 0.15s, backdrop-filter 0.15s;
110
- font-size: 0.7rem;
111
- line-height: 1.3;
112
- margin: 0 2px;
113
- overflow: hidden;
114
- backdrop-filter: blur(8px) saturate(140%);
115
- -webkit-backdrop-filter: blur(8px) saturate(140%);
116
- }
117
-
118
- .agenda-calendar .fc-event .fc-event-main {
119
- background: inherit;
120
- border-radius: inherit;
121
- overflow: hidden;
122
- }
123
-
124
- .agenda-calendar .fc-event:not(.fc-bg-event):hover {
125
- opacity: 0.92;
126
- box-shadow: 0 2px 8px rgba(0,0,0,0.12);
127
- backdrop-filter: blur(12px) saturate(160%);
128
- -webkit-backdrop-filter: blur(12px) saturate(160%);
129
- }
130
-
131
- .agenda-calendar .fc-bg-event {
132
- pointer-events: none;
133
- }
134
-
135
- /* ── Now indicator ── */
136
- .agenda-calendar .fc-timegrid-now-indicator-line {
137
- border-color: hsl(var(--destructive));
138
- border-width: 2px;
139
- }
140
-
141
- .agenda-calendar .fc-timegrid-now-indicator-arrow {
142
- border-top-color: hsl(var(--destructive));
143
- }
144
-
145
- /* ── Month view ── */
146
- .agenda-calendar .fc-daygrid-day-number {
147
- font-size: 0.8rem;
148
- padding: 4px 8px;
149
- text-decoration: none;
150
- color: hsl(var(--foreground));
151
- }
152
-
153
- .agenda-calendar .fc-daygrid-day.fc-day-today .fc-daygrid-day-number {
154
- background-color: hsl(var(--primary));
155
- color: hsl(var(--primary-foreground));
156
- border-radius: 50%;
157
- width: 1.5rem;
158
- height: 1.5rem;
159
- display: flex;
160
- align-items: center;
161
- justify-content: center;
162
- font-size: 0.75rem;
163
- }
164
-
165
- /* ── Selection ── */
166
- .agenda-calendar .fc-highlight {
167
- background: hsl(var(--primary) / 0.08);
168
- }
169
-
170
- /* ── Links ── */
171
- .agenda-calendar .fc a {
172
- text-decoration: none;
173
- color: inherit;
174
- }
175
-
176
- /* ── Scrollbar ── */
177
- .agenda-calendar .fc-scroller {
178
- scrollbar-width: thin;
179
- scrollbar-color: hsl(var(--muted-foreground) / 0.12) transparent;
180
- }
181
-
182
- .agenda-calendar .fc-scroller::-webkit-scrollbar {
183
- width: 6px;
184
- }
185
-
186
- .agenda-calendar .fc-scroller::-webkit-scrollbar-track {
187
- background: transparent;
188
- }
189
-
190
- .agenda-calendar .fc-scroller::-webkit-scrollbar-thumb {
191
- background: hsl(var(--muted-foreground) / 0.12);
192
- border-radius: 3px;
193
- }
194
-
195
- /* ── Clean up borders ── */
196
- .agenda-calendar .fc .fc-timegrid {
197
- border: none;
198
- }
199
-
200
- .agenda-calendar .fc-scrollgrid {
201
- border: none !important;
202
- }
203
-
204
- .agenda-calendar .fc-scrollgrid td:last-child {
205
- border-right: none;
206
- }
207
-
208
- /* ── Unavailable time background — opaque/disabled feel ── */
209
- .agenda-calendar .fc-unavailable-bg {
210
- background: hsl(var(--muted-foreground) / 0.08) !important;
211
- background-image: repeating-linear-gradient(
212
- 45deg,
213
- transparent,
214
- transparent 4px,
215
- hsl(var(--muted-foreground) / 0.04) 4px,
216
- hsl(var(--muted-foreground) / 0.04) 8px
217
- ) !important;
218
- border-radius: 0;
219
- border-left: none !important;
220
- }
221
-
222
- /* ── Location label on schedule blocks ── */
223
- .agenda-calendar .fc-location-label {
224
- background: transparent !important;
225
- border: none !important;
226
- border-left-width: 0 !important;
227
- cursor: default !important;
228
- pointer-events: none;
229
- box-shadow: none !important;
230
- z-index: 1 !important;
231
- margin: 0 4px !important;
232
- font-weight: 500 !important;
233
- }
234
-
235
- .agenda-calendar .fc-location-label .fc-event-main {
236
- padding: 0 !important;
237
- }
238
-
239
- /* Week view day header with date */
240
- .agenda-calendar .fc-timegrid .fc-col-header-cell {
241
- padding: 4px 0;
242
- }
243
-
244
- /* ── Alternating resource column backgrounds ── */
245
- .agenda-calendar .fc-resource-alt {
246
- background-color: hsl(var(--muted) / 0.4) !important;
247
- }
248
-
249
- .dark .agenda-calendar .fc-resource-alt {
250
- background-color: hsl(var(--muted-foreground) / 0.08) !important;
251
- }
252
-
253
- /* Resource group header separator — stronger border between professionals */
254
- .agenda-calendar .fc-resource-group {
255
- border-left: 2px solid hsl(var(--border));
256
- }
257
-
258
- /* Also stripe the resource header label for the alt group */
259
- .agenda-calendar th.fc-resource-alt {
260
- background-color: hsl(var(--muted) / 0.4) !important;
261
- }
262
-
263
- .dark .agenda-calendar th.fc-resource-alt {
264
- background-color: hsl(var(--muted-foreground) / 0.06) !important;
265
- }
266
- `
267
-
268
- let injected = false
269
-
270
- export function injectCalendarStyles(): void {
271
- if (injected) return
272
- if (typeof document === 'undefined') return
273
-
274
- // Check if already present (e.g. from CSS import in dev mode)
275
- if (document.getElementById(STYLE_ID)) {
276
- injected = true
277
- return
278
- }
279
-
280
- const style = document.createElement('style')
281
- style.id = STYLE_ID
282
- style.textContent = css
283
- document.head.appendChild(style)
284
- injected = true
285
- }
@@ -1,86 +0,0 @@
1
- import React from 'react'
2
- import { SettingsGroup, ToggleRow, SelectRow, useTenantPluginSettings } from '@fayz-ai/saas'
3
- import { useTranslation } from '@fayz-ai/core'
4
- import { useAgendaSettings } from '../hooks/useAgendaSettings'
5
-
6
- const HOUR_OPTIONS = Array.from({ length: 18 }, (_, i) => {
7
- const h = (5 + i).toString().padStart(2, '0')
8
- return { value: `${h}:00`, label: `${h}:00` }
9
- })
10
-
11
- // Per-tenant toggle defaults = the values that used to be hardcoded here.
12
- // NOTE: these are persisted + re-hydrated per tenant; actually consuming them to
13
- // change agenda behaviour is a follow-up (see useTenantPluginSettings docs).
14
- const AGENDA_TOGGLE_DEFAULTS = {
15
- conflictDetection: true,
16
- dragDrop: true,
17
- autoCreateOrder: true,
18
- enableLocation: false,
19
- enableWorkingHours: true,
20
- blockOutside: false,
21
- enableConfirmations: true,
22
- autoConfirm: false,
23
- reminder: true,
24
- showCancelled: false,
25
- showNoShow: true,
26
- compact: false,
27
- newBookingNotif: true,
28
- cancelAlerts: true,
29
- noShowTracking: false,
30
- }
31
-
32
- export function AgendaGeneralSettings() {
33
- const t = useTranslation()
34
- const { startTime, endTime, setStartTime, setEndTime } = useAgendaSettings()
35
- const s = useTenantPluginSettings('agenda', AGENDA_TOGGLE_DEFAULTS)
36
- return (
37
- <div className="space-y-4">
38
- <SettingsGroup title={t('agenda.settings.scheduling')} description={t('agenda.settings.schedulingDesc')}>
39
- <ToggleRow label={t('agenda.settings.conflictDetection')} description={t('agenda.settings.conflictDetectionDesc')} checked={s.get('conflictDetection')} onChange={(v) => s.set('conflictDetection', v)} />
40
- <ToggleRow label={t('agenda.settings.dragDrop')} description={t('agenda.settings.dragDropDesc')} checked={s.get('dragDrop')} onChange={(v) => s.set('dragDrop', v)} />
41
- <ToggleRow label={t('agenda.settings.autoCreateOrder')} description={t('agenda.settings.autoCreateOrderDesc')} checked={s.get('autoCreateOrder')} onChange={(v) => s.set('autoCreateOrder', v)} />
42
- </SettingsGroup>
43
-
44
- <SettingsGroup title={t('agenda.settings.locations')} description={t('agenda.settings.locationsDesc')}>
45
- <ToggleRow label={t('agenda.settings.enableLocation')} description={t('agenda.settings.enableLocationDesc')} checked={s.get('enableLocation')} onChange={(v) => s.set('enableLocation', v)} />
46
- </SettingsGroup>
47
-
48
- <SettingsGroup title={t('agenda.settings.workingHours')} description={t('agenda.settings.workingHoursDesc')}>
49
- <ToggleRow label={t('agenda.settings.enableWorkingHours')} description={t('agenda.settings.enableWorkingHoursDesc')} checked={s.get('enableWorkingHours')} onChange={(v) => s.set('enableWorkingHours', v)} />
50
- <ToggleRow label={t('agenda.settings.blockOutside')} description={t('agenda.settings.blockOutsideDesc')} checked={s.get('blockOutside')} onChange={(v) => s.set('blockOutside', v)} />
51
- </SettingsGroup>
52
-
53
- <SettingsGroup title={t('agenda.settings.confirmations')} description={t('agenda.settings.confirmationsDesc')}>
54
- <ToggleRow label={t('agenda.settings.enableConfirmations')} description={t('agenda.settings.enableConfirmationsDesc')} checked={s.get('enableConfirmations')} onChange={(v) => s.set('enableConfirmations', v)} />
55
- <ToggleRow label={t('agenda.settings.autoConfirm')} description={t('agenda.settings.autoConfirmDesc')} checked={s.get('autoConfirm')} onChange={(v) => s.set('autoConfirm', v)} />
56
- <ToggleRow label={t('agenda.settings.reminder')} description={t('agenda.settings.reminderDesc')} checked={s.get('reminder')} onChange={(v) => s.set('reminder', v)} />
57
- </SettingsGroup>
58
-
59
- <SettingsGroup title={t('agenda.settings.calendarDisplay')} description={t('agenda.settings.calendarDisplayDesc')}>
60
- <SelectRow
61
- label={t('agenda.settings.dayStartTime')}
62
- description={t('agenda.settings.dayStartTimeDesc')}
63
- value={startTime}
64
- options={HOUR_OPTIONS}
65
- onChange={setStartTime}
66
- />
67
- <SelectRow
68
- label={t('agenda.settings.dayEndTime')}
69
- description={t('agenda.settings.dayEndTimeDesc')}
70
- value={endTime}
71
- options={HOUR_OPTIONS}
72
- onChange={setEndTime}
73
- />
74
- <ToggleRow label={t('agenda.settings.showCancelled')} description={t('agenda.settings.showCancelledDesc')} checked={s.get('showCancelled')} onChange={(v) => s.set('showCancelled', v)} />
75
- <ToggleRow label={t('agenda.settings.showNoShow')} description={t('agenda.settings.showNoShowDesc')} checked={s.get('showNoShow')} onChange={(v) => s.set('showNoShow', v)} />
76
- <ToggleRow label={t('agenda.settings.compact')} description={t('agenda.settings.compactDesc')} checked={s.get('compact')} onChange={(v) => s.set('compact', v)} />
77
- </SettingsGroup>
78
-
79
- <SettingsGroup title={t('agenda.settings.notifications')} description={t('agenda.settings.notificationsDesc')}>
80
- <ToggleRow label={t('agenda.settings.newBookingNotif')} description={t('agenda.settings.newBookingNotifDesc')} checked={s.get('newBookingNotif')} onChange={(v) => s.set('newBookingNotif', v)} />
81
- <ToggleRow label={t('agenda.settings.cancelAlerts')} description={t('agenda.settings.cancelAlertsDesc')} checked={s.get('cancelAlerts')} onChange={(v) => s.set('cancelAlerts', v)} />
82
- <ToggleRow label={t('agenda.settings.noShowTracking')} description={t('agenda.settings.noShowTrackingDesc')} checked={s.get('noShowTracking')} onChange={(v) => s.set('noShowTracking', v)} />
83
- </SettingsGroup>
84
- </div>
85
- )
86
- }
@@ -1,103 +0,0 @@
1
- import React, { useMemo } from 'react'
2
- import { formatCurrency, useTranslation, getCurrentLocale } from '@fayz-ai/core'
3
- import type { CalendarBooking } from '../types'
4
-
5
- // ---------------------------------------------------------------------------
6
- // Mobile agenda list — a thumb-friendly, date-grouped list of upcoming items.
7
- // Rendered on <md viewports instead of the FullCalendar grid. Each row shows a
8
- // category/status dot, the title, the time, and (for finance-style events) the
9
- // amount. Fed straight from the store bookings so it works for any seeded app.
10
- // ---------------------------------------------------------------------------
11
-
12
- function startOfDay(d: Date): Date {
13
- const x = new Date(d)
14
- x.setHours(0, 0, 0, 0)
15
- return x
16
- }
17
-
18
- function timeLabel(iso: string): string {
19
- const d = new Date(iso)
20
- return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`
21
- }
22
-
23
- export interface AgendaMobileListProps {
24
- bookings: CalendarBooking[]
25
- statusColors: Record<string, string>
26
- currencyCode: string
27
- onSelect: (booking: CalendarBooking) => void
28
- }
29
-
30
- export function AgendaMobileList({ bookings, statusColors, currencyCode, onSelect }: AgendaMobileListProps) {
31
- const t = useTranslation()
32
- const locale = getCurrentLocale() === 'pt-BR' ? 'pt-BR' : 'en'
33
-
34
- const groups = useMemo(() => {
35
- const todayStart = startOfDay(new Date()).getTime()
36
- const sorted = bookings
37
- .filter((b) => !!b.startsAt)
38
- .slice()
39
- .sort((a, b) => (a.startsAt < b.startsAt ? -1 : a.startsAt > b.startsAt ? 1 : 0))
40
- const map = new Map<string, CalendarBooking[]>()
41
- for (const b of sorted) {
42
- const day = startOfDay(new Date(b.startsAt))
43
- if (day.getTime() < todayStart) continue // upcoming only
44
- const key = day.toISOString().slice(0, 10)
45
- const list = map.get(key) ?? []
46
- list.push(b)
47
- map.set(key, list)
48
- }
49
- return Array.from(map.entries()).map(([key, items]) => ({ key, date: new Date(key + 'T00:00:00'), items }))
50
- }, [bookings])
51
-
52
- function dayLabel(date: Date): string {
53
- const today = startOfDay(new Date())
54
- const diff = Math.round((startOfDay(date).getTime() - today.getTime()) / 86400000)
55
- if (diff === 0) return t('agenda.list.today')
56
- if (diff === 1) return t('agenda.list.tomorrow')
57
- return date.toLocaleDateString(locale, { weekday: 'long', day: 'numeric', month: 'long' })
58
- }
59
-
60
- if (groups.length === 0) {
61
- return (
62
- <div className="flex-1 flex flex-col items-center justify-center px-6 py-16 text-center text-muted-foreground">
63
- <p className="text-sm">{t('agenda.list.empty')}</p>
64
- </div>
65
- )
66
- }
67
-
68
- return (
69
- <div className="flex-1 overflow-y-auto px-3 py-3 space-y-5">
70
- {groups.map((g) => (
71
- <div key={g.key}>
72
- <h3 className="px-1 pb-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground">
73
- {dayLabel(g.date)}
74
- </h3>
75
- <div className="space-y-1.5">
76
- {g.items.map((b) => {
77
- const color = statusColors[b.status] ?? '#6b7280'
78
- const hasAmount = typeof b.orderTotal === 'number' && b.orderTotal > 0
79
- return (
80
- <button
81
- key={b.id}
82
- onClick={() => onSelect(b)}
83
- className="flex w-full items-center gap-3 rounded-lg border bg-card px-3 py-2.5 text-left shadow-sm transition-colors active:bg-muted/50"
84
- >
85
- <span className="h-2.5 w-2.5 shrink-0 rounded-full" style={{ backgroundColor: color }} />
86
- <div className="min-w-0 flex-1">
87
- <p className="truncate text-sm font-medium text-foreground">{b.clientName ?? '—'}</p>
88
- <p className="text-xs text-muted-foreground">{timeLabel(b.startsAt)}</p>
89
- </div>
90
- {hasAmount && (
91
- <span className="shrink-0 text-sm font-semibold tabular-nums text-foreground">
92
- {formatCurrency(b.orderTotal, currencyCode)}
93
- </span>
94
- )}
95
- </button>
96
- )
97
- })}
98
- </div>
99
- </div>
100
- ))}
101
- </div>
102
- )
103
- }