@oneclick.dev/cms-core-modules 0.0.122 → 0.0.123
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/{ContentEditor-CoJjsV-m.js → ContentEditor-C-Wm48ai.js} +63 -59
- package/dist/{ContentEditor-DIwqplfB.mjs → ContentEditor-MDGolnIP.mjs} +27596 -26138
- package/dist/{NewReservationDialog.vue_vue_type_script_setup_true_lang-bZidw6RT.mjs → NewReservationDialog.vue_vue_type_script_setup_true_lang-8I_Z9cD_.mjs} +530 -530
- package/dist/NewReservationDialog.vue_vue_type_script_setup_true_lang-BVE_uURZ.js +1 -0
- package/dist/OrderDetailDialog.vue_vue_type_script_setup_true_lang-BdFa-xNf.mjs +3566 -0
- package/dist/OrderDetailDialog.vue_vue_type_script_setup_true_lang-DzPOadcU.js +925 -0
- package/dist/TableCalculationWidget-CkQPrVUd.js +59 -0
- package/dist/TableCalculationWidget-CrqcLGfU.mjs +254 -0
- package/dist/TableDataWidget-7qvC3Egd.js +1 -0
- package/dist/TableDataWidget-DMTSoGRO.mjs +121 -0
- package/dist/TableOverviewCard-AFq-puJs.js +1 -0
- package/dist/TableOverviewCard-Ci0d4o4w.mjs +391 -0
- package/dist/TableResultView.vue_vue_type_script_setup_true_lang-CBn-Oxl9.mjs +534 -0
- package/dist/TableResultView.vue_vue_type_script_setup_true_lang-C_Lv-SmJ.js +1 -0
- package/dist/TableRowActionCard-BhdnnPaq.mjs +266 -0
- package/dist/TableRowActionCard-IzB6tNN-.js +1 -0
- package/dist/TableView-BkwoKREo.js +4 -0
- package/dist/TableView-C4Zyp8d7.mjs +8228 -0
- package/dist/{agenda-BCKDYOeF.mjs → agenda-DWdbWUbb.mjs} +10 -9
- package/dist/agenda-r9Gl85GL.js +1 -0
- package/dist/dateRangePresets-B-l5b_wR.mjs +48 -0
- package/dist/dateRangePresets-CPWqst_x.js +1 -0
- package/dist/fuse-Deb-Iq39.mjs +1473 -0
- package/dist/fuse-_CGUd5Zq.js +1 -0
- package/dist/{index-DU3Ib10Z.mjs → index-B_qaX29C.mjs} +7 -6
- package/dist/{index-Bk3yLv_G.js → index-yHLT6gaZ.js} +3 -3
- package/dist/index.cjs.js +1 -1
- package/dist/index.mjs +419 -109
- package/dist/{orders-CElKNc1v.mjs → orders-BfTLIm7U.mjs} +10 -9
- package/dist/orders-DUa2PVoa.js +1 -0
- package/dist/reports-ChCsd1Gk.mjs +1107 -0
- package/dist/reports-DmJPm8uP.js +158 -0
- package/dist/row-item-C1dUyimV.mjs +204 -0
- package/dist/row-item-Cyo3m3MZ.js +1 -0
- package/dist/src/appointments/components/edit/EventDialog/BookingsList.vue.d.ts +9 -3
- package/dist/src/appointments/components/edit/EventDialog/OrderDetailDialog.vue.d.ts +2 -0
- package/dist/src/appointments/components/edit/EventDialog/ReservationDetailDialog.vue.d.ts +4 -2
- package/dist/src/appointments/components/edit/dashboard/BookingsList.vue.d.ts +9 -3
- package/dist/src/appointments/pages/edit/orders.vue.d.ts +9 -3
- package/dist/src/appointments/pages/edit/reports.vue.d.ts +229 -1
- package/dist/src/table/chat-components/TableCalculationWidget.vue.d.ts +15 -0
- package/dist/src/table/chat-components/TableDataWidget.vue.d.ts +15 -0
- package/dist/src/table/chat-components/TableOverviewCard.vue.d.ts +61 -0
- package/dist/src/table/chat-components/TableResultView.vue.d.ts +48 -0
- package/dist/src/table/chat-components/TableRowActionCard.vue.d.ts +15 -0
- package/dist/src/table/components/filters/DialogTableFilterOptionItem.vue.d.ts +16 -0
- package/dist/src/table/components/filters/NumberComparisonFilter.vue.d.ts +12 -0
- package/dist/src/table/components/filters/NumberComparisonFilterSettings.vue.d.ts +12 -0
- package/dist/src/table/components/filters/NumberRangeFilter.vue.d.ts +12 -0
- package/dist/src/table/components/filters/NumberRangeFilterSettings.vue.d.ts +12 -0
- package/dist/src/table/components/filters/filter-utils.d.ts +14 -0
- package/dist/src/table/composables/useTableAgentTools.d.ts +33 -0
- package/dist/src/table/index.d.ts +339 -0
- package/dist/src/table/tool-sandbox.d.ts +13 -0
- package/dist/src/table/tool-utils.d.ts +11 -0
- package/dist/src/table/tools.d.ts +333 -1
- package/dist/src/table/types.d.ts +79 -0
- package/dist/tool-sandbox-DdkMLkDK.mjs +182 -0
- package/dist/tool-sandbox-DoF1PsyS.js +115 -0
- package/dist/useTableAgentTools-D5mzGf3A.js +1 -0
- package/dist/useTableAgentTools-DcN3kYRL.mjs +131 -0
- package/package.json +17 -17
- package/src/table/tools.ts +304 -1
- package/dist/NewReservationDialog.vue_vue_type_script_setup_true_lang-BdZbcubW.js +0 -1
- package/dist/OrderDetailDialog.vue_vue_type_script_setup_true_lang-BYSeUW_V.js +0 -925
- package/dist/OrderDetailDialog.vue_vue_type_script_setup_true_lang-DwAUYR8p.mjs +0 -5021
- package/dist/TableView-Ctnep-Qu.mjs +0 -6247
- package/dist/TableView-DJqyJL9L.js +0 -4
- package/dist/agenda-B54F8cEr.js +0 -1
- package/dist/orders-BMosTk6r.js +0 -1
- package/dist/reports-BQT_GZzU.js +0 -158
- package/dist/reports-DksZCTOw.mjs +0 -837
package/src/table/tools.ts
CHANGED
|
@@ -1 +1,304 @@
|
|
|
1
|
-
export const tools = [
|
|
1
|
+
export const tools = [
|
|
2
|
+
{
|
|
3
|
+
name: 'inspectTable',
|
|
4
|
+
description: 'Inspect this table before querying it. Returns the available columns and their data types, configured date-range capability, row actions, saved statistics, and a small sample of rows. Use this first whenever you do not yet know the exact property names or action IDs.',
|
|
5
|
+
executionMode: 'component',
|
|
6
|
+
chatComponent: 'TableOverviewCard',
|
|
7
|
+
parameters: {
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: {
|
|
10
|
+
sampleLimit: {
|
|
11
|
+
type: 'number',
|
|
12
|
+
description: 'How many example rows to inspect. Use a small sample only. Default: 3, minimum: 1, maximum: 10.',
|
|
13
|
+
default: 3,
|
|
14
|
+
minimum: 1,
|
|
15
|
+
maximum: 10,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
required: [],
|
|
19
|
+
additionalProperties: false,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'queryTableData',
|
|
24
|
+
description: 'Fetch, filter, sort, and display rows from this table. Use inspectTable first if column property names are unknown. Date ranges are inclusive. The result is shown directly in chat as a table, or as a card when exactly one row is returned.',
|
|
25
|
+
executionMode: 'component',
|
|
26
|
+
chatComponent: 'TableDataWidget',
|
|
27
|
+
parameters: {
|
|
28
|
+
type: 'object',
|
|
29
|
+
properties: {
|
|
30
|
+
startDate: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
format: 'date',
|
|
33
|
+
description: 'Inclusive start date in YYYY-MM-DD format. Omit when no date range is requested.',
|
|
34
|
+
},
|
|
35
|
+
endDate: {
|
|
36
|
+
type: 'string',
|
|
37
|
+
format: 'date',
|
|
38
|
+
description: 'Inclusive end date in YYYY-MM-DD format. Omit when no date range is requested.',
|
|
39
|
+
},
|
|
40
|
+
dateProperty: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
description: 'Row property containing the date to filter, using dot notation for nested values. Use the property reported by inspectTable. It may be omitted when the table has a configured date-range fetch flow.',
|
|
43
|
+
},
|
|
44
|
+
useDefaultDateRange: {
|
|
45
|
+
type: 'boolean',
|
|
46
|
+
description: 'Whether to apply the table\'s configured default date range when startDate and endDate are omitted. Set false for all-time data. Default: true.',
|
|
47
|
+
default: true,
|
|
48
|
+
},
|
|
49
|
+
filters: {
|
|
50
|
+
type: 'array',
|
|
51
|
+
description: 'Additional row filters. Every filter is combined with AND. Use the values array for in/notIn and value for the other operators.',
|
|
52
|
+
default: [],
|
|
53
|
+
items: {
|
|
54
|
+
type: 'object',
|
|
55
|
+
properties: {
|
|
56
|
+
property: {
|
|
57
|
+
type: 'string',
|
|
58
|
+
description: 'Column property to filter, with dot notation allowed for nested values.',
|
|
59
|
+
},
|
|
60
|
+
operator: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
enum: ['==', '!=', '>', '>=', '<', '<=', 'contains', 'startsWith', 'endsWith', 'in', 'notIn', 'isEmpty', 'isNotEmpty'],
|
|
63
|
+
description: 'Comparison operator. contains/startsWith/endsWith are case-insensitive for text; in/notIn compare against values.',
|
|
64
|
+
},
|
|
65
|
+
value: {
|
|
66
|
+
description: 'Comparison value for single-value operators. Preserve the natural string, number, boolean, or null type.',
|
|
67
|
+
anyOf: [
|
|
68
|
+
{ type: 'string' },
|
|
69
|
+
{ type: 'number' },
|
|
70
|
+
{ type: 'boolean' },
|
|
71
|
+
{ type: 'null' },
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
values: {
|
|
75
|
+
type: 'array',
|
|
76
|
+
description: 'Candidate values for the in or notIn operator.',
|
|
77
|
+
items: {
|
|
78
|
+
anyOf: [
|
|
79
|
+
{ type: 'string' },
|
|
80
|
+
{ type: 'number' },
|
|
81
|
+
{ type: 'boolean' },
|
|
82
|
+
{ type: 'null' },
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
required: ['property', 'operator'],
|
|
88
|
+
additionalProperties: false,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
sortBy: {
|
|
92
|
+
type: 'string',
|
|
93
|
+
description: 'Optional property to sort by, with dot notation allowed for nested values.',
|
|
94
|
+
},
|
|
95
|
+
sortDirection: {
|
|
96
|
+
type: 'string',
|
|
97
|
+
enum: ['asc', 'desc'],
|
|
98
|
+
description: 'Sort direction. Default: asc.',
|
|
99
|
+
default: 'asc',
|
|
100
|
+
},
|
|
101
|
+
columns: {
|
|
102
|
+
type: 'array',
|
|
103
|
+
description: 'Optional ordered list of column properties to show. Omit to use the table\'s configured visible columns.',
|
|
104
|
+
items: {
|
|
105
|
+
type: 'string',
|
|
106
|
+
},
|
|
107
|
+
uniqueItems: true,
|
|
108
|
+
},
|
|
109
|
+
limit: {
|
|
110
|
+
type: 'number',
|
|
111
|
+
description: 'Maximum number of matching rows to display and return. Default: 20, minimum: 1, maximum: 100.',
|
|
112
|
+
default: 20,
|
|
113
|
+
minimum: 1,
|
|
114
|
+
maximum: 100,
|
|
115
|
+
},
|
|
116
|
+
title: {
|
|
117
|
+
type: 'string',
|
|
118
|
+
description: 'Short user-facing title for the result widget, for example "Orders from the last 3 weeks".',
|
|
119
|
+
},
|
|
120
|
+
view: {
|
|
121
|
+
type: 'string',
|
|
122
|
+
enum: ['auto', 'table', 'card'],
|
|
123
|
+
description: 'Preferred presentation. auto uses a card for one row and a table for multiple rows. Default: auto.',
|
|
124
|
+
default: 'auto',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
required: [],
|
|
128
|
+
additionalProperties: false,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'calculateTableData',
|
|
133
|
+
description: 'Calculate a count, sum, average, minimum, maximum, median, unique count, grouped result, or custom JavaScript result from this table. Use inspectTable first when property names are unknown. Filtering happens before the calculation, and date ranges are inclusive.',
|
|
134
|
+
executionMode: 'component',
|
|
135
|
+
chatComponent: 'TableCalculationWidget',
|
|
136
|
+
parameters: {
|
|
137
|
+
type: 'object',
|
|
138
|
+
properties: {
|
|
139
|
+
startDate: {
|
|
140
|
+
type: 'string',
|
|
141
|
+
format: 'date',
|
|
142
|
+
description: 'Inclusive start date in YYYY-MM-DD format. Omit when no date range is requested.',
|
|
143
|
+
},
|
|
144
|
+
endDate: {
|
|
145
|
+
type: 'string',
|
|
146
|
+
format: 'date',
|
|
147
|
+
description: 'Inclusive end date in YYYY-MM-DD format. Omit when no date range is requested.',
|
|
148
|
+
},
|
|
149
|
+
dateProperty: {
|
|
150
|
+
type: 'string',
|
|
151
|
+
description: 'Row property containing the date to filter, using dot notation for nested values. It may be omitted when the table has a configured date-range fetch flow.',
|
|
152
|
+
},
|
|
153
|
+
useDefaultDateRange: {
|
|
154
|
+
type: 'boolean',
|
|
155
|
+
description: 'Whether to apply the table\'s configured default date range when startDate and endDate are omitted. Set false for an all-time calculation. Default: true.',
|
|
156
|
+
default: true,
|
|
157
|
+
},
|
|
158
|
+
filters: {
|
|
159
|
+
type: 'array',
|
|
160
|
+
description: 'Optional row filters applied before calculating. Every filter is combined with AND.',
|
|
161
|
+
default: [],
|
|
162
|
+
items: {
|
|
163
|
+
type: 'object',
|
|
164
|
+
properties: {
|
|
165
|
+
property: {
|
|
166
|
+
type: 'string',
|
|
167
|
+
description: 'Column property to filter, with dot notation allowed for nested values.',
|
|
168
|
+
},
|
|
169
|
+
operator: {
|
|
170
|
+
type: 'string',
|
|
171
|
+
enum: ['==', '!=', '>', '>=', '<', '<=', 'contains', 'startsWith', 'endsWith', 'in', 'notIn', 'isEmpty', 'isNotEmpty'],
|
|
172
|
+
description: 'Comparison operator. Use in/notIn with values.',
|
|
173
|
+
},
|
|
174
|
+
value: {
|
|
175
|
+
description: 'Comparison value for single-value operators.',
|
|
176
|
+
anyOf: [
|
|
177
|
+
{ type: 'string' },
|
|
178
|
+
{ type: 'number' },
|
|
179
|
+
{ type: 'boolean' },
|
|
180
|
+
{ type: 'null' },
|
|
181
|
+
],
|
|
182
|
+
},
|
|
183
|
+
values: {
|
|
184
|
+
type: 'array',
|
|
185
|
+
description: 'Candidate values for the in or notIn operator.',
|
|
186
|
+
items: {
|
|
187
|
+
anyOf: [
|
|
188
|
+
{ type: 'string' },
|
|
189
|
+
{ type: 'number' },
|
|
190
|
+
{ type: 'boolean' },
|
|
191
|
+
{ type: 'null' },
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
required: ['property', 'operator'],
|
|
197
|
+
additionalProperties: false,
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
operation: {
|
|
201
|
+
type: 'string',
|
|
202
|
+
enum: ['count', 'sum', 'average', 'min', 'max', 'median', 'unique_count', 'custom'],
|
|
203
|
+
description: 'Calculation to perform. property is required for sum, average, min, max, median, and unique_count. code is required for custom.',
|
|
204
|
+
},
|
|
205
|
+
property: {
|
|
206
|
+
type: 'string',
|
|
207
|
+
description: 'Property to calculate, using dot notation for nested values. Not needed for count or custom.',
|
|
208
|
+
},
|
|
209
|
+
groupBy: {
|
|
210
|
+
type: 'string',
|
|
211
|
+
description: 'Optional property to group rows by before applying the operation. Grouped calculations are displayed as multiple result rows.',
|
|
212
|
+
},
|
|
213
|
+
code: {
|
|
214
|
+
type: 'string',
|
|
215
|
+
description: 'JavaScript function body used only when operation is custom. The filtered rows are available as data (and rows); return a JSON-serializable value, object, or array. Do not access the network, browser APIs, or global state. Example: return data.reduce((total, row) => total + Number(row.amount || 0), 0) / Math.max(data.length, 1)',
|
|
216
|
+
},
|
|
217
|
+
title: {
|
|
218
|
+
type: 'string',
|
|
219
|
+
description: 'Short user-facing title for the result, for example "Average order value".',
|
|
220
|
+
},
|
|
221
|
+
precision: {
|
|
222
|
+
type: 'number',
|
|
223
|
+
description: 'Maximum number of decimal places for numeric results. Default: 2, minimum: 0, maximum: 10.',
|
|
224
|
+
default: 2,
|
|
225
|
+
minimum: 0,
|
|
226
|
+
maximum: 10,
|
|
227
|
+
},
|
|
228
|
+
view: {
|
|
229
|
+
type: 'string',
|
|
230
|
+
enum: ['auto', 'metric', 'card', 'table'],
|
|
231
|
+
description: 'Preferred presentation. auto chooses a metric/card for a single result and a table for grouped or tabular results. Default: auto.',
|
|
232
|
+
default: 'auto',
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
required: ['operation'],
|
|
236
|
+
additionalProperties: false,
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
name: 'performTableRowAction',
|
|
241
|
+
description: 'Prepare a configured action for exactly one matching table row and show a confirmation card before running it. Always call inspectTable first to obtain the action ID and exact row property names. Never guess an action or run it when the row match is ambiguous.',
|
|
242
|
+
executionMode: 'component',
|
|
243
|
+
chatComponent: 'TableRowActionCard',
|
|
244
|
+
parameters: {
|
|
245
|
+
type: 'object',
|
|
246
|
+
properties: {
|
|
247
|
+
action: {
|
|
248
|
+
type: 'string',
|
|
249
|
+
description: 'Action ID returned by inspectTable. An exact action label may only be used when it uniquely identifies one configured action.',
|
|
250
|
+
},
|
|
251
|
+
match: {
|
|
252
|
+
type: 'array',
|
|
253
|
+
description: 'Exact property/value conditions that identify one row. All conditions are combined with AND. Prefer a stable unique ID property.',
|
|
254
|
+
minItems: 1,
|
|
255
|
+
items: {
|
|
256
|
+
type: 'object',
|
|
257
|
+
properties: {
|
|
258
|
+
property: {
|
|
259
|
+
type: 'string',
|
|
260
|
+
description: 'Row property to match, with dot notation allowed for nested values.',
|
|
261
|
+
},
|
|
262
|
+
value: {
|
|
263
|
+
description: 'Exact value to match. Preserve the natural string, number, boolean, or null type.',
|
|
264
|
+
anyOf: [
|
|
265
|
+
{ type: 'string' },
|
|
266
|
+
{ type: 'number' },
|
|
267
|
+
{ type: 'boolean' },
|
|
268
|
+
{ type: 'null' },
|
|
269
|
+
],
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
required: ['property', 'value'],
|
|
273
|
+
additionalProperties: false,
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
startDate: {
|
|
277
|
+
type: 'string',
|
|
278
|
+
format: 'date',
|
|
279
|
+
description: 'Optional inclusive start date in YYYY-MM-DD format used while fetching the candidate row.',
|
|
280
|
+
},
|
|
281
|
+
endDate: {
|
|
282
|
+
type: 'string',
|
|
283
|
+
format: 'date',
|
|
284
|
+
description: 'Optional inclusive end date in YYYY-MM-DD format used while fetching the candidate row.',
|
|
285
|
+
},
|
|
286
|
+
dateProperty: {
|
|
287
|
+
type: 'string',
|
|
288
|
+
description: 'Optional row date property for the date range, with dot notation allowed for nested values.',
|
|
289
|
+
},
|
|
290
|
+
useDefaultDateRange: {
|
|
291
|
+
type: 'boolean',
|
|
292
|
+
description: 'Whether to apply the table\'s configured default date range when startDate and endDate are omitted. Set false to search all time. Default: true.',
|
|
293
|
+
default: true,
|
|
294
|
+
},
|
|
295
|
+
confirmationMessage: {
|
|
296
|
+
type: 'string',
|
|
297
|
+
description: 'Short, explicit confirmation text explaining what will happen to the matched row. The user still has to approve the action in the widget.',
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
required: ['action', 'match'],
|
|
301
|
+
additionalProperties: false,
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const e=require("vue"),ee=require("lucide-vue-next"),fe=require("@oneclick.dev/cms-kit"),he=require("./utils-Yd6F5mea.js"),pe=require("./DateFormatter-CSAbE3BC.js"),_e=require("./_plugin-vue_export-helper-BHFhmbuH.js"),ye={class:"space-y-3"},xe={class:"grid gap-4 @md/modal:grid-cols-2 @2xl/modal:grid-cols-3 @4xl/modal:grid-cols-4 overflow-hidden p-1"},Ne={key:0,class:"flex items-center gap-3 min-h-9"},be={key:0,class:"italic text-xs opacity-50"},Ve={key:0,class:"italic text-xs opacity-50"},Ce={key:0,class:"italic text-xs opacity-50"},Se={key:0,class:"italic text-xs opacity-50"},we={key:0,class:"text-red-400"},Ee={class:"list-disc pl-4"},Te=e.defineComponent({__name:"CustomerInformation",props:{agendaData:{}},setup($,{expose:P}){const w=[{id:"firstName",fieldName:"First Name",fieldType:"text",required:!0,visible:!0},{id:"lastName",fieldName:"Last Name",fieldType:"text",required:!0,visible:!0},{id:"phone",fieldName:"Phone No",fieldType:"tel",required:!0,visible:!0},{id:"email",fieldName:"Email",fieldType:"email",required:!0,visible:!0},{id:"birthDate",fieldName:"Birth date",fieldType:"date",required:!0,visible:!0}],L=new Set(["firstName","email"]),Z=$,R=e.ref([]),V=e.reactive({}),E=e.computed(()=>{const u=Z.agendaData?.customerInformationFields,g=(Array.isArray(u)&&u.length>0?u:w).filter(N=>N?.id&&(N.visible!==!1||L.has(N.id))).map(N=>({...N,required:L.has(N.id),visible:!0})),x=w.filter(N=>L.has(N.id)&&!g.some(X=>X.id===N.id)).map(N=>({...N,required:!0,visible:!0}));return[...g,...x]}),T=u=>u.fieldName||u.id,I=u=>u.replace(/[^A-Za-z0-9_-]/g,"-"),h=(u,b)=>["new-res-customer-info",u.id,b].filter(Boolean).map(x=>I(x)).join("-"),S=u=>u.fieldType==="email"||u.fieldType==="tel"||u.fieldType==="date"?u.fieldType:"text",M=u=>Array.isArray(u.options)?u.options.filter(Boolean):[],O=u=>u.fieldType==="checkbox"?!1:"",B=(u=!1)=>{const b=new Set(E.value.map(g=>g.id));Object.keys(V).forEach(g=>{b.has(g)||delete V[g]}),E.value.forEach(g=>{const x=O(g);(u||V[g.id]===void 0||typeof V[g.id]!=typeof x)&&(V[g.id]=x)})},q=()=>{const u=E.value.reduce((b,g)=>{const x=V[g.id];return b[g.id]=typeof x=="string"?x.trim():!!x,b},{});return Object.entries(u).forEach(([b,g])=>{V[b]=g}),u},k=(u,b)=>u.fieldType==="checkbox"?b===!0:typeof b=="string"?b.trim().length>0:b!=null,G=()=>{R.value=[],B(!0)},U=()=>{const u=[],b=q();return E.value.forEach(g=>{const x=b[g.id],N=T(g);g.required&&!k(g,x)&&u.push(`Please fill in ${N}.`),g.fieldType==="email"&&k(g,x)&&typeof x=="string"&&/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(x)===!1&&u.push(`Please fill in a correct ${N}.`)}),R.value=u,u.length===0};return e.watch(E,()=>{B()},{immediate:!0}),P({getCustomerInfo:q,reset:G,validateForm:U}),(u,b)=>{const g=e.resolveComponent("Checkbox"),x=e.resolveComponent("Label"),N=e.resolveComponent("SelectValue"),X=e.resolveComponent("SelectTrigger"),ae=e.resolveComponent("SelectItem"),se=e.resolveComponent("SelectGroup"),te=e.resolveComponent("SelectContent"),K=e.resolveComponent("Select"),oe=e.resolveComponent("RadioGroupItem"),Y=e.resolveComponent("RadioGroup"),ne=e.resolveComponent("Input");return e.openBlock(),e.createElementBlock("div",ye,[b[0]||(b[0]=e.createElementVNode("h2",{class:"text-sm font-medium"},"Customer Information",-1)),e.createElementVNode("div",xe,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(E.value,m=>(e.openBlock(),e.createElementBlock("div",{key:m.id,class:e.normalizeClass(["grid gap-2",m.fieldType==="checkbox"?"@md/modal:col-span-2":""])},[m.fieldType==="checkbox"?(e.openBlock(),e.createElementBlock("div",Ne,[e.createVNode(g,{id:h(m),modelValue:V[m.id],"onUpdate:modelValue":D=>V[m.id]=D},null,8,["id","modelValue","onUpdate:modelValue"]),e.createVNode(x,{for:h(m),class:"font-normal cursor-pointer"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(T(m))+" ",1),m.required?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("span",be,"optional"))]),_:2},1032,["for"])])):m.fieldType==="select"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createVNode(x,{for:h(m)},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(T(m))+" ",1),m.required?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("span",Ve,"optional"))]),_:2},1032,["for"]),e.createVNode(K,{modelValue:V[m.id],"onUpdate:modelValue":D=>V[m.id]=D},{default:e.withCtx(()=>[e.createVNode(X,{id:h(m),class:"w-full"},{default:e.withCtx(()=>[e.createVNode(N,{placeholder:`Select ${T(m)}`},null,8,["placeholder"])]),_:2},1032,["id"]),e.createVNode(te,null,{default:e.withCtx(()=>[e.createVNode(se,null,{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(M(m),D=>(e.openBlock(),e.createBlock(ae,{key:D,value:D},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(D),1)]),_:2},1032,["value"]))),128))]),_:2},1024)]),_:2},1024)]),_:2},1032,["modelValue","onUpdate:modelValue"])],64)):m.fieldType==="radio"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:2},[e.createVNode(x,null,{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(T(m))+" ",1),m.required?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("span",Ce,"optional"))]),_:2},1024),e.createVNode(Y,{modelValue:V[m.id],"onUpdate:modelValue":D=>V[m.id]=D,class:"grid gap-2"},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(M(m),D=>(e.openBlock(),e.createElementBlock("div",{key:D,class:"flex items-center gap-2"},[e.createVNode(oe,{id:h(m,D),value:D},null,8,["id","value"]),e.createVNode(x,{for:h(m,D),class:"font-normal cursor-pointer"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(D),1)]),_:2},1032,["for"])]))),128))]),_:2},1032,["modelValue","onUpdate:modelValue"])],64)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:3},[e.createVNode(x,{for:h(m)},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(T(m))+" ",1),m.required?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("span",Se,"optional"))]),_:2},1032,["for"]),e.createVNode(ne,{modelValue:V[m.id],"onUpdate:modelValue":D=>V[m.id]=D,id:h(m),type:S(m),autocomplete:"off"},null,8,["modelValue","onUpdate:modelValue","id","type"])],64))],2))),128))]),R.value.length>0?(e.openBlock(),e.createElementBlock("div",we,[e.createElementVNode("ul",Ee,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(R.value,m=>(e.openBlock(),e.createElementBlock("li",{key:m},e.toDisplayString(m),1))),128))])])):e.createCommentVNode("",!0)])}}});function Be($={}){const P=e.ref(null),w=e.ref(!1),L=e.ref(!1),Z=e.ref(!1),R=e.ref(!1),V=$.dragSpeed??1.1,E=$.dragThreshold??10,T=$.edgeThreshold??10,I=$.ignoreDragSelector??'input, select, textarea, [contenteditable="true"], [data-horizontal-scroll-ignore-drag]';let h=null,S=0,M=0,O=!1,B=null,q=null,k=null;const G=()=>{B===null||typeof window>"u"||(window.clearTimeout(B),B=null)},U=()=>{const r=P.value;if(!r){L.value=!1,Z.value=!1,R.value=!1;return}const l=Math.max(r.scrollWidth-r.clientWidth,0);L.value=l>T,Z.value=L.value&&r.scrollLeft>T,R.value=L.value&&r.scrollLeft<l-T},u=()=>{e.nextTick(()=>{if(typeof window>"u"){U();return}window.requestAnimationFrame(()=>U())})},b=()=>{if(typeof $.scrollStep=="number")return $.scrollStep;const r=P.value;return r?Math.max(Math.floor(r.clientWidth*.72),180):240},g=(r,l="smooth")=>{const _=P.value;if(_){if(_.scrollBy({left:r,behavior:l}),l==="auto"){U();return}u()}},x=()=>{g(-b())},N=()=>{g(b())},X=()=>{const r=P.value;h!==null&&r?.hasPointerCapture?.(h)&&r.releasePointerCapture(h),w.value&&(O=!0,G(),typeof window<"u"&&(B=window.setTimeout(()=>{O=!1,B=null},0))),h=null,w.value=!1,r&&(r.style.userSelect="",r.style.cursor=""),U()},ae=()=>{U()},se=r=>{const l=P.value;if(!l||!L.value||Math.abs(r.deltaY)<=Math.abs(r.deltaX))return;const _=r.deltaY<0,W=r.deltaY>0;_&&!Z.value||W&&!R.value||(r.preventDefault(),l.scrollLeft+=r.deltaY,U())},te=r=>r instanceof Element?!!r.closest(I):!1,K=r=>{const l=P.value;!l||!L.value||r.pointerType!=="touch"&&r.button===0&&(te(r.target)||(h=r.pointerId,S=r.clientX,M=l.scrollLeft,O=!1))},oe=r=>{const l=P.value;if(!l||h!==r.pointerId)return;const _=r.clientX-S;!w.value&&Math.abs(_)<E||(w.value||(w.value=!0,l.style.userSelect="none",l.style.cursor="grabbing",l.setPointerCapture?.(r.pointerId)),r.preventDefault(),l.scrollLeft=M-_*V,U())},Y=r=>{h===r.pointerId&&X()},ne=()=>{h!==null&&X()},m=r=>{O&&(r.preventDefault(),r.stopPropagation(),O=!1)},D=r=>{typeof ResizeObserver<"u"&&(q=new ResizeObserver(()=>U()),q.observe(r)),$.observeMutations!==!1&&typeof MutationObserver<"u"&&(k=new MutationObserver(()=>u()),k.observe(r,{childList:!0,subtree:!0,characterData:!0}))},z=()=>{q?.disconnect(),k?.disconnect(),q=null,k=null},ce=r=>{r.addEventListener("scroll",ae),r.addEventListener("wheel",se,{passive:!1}),r.addEventListener("pointerdown",K),r.addEventListener("pointermove",oe),r.addEventListener("pointerup",Y),r.addEventListener("pointercancel",ne),r.addEventListener("lostpointercapture",ne),r.addEventListener("click",m,!0),D(r),u()},le=r=>{r.removeEventListener("scroll",ae),r.removeEventListener("wheel",se),r.removeEventListener("pointerdown",K),r.removeEventListener("pointermove",oe),r.removeEventListener("pointerup",Y),r.removeEventListener("pointercancel",ne),r.removeEventListener("lostpointercapture",ne),r.removeEventListener("click",m,!0),z()};return e.watch(P,(r,l)=>{l&&le(l),r?ce(r):U()}),e.onMounted(()=>{u()}),e.onBeforeUnmount(()=>{G(),P.value&&le(P.value),O=!1,X()}),{canScrollLeft:e.computed(()=>Z.value),canScrollRight:e.computed(()=>R.value),containerRef:P,isDragging:w,isScrollable:L,refresh:u,scrollNext:N,scrollPrev:x,showLeftShadow:Z,showRightShadow:R}}const De={class:"flex items-start justify-between gap-3"},$e={class:"text-sm font-medium"},Re={key:0,class:"mt-1 text-xs text-muted-foreground"},Ie={class:"grid gap-4 @md/quick-adder:grid-cols-2 @2xl/quick-adder:grid-cols-3 @4xl/quick-adder:grid-cols-4"},Fe={class:"grid gap-2"},Oe={key:0,class:"grid gap-2"},Le={key:1,class:"grid gap-2"},Me={key:2,class:"grid gap-2"},Ae={class:"grid gap-2"},Pe={class:"grid gap-2"},Ue={key:0,class:"rounded-md border border-dashed bg-muted/20 px-4 py-4 text-sm text-muted-foreground"},ze={key:1,class:"relative flex items-center gap-2 overflow-hidden"},qe={class:"relative min-w-0 flex-1 overflow-hidden"},je={key:0,class:"pointer-events-none absolute inset-y-0 left-0 z-10 w-10 md:w-20 bg-gradient-to-r from-background via-background/95 to-transparent"},He={key:1,class:"pointer-events-none absolute inset-y-0 right-0 z-10 w-10 md:w-20 bg-gradient-to-l from-background via-background/95 to-transparent"},Qe={key:0,class:"absolute -top-1 -right-1 flex items-center justify-center bg-primary rounded-full text-background size-4"},Ye={class:"flex flex-wrap gap-2"},We=["onClick"],Ge={key:0},Xe={key:1},Ze={key:2},Ke=e.defineComponent({__name:"QuickReservationAdder",props:{agendaData:{},surface:{default:"card"}},emits:["add"],setup($,{emit:P}){const w=$,L=P,Z=new pe.$fb18d541ea1ad717$export$ad991b66133851cf("en-US",{dateStyle:"long"}),R=pe.$14e0f24ef4ac5c92$export$d0bdf45af03a6ea3(pe.$14e0f24ef4ac5c92$export$aa8b41735afcabd2()),V=e.computed(()=>w.surface==="popover"),E=e.ref(""),T=e.ref(void 0),I=e.ref(""),h=e.ref(""),S=e.ref([]),M=e.ref(1),O=e.ref(0),B=e.computed(()=>w.agendaData?.resources?.find(r=>r.id===I.value)),q=r=>{const[l,_]=r.split(":").map(Number);return l*60+_},k=r=>{const l=Math.floor(r/60),_=r%60;return`${l.toString().padStart(2,"0")}:${_.toString().padStart(2,"0")}`},G=()=>{if(!B.value)return[];const r=B.value.interval||60;let l=null,_=null;for(const a of Object.values(B.value.openingHours||{}))for(const n of a){const d=q(n.start),v=q(n.end);(l===null||d<l)&&(l=d),(_===null||v>_)&&(_=v)}if(l===null||_===null)return[];const W=[];for(let a=l;a<_;a+=r)W.push(k(a));return W},U=e.computed(()=>{const r=Number(O.value);return T.value&&I.value&&h.value&&S.value.length>0&&Number.isFinite(r)&&r>=0}),u=e.computed(()=>G()),{canScrollLeft:b,canScrollRight:g,containerRef:x,isDragging:N,isScrollable:X,scrollNext:ae,scrollPrev:se,showLeftShadow:te,showRightShadow:K}=Be(),oe=r=>S.value.includes(r),Y=r=>{if(oe(r)){S.value=S.value.filter(l=>l!==r);return}S.value=[...S.value,r].sort((l,_)=>q(l)-q(_))},ne=(r,l)=>{T.value=r?e.markRaw(r):void 0,E.value=r?`${r}`:"",l()},m=e.ref(""),D=e.ref(""),z=e.ref([]),ce=()=>{L("add",{date:T.value,resourceId:I.value,pricingOptionId:h.value,startTimes:S.value,spots:M.value,paid:Number(O.value)||0}),S.value=[],z.value=[],D.value="",m.value=""},le=()=>{E.value=R.toString(),T.value=R,I.value=w.agendaData?.resources?.[0]?.id||"",h.value=w.agendaData?.pricingOptions?.find(r=>r.isDefault)?.id||w.agendaData?.pricingOptions?.[0]?.id||"",S.value=[],M.value=1,O.value=0,m.value=""};return e.onMounted(()=>{le()}),(r,l)=>{const _=e.resolveComponent("Label"),W=e.resolveComponent("Button"),a=e.resolveComponent("PopoverTrigger"),n=e.resolveComponent("Calendar"),d=e.resolveComponent("PopoverContent"),v=e.resolveComponent("Popover"),C=e.resolveComponent("DynamicSelectOption"),H=e.resolveComponent("DynamicSelect"),j=e.resolveComponent("Input");return e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(e.unref(he.classNames)("@container/quick-adder grid gap-4 overflow-hidden bg-background",e.unref(V)?"p-5 sm:p-6":"rounded-md border p-4"))},[e.createElementVNode("div",De,[e.createElementVNode("div",null,[e.createElementVNode("h3",$e,e.toDisplayString(e.unref(V)?"Quick add reservations":"Add reservations"),1),e.unref(V)?(e.openBlock(),e.createElementBlock("p",Re," Choose one date and add multiple timeslots in one pass. ")):e.createCommentVNode("",!0)])]),e.createElementVNode("div",Ie,[e.createElementVNode("div",Fe,[e.createVNode(_,null,{default:e.withCtx(()=>[...l[4]||(l[4]=[e.createTextVNode("Date",-1)])]),_:1}),e.createVNode(v,null,{default:e.withCtx(({close:p})=>[e.createVNode(a,{"as-child":""},{default:e.withCtx(()=>[e.createVNode(W,{type:"button",variant:"outline",class:e.normalizeClass(e.unref(he.classNames)("w-full justify-start text-left font-normal",!e.unref(T)&&"text-muted-foreground"))},{default:e.withCtx(()=>[e.createVNode(e.unref(ee.CalendarIcon)),e.createTextVNode(" "+e.toDisplayString(e.unref(T)?e.unref(Z).format(e.unref(T).toDate(e.unref(pe.$14e0f24ef4ac5c92$export$aa8b41735afcabd2)())):"Pick a date"),1)]),_:1},8,["class"])]),_:1}),e.createVNode(d,{class:"w-auto p-0",align:"start"},{default:e.withCtx(()=>[e.createVNode(n,{"model-value":e.unref(T),"default-placeholder":e.unref(R),layout:"month-and-year","initial-focus":"","onUpdate:modelValue":re=>ne(re,p),minValue:e.unref(pe.$14e0f24ef4ac5c92$export$d0bdf45af03a6ea3)(e.unref(pe.$14e0f24ef4ac5c92$export$aa8b41735afcabd2)())},null,8,["model-value","default-placeholder","onUpdate:modelValue","minValue"])]),_:2},1024)]),_:1})]),$.agendaData.resources?.length>1?(e.openBlock(),e.createElementBlock("div",Oe,[e.createVNode(_,null,{default:e.withCtx(()=>[...l[5]||(l[5]=[e.createTextVNode("Resource",-1)])]),_:1}),e.createVNode(H,{modelValue:e.unref(I),"onUpdate:modelValue":l[0]||(l[0]=p=>e.isRef(I)?I.value=p:null),"wrapper-class":"w-full",class:"w-full",placeholder:"Select resource"},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList($.agendaData.resources||[],p=>(e.openBlock(),e.createBlock(C,{key:p.id,value:p.id},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(p.name),1)]),_:2},1032,["value"]))),128))]),_:1},8,["modelValue"])])):e.createCommentVNode("",!0),$.agendaData.pricingOptions?.length>1?(e.openBlock(),e.createElementBlock("div",Le,[e.createVNode(_,null,{default:e.withCtx(()=>[...l[6]||(l[6]=[e.createTextVNode("Type",-1)])]),_:1}),e.createVNode(H,{modelValue:e.unref(h),"onUpdate:modelValue":l[1]||(l[1]=p=>e.isRef(h)?h.value=p:null),"wrapper-class":"w-full",class:"w-full",placeholder:"Select type"},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList($.agendaData.pricingOptions||[],p=>(e.openBlock(),e.createBlock(C,{key:p.id,value:p.id},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(p.name)+" ("+e.toDisplayString(p.duration)+"min) ",1)]),_:2},1032,["value"]))),128))]),_:1},8,["modelValue"])])):e.createCommentVNode("",!0),$.agendaData?.maxTicketsPerReservation>1?(e.openBlock(),e.createElementBlock("div",Me,[e.createVNode(_,null,{default:e.withCtx(()=>[...l[7]||(l[7]=[e.createTextVNode("Spots/tickets",-1)])]),_:1}),e.createVNode(j,{modelValue:e.unref(M),"onUpdate:modelValue":l[2]||(l[2]=p=>e.isRef(M)?M.value=p:null),modelModifiers:{number:!0},type:"number",min:"1",class:"no-spinner",autocomplete:"off"},null,8,["modelValue"])])):e.createCommentVNode("",!0),e.createElementVNode("div",Ae,[e.createVNode(_,null,{default:e.withCtx(()=>[...l[8]||(l[8]=[e.createTextVNode("Paid (per reservation)",-1)])]),_:1}),e.createVNode(j,{modelValue:e.unref(O),"onUpdate:modelValue":l[3]||(l[3]=p=>e.isRef(O)?O.value=p:null),modelModifiers:{number:!0},type:"number",min:"0",step:"1",class:"no-spinner",autocomplete:"off"},null,8,["modelValue"]),l[9]||(l[9]=e.createElementVNode("p",{class:"text-xs text-muted-foreground"}," This amount is copied to every reservation you add. ",-1))])]),e.createElementVNode("div",Pe,[e.createVNode(_,null,{default:e.withCtx(()=>[...l[10]||(l[10]=[e.createTextVNode("Available hours",-1)])]),_:1}),e.unref(u).length===0?(e.openBlock(),e.createElementBlock("div",Ue," No preset hours are available for this resource. You can still add a custom time below. ")):(e.openBlock(),e.createElementBlock("div",ze,[e.unref(b)?(e.openBlock(),e.createBlock(W,{key:0,type:"button",size:"icon",variant:"outline",class:"hidden absolute size-8 shrink-0 rounded-full shadow-sm md:inline-flex z-[11] left-0.5",onClick:e.unref(se)},{default:e.withCtx(()=>[e.createVNode(e.unref(ee.ChevronLeft),{class:"size-4"})]),_:1},8,["onClick"])):e.createCommentVNode("",!0),e.createElementVNode("div",qe,[e.unref(te)?(e.openBlock(),e.createElementBlock("div",je)):e.createCommentVNode("",!0),e.unref(K)?(e.openBlock(),e.createElementBlock("div",He)):e.createCommentVNode("",!0),e.createElementVNode("div",{ref_key:"hourScrollContainer",ref:x,class:e.normalizeClass(e.unref(he.classNames)("hour-scroll-track flex w-full min-w-0 gap-2 overflow-x-auto overscroll-contain py-2",e.unref(X)&&!e.unref(N)&&"cursor-grab",e.unref(N)&&"cursor-grabbing select-none"))},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(u),p=>(e.openBlock(),e.createBlock(W,{key:p,type:"button",variant:"outline",class:e.normalizeClass(["relative h-12 shrink-0",oe(p)?"border-primary!":""]),onClick:re=>Y(p)},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(p)+" ",1),oe(p)?(e.openBlock(),e.createElementBlock("div",Qe,[e.createVNode(e.unref(ee.Check),{class:"size-3"})])):e.createCommentVNode("",!0)]),_:2},1032,["class","onClick"]))),128))],2)]),e.unref(g)?(e.openBlock(),e.createBlock(W,{key:1,type:"button",size:"icon",variant:"outline",class:"hidden absolute size-8 shrink-0 rounded-full shadow-sm md:inline-flex z-[11] right-0.5",onClick:e.unref(ae)},{default:e.withCtx(()=>[e.createVNode(e.unref(ee.ChevronRight),{class:"size-4"})]),_:1},8,["onClick"])):e.createCommentVNode("",!0)])),e.createElementVNode("div",Ye,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(z),p=>(e.openBlock(),e.createElementBlock("div",{key:p,class:"relative"},[e.createVNode(W,{type:"button",variant:"outline",class:"h-12 px-4 py-2"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(p),1)]),_:2},1024),e.createElementVNode("div",{class:"absolute -top-1 -right-1 flex items-center justify-center bg-red-500 rounded-full text-white size-4 cursor-pointer",onClick:re=>{z.value=e.unref(z).filter(J=>J!==p),S.value=e.unref(S).filter(J=>J!==p)}},[e.createVNode(e.unref(ee.X),{class:"size-3"})],8,We)]))),128))])]),e.createElementVNode("div",null,[e.createVNode(W,{disabled:!e.unref(U),onClick:ce},{default:e.withCtx(()=>[e.unref(S).length===0?(e.openBlock(),e.createElementBlock("span",Ge,"Select at least one timeslot")):e.unref(S).length===1?(e.openBlock(),e.createElementBlock("span",Xe,"Add 1 reservation")):(e.openBlock(),e.createElementBlock("span",Ze,"Add "+e.toDisplayString(e.unref(S).length)+" reservations",1))]),_:1},8,["disabled"])])],2)}}}),Je=_e._export_sfc(Ke,[["__scopeId","data-v-30be47b0"]]),et={class:"space-y-3"},tt={class:"flex flex-wrap items-center justify-between gap-3"},ot={class:"text-xs text-muted-foreground"},nt={class:"flex flex-wrap items-center gap-2"},at={key:0,class:"rounded-md border border-dashed bg-muted/20 px-4 py-6 text-sm text-muted-foreground"},rt={key:1,class:"space-y-3"},st={class:"flex items-start gap-2 p-3 md:hidden"},lt=["aria-expanded","onClick"],it={class:"mt-0.5 flex size-10 shrink-0 items-center justify-center rounded-full bg-muted text-sm font-semibold text-muted-foreground"},ct={class:"min-w-0 flex-1"},dt={class:"flex items-start justify-between gap-3"},ut={class:"min-w-0"},mt={class:"block truncate text-base font-semibold"},pt={class:"mt-1 block truncate text-xs text-muted-foreground"},ft={class:"mt-1 block truncate text-xs text-muted-foreground"},gt={class:"flex size-10 shrink-0 items-center justify-center rounded-xl border border-border/70 text-muted-foreground"},vt={class:"mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground"},ht={class:"inline-flex items-center gap-1.5"},kt={class:"inline-flex items-center gap-1.5"},_t={class:"hidden items-start justify-between gap-3 p-4 pb-0 md:flex"},yt={class:"text-sm font-medium"},xt={class:"text-xs text-muted-foreground"},Nt={class:"grid gap-4 border-t pt-3 md:grid-cols-2 md:border-0 md:pt-4 xl:grid-cols-5"},bt={class:"grid gap-2"},Vt={class:"grid gap-2"},Ct={key:0,class:"text-xs text-orange-500"},St={class:"grid gap-2"},wt={key:0,class:"text-xs text-muted-foreground"},Et={key:1,class:"flex items-center h-[36px] text-sm"},Tt={key:0},Bt={key:1},Dt={key:2},$t={key:0,class:"grid gap-2"},Rt=e.defineComponent({__name:"ReservationLines",props:{modelValue:{},agendaData:{},availabilityByReservation:{}},emits:["add","quick-add","update:modelValue"],setup($,{emit:P}){const w=$,L=P,Z=/^([01]\d|2[0-3]):[0-5]\d$/,R=e.computed(()=>w.modelValue??[]),V=e.computed(()=>Number(w.agendaData?.maxTicketsPerReservation)>1),E=e.ref(null),T=e.ref(!1),I=e.computed(()=>String(w.agendaData?.currency||"EUR").toUpperCase()),h=e.computed(()=>{try{return new Intl.NumberFormat("en-US",{style:"currency",currency:I.value,minimumFractionDigits:2,maximumFractionDigits:2})}catch{return new Intl.NumberFormat("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}}),S=a=>{L("update:modelValue",a)},M=a=>["date","resourceId","pricingOption"].includes(a),O=a=>{if(!a.date||!a.resourceId||!a.pricingOption)return a;const n=Y(a);return n.length===0?{...a,startTime:""}:n.includes(a.startTime)?a:{...a,startTime:n[0]}},B=(a,n,d)=>{S(R.value.map(v=>{if(v.id!==a)return v;if(n==="date"){const H={...v,date:String(d??""),dateValue:d||void 0};return O(H)}const C={...v,[n]:d};return M(n)?O(C):C}))},q=(a,n)=>{const d=Number(n);B(a,"paid",Number.isFinite(d)?d:0)},k=(a,n)=>{const d=Number(n);B(a,"spots",Number.isFinite(d)&&d>0?d:1)},G=a=>{S(R.value.filter(n=>n.id!==a))},U=a=>{L("quick-add",a),T.value=!1},u=a=>w.agendaData?.pricingOptions?.find(n=>n.id===a.pricingOption),b=a=>{const n=u(a);return n?n.duration?`${n.name} (${n.duration}min)`:n.name:"Reservation"},g=a=>w.agendaData?.resources?.find(n=>n.id===a.resourceId),x=a=>g(a)?.name||"Unknown resource",N=a=>{if(!a||!Z.test(a))return null;const[n,d]=a.split(":").map(Number);return n*60+d},X=a=>{const n=(a%1440+1440)%1440,d=Math.floor(n/60),v=n%60;return`${d.toString().padStart(2,"0")}:${v.toString().padStart(2,"0")}`},ae=a=>{const n=Number(u(a)?.duration);return Number.isFinite(n)&&n>0?n:0},se=a=>{if(!a.startTime)return"";const n=ae(a);if(n<=0)return"";const d=N(a.startTime);return d===null?"":X(d+n)},te=a=>{if(!/^\d{4}-\d{2}-\d{2}$/.test(a))return null;const[n,d,v]=a.split("-").map(Number),C=new Date(n,d-1,v);return Number.isNaN(C.getTime())||C.getFullYear()!==n||C.getMonth()!==d-1||C.getDate()!==v?null:C},K=(a,n)=>(w.agendaData?.exceptions||[]).find(v=>n>=v.startDate&&n<=v.endDate?!v.resourceIds||v.resourceIds.length===0?!0:v.resourceIds.includes(a):!1)||null,oe=a=>{const n=g(a),d=te(a.date);if(!n||!d)return[];const v=K(n.id,a.date);if(v)return v.isClosed?[]:(v.timeslots||[]).map(H=>({start:H.startTime,end:H.endTime}));const C=d.getDay();return n.openingHours?.[C]||[]},Y=a=>{const n=g(a);if(!n)return[];const d=Number(n.interval)>0?Number(n.interval):60,v=ae(a),C=new Set;for(const H of oe(a)){const j=N(H.start),p=N(H.end);if(j===null||p===null||p<=j)continue;const re=v>0?p-v:p-d;for(let J=j;J<=re;J+=d)C.add(X(J))}return Array.from(C).sort((H,j)=>(N(H)??0)-(N(j)??0))},ne=a=>{if(!a.startTime)return"Select time";const n=se(a);return n?`${a.startTime} - ${n}`:a.startTime},m=a=>{const n=Number(a);if(!Number.isFinite(n))return I.value==="EUR"?"€0.00":"0.00";try{return h.value.format(n)}catch{return`${n.toFixed(2)}`}},D=a=>{const n=Number(a.spots),d=Number.isFinite(n)&&n>0?n:1;return d===1?"1 spot":`${d} spots`},z=a=>w.availabilityByReservation?.[a.id]??null,ce=a=>{const n=z(a);return!n||n.status==="checking"?"text-muted-foreground":n.status==="available"?"text-green-600 dark:text-green-400":"text-red-600 dark:text-red-400"},le=a=>{if(!/^\d{4}-\d{2}-\d{2}$/.test(a))return null;const[n,d,v]=a.split("-").map(Number),C=new Date(n,d-1,v);return Number.isNaN(C.getTime())||C.getFullYear()!==n||C.getMonth()!==d-1||C.getDate()!==v?null:(C.setHours(0,0,0,0),C)},r=a=>{const n=le(String(a.date||"").trim());if(!n)return"";const d=new Date;if(d.setHours(0,0,0,0),n<d)return"This date is in the past. Double-check it before saving.";const v=new Date(d);return v.setFullYear(v.getFullYear()+1),n>v?"This date is more than a year ahead. Double-check it before saving.":""},l=a=>!a.date||!a.startTime||!a.resourceId||!a.pricingOption,_=a=>E.value===a,W=a=>{E.value=E.value===a?null:a};return e.watch(R,a=>{const n=new Set(a.map(d=>d.id));if(E.value&&!n.has(E.value)&&(E.value=null),!E.value){const d=a.find(l);d&&(E.value=d.id)}},{immediate:!0}),(a,n)=>{const d=e.resolveComponent("Button"),v=e.resolveComponent("PopoverTrigger"),C=e.resolveComponent("PopoverContent"),H=e.resolveComponent("Popover"),j=e.resolveComponent("Label"),p=e.resolveComponent("DynamicSelectOption"),re=e.resolveComponent("DynamicSelect"),J=e.resolveComponent("Input"),ge=e.resolveComponent("SelectValue"),ve=e.resolveComponent("SelectTrigger"),t=e.resolveComponent("SelectItem"),s=e.resolveComponent("SelectContent"),c=e.resolveComponent("Select");return e.openBlock(),e.createElementBlock("div",et,[e.createElementVNode("div",tt,[e.createElementVNode("p",ot,e.toDisplayString(R.value.length===1?"1 reservation line":`${R.value.length} reservation lines`),1),e.createElementVNode("div",nt,[e.createVNode(H,{open:T.value,"onUpdate:open":n[0]||(n[0]=o=>T.value=o)},{default:e.withCtx(()=>[e.createVNode(v,{"as-child":""},{default:e.withCtx(()=>[e.createVNode(d,{type:"button",variant:"outline",size:"sm",class:"gap-2"},{default:e.withCtx(()=>[e.createVNode(e.unref(ee.Zap),{class:"size-4 text-primary"}),n[2]||(n[2]=e.createTextVNode(" Quick add ",-1))]),_:1})]),_:1}),e.createVNode(C,{align:"end",class:"max-h-[80vh] w-[min(34rem,calc(100vw-2rem))] overflow-y-auto p-0"},{default:e.withCtx(()=>[T.value?(e.openBlock(),e.createBlock(Je,{key:0,surface:"popover",agendaData:$.agendaData,onAdd:U},null,8,["agendaData"])):e.createCommentVNode("",!0)]),_:1})]),_:1},8,["open"]),e.createVNode(d,{type:"button",variant:"outline",size:"sm",onClick:n[1]||(n[1]=o=>L("add"))},{default:e.withCtx(()=>[e.createVNode(e.unref(ee.Plus),{class:"size-4"}),n[3]||(n[3]=e.createTextVNode(" Add line ",-1))]),_:1})])]),R.value.length===0?(e.openBlock(),e.createElementBlock("div",at," Use Quick add to create filled reservation lines, or add an empty line manually. ")):(e.openBlock(),e.createElementBlock("div",rt,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(R.value,(o,f)=>(e.openBlock(),e.createElementBlock("div",{key:o.id,class:"rounded-xl border bg-background"},[e.createElementVNode("div",st,[e.createElementVNode("button",{type:"button",class:"flex min-w-0 flex-1 items-start gap-3 rounded-lg px-1 py-1 text-left outline-none transition-colors hover:bg-muted/40 focus-visible:ring-2 focus-visible:ring-ring/50","aria-expanded":_(o.id),onClick:i=>W(o.id)},[e.createElementVNode("span",it,e.toDisplayString(f+1),1),e.createElementVNode("span",ct,[e.createElementVNode("span",dt,[e.createElementVNode("span",ut,[e.createElementVNode("span",mt,e.toDisplayString(ne(o)),1),e.createElementVNode("span",pt,e.toDisplayString(o.date||"No date selected"),1),e.createElementVNode("span",ft,e.toDisplayString(x(o))+" · "+e.toDisplayString(b(o)),1),z(o)?.message?(e.openBlock(),e.createElementBlock("span",{key:0,class:e.normalizeClass(["mt-1 block text-xs font-medium",ce(o)])},e.toDisplayString(z(o)?.message),3)):e.createCommentVNode("",!0)]),e.createElementVNode("span",gt,[e.createVNode(e.unref(ee.Pencil),{class:"size-4"})])]),e.createElementVNode("span",vt,[e.createElementVNode("span",ht,[e.createVNode(e.unref(ee.Users),{class:"size-4"}),e.createTextVNode(" "+e.toDisplayString(D(o)),1)]),e.createElementVNode("span",kt,[e.createVNode(e.unref(ee.Tag),{class:"size-4"}),e.createTextVNode(" "+e.toDisplayString(m(o.paid)),1)])])])],8,lt),e.createVNode(d,{type:"button",variant:"ghost",size:"icon",class:"mt-1 shrink-0",onClick:i=>G(o.id)},{default:e.withCtx(()=>[e.createVNode(e.unref(ee.Trash2),{class:"size-4"})]),_:1},8,["onClick"])]),e.createElementVNode("div",_t,[e.createElementVNode("div",null,[e.createElementVNode("p",yt,"Reservation "+e.toDisplayString(f+1),1),e.createElementVNode("p",xt,e.toDisplayString(x(o))+" · "+e.toDisplayString(b(o)),1),z(o)?.message?(e.openBlock(),e.createElementBlock("p",{key:0,class:e.normalizeClass(["mt-1 text-xs font-medium",ce(o)])},e.toDisplayString(z(o)?.message),3)):e.createCommentVNode("",!0)]),e.createVNode(d,{type:"button",variant:"ghost",size:"icon",class:"shrink-0",onClick:i=>G(o.id)},{default:e.withCtx(()=>[e.createVNode(e.unref(ee.Trash2),{class:"size-4"})]),_:1},8,["onClick"])]),e.createElementVNode("div",{class:e.normalizeClass(["px-3 pb-3 md:px-4 md:pb-4 overflow-hidden",_(o.id)?"block":"hidden md:block"])},[e.createElementVNode("div",Nt,[e.createElementVNode("div",bt,[e.createVNode(j,null,{default:e.withCtx(()=>[...n[4]||(n[4]=[e.createTextVNode("Resource",-1)])]),_:1}),e.createVNode(re,{"model-value":o.resourceId,"wrapper-class":"w-full",class:"w-full",placeholder:"Select resource","onUpdate:modelValue":i=>B(o.id,"resourceId",String(i??""))},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList($.agendaData?.resources||[],i=>(e.openBlock(),e.createBlock(p,{key:i.id,value:i.id},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(i.name),1)]),_:2},1032,["value"]))),128))]),_:1},8,["model-value","onUpdate:modelValue"])]),e.createElementVNode("div",Vt,[e.createVNode(j,null,{default:e.withCtx(()=>[...n[5]||(n[5]=[e.createTextVNode("Date",-1)])]),_:1}),e.createVNode(J,{"model-value":o.date,type:"date","onUpdate:modelValue":i=>B(o.id,"date",String(i??""))},null,8,["model-value","onUpdate:modelValue"]),r(o)?(e.openBlock(),e.createElementBlock("p",Ct,e.toDisplayString(r(o)),1)):e.createCommentVNode("",!0)]),e.createElementVNode("div",St,[e.createVNode(j,{for:`new_reservation_res_line_${f}_time`},{default:e.withCtx(()=>[...n[6]||(n[6]=[e.createTextVNode("Time",-1)])]),_:1},8,["for"]),o.resourceId&&o.date?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createVNode(c,{"model-value":o.startTime,"onUpdate:modelValue":i=>B(o.id,"startTime",String(i??""))},{default:e.withCtx(()=>[e.createVNode(ve,{id:`new_reservation_res_line_${f}_time`,class:"w-full"},{default:e.withCtx(()=>[e.createVNode(ge,{placeholder:"Select an hour"})]),_:1},8,["id"]),e.createVNode(s,null,{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(Y(o),i=>(e.openBlock(),e.createBlock(t,{key:i,value:i},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(i),1)]),_:2},1032,["value"]))),128))]),_:2},1024)]),_:2},1032,["model-value","onUpdate:modelValue"]),o.resourceId&&o.date&&Y(o).length===0?(e.openBlock(),e.createElementBlock("p",wt," No times are available for this resource on the selected date. ")):e.createCommentVNode("",!0)],64)):(e.openBlock(),e.createElementBlock("p",Et,[!o.resourceId&&!o.date?(e.openBlock(),e.createElementBlock("span",Tt,"Please select a resource and date.")):o.resourceId?o.date?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("span",Dt,"Please select a date.")):(e.openBlock(),e.createElementBlock("span",Bt,"Please select a resource."))]))]),e.createElementVNode("div",{class:e.normalizeClass(["grid gap-2",{hidden:$.agendaData?.pricingOptions?.length<2}])},[e.createVNode(j,null,{default:e.withCtx(()=>[...n[7]||(n[7]=[e.createTextVNode("Type",-1)])]),_:1}),e.createVNode(re,{"model-value":o.pricingOption,"wrapper-class":"w-full",class:"w-full",placeholder:"Select type","onUpdate:modelValue":i=>B(o.id,"pricingOption",String(i??""))},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList($.agendaData?.pricingOptions||[],i=>(e.openBlock(),e.createBlock(p,{key:i.id,value:i.id},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(i.name),1)]),_:2},1032,["value"]))),128))]),_:1},8,["model-value","onUpdate:modelValue"])],2),e.createElementVNode("div",{class:e.normalizeClass(["grid gap-4",V.value?"md:grid-cols-2 xl:grid-cols-2 xl:col-span-1":""])},[V.value?(e.openBlock(),e.createElementBlock("div",$t,[e.createVNode(j,null,{default:e.withCtx(()=>[...n[8]||(n[8]=[e.createTextVNode("Spots",-1)])]),_:1}),e.createVNode(J,{"model-value":o.spots,type:"number",min:"1",class:"no-spinner","onUpdate:modelValue":i=>k(o.id,i)},null,8,["model-value","onUpdate:modelValue"])])):e.createCommentVNode("",!0),e.createElementVNode("div",{class:e.normalizeClass(["grid gap-2",V.value?"":"md:col-span-2 xl:col-span-1"])},[e.createVNode(j,null,{default:e.withCtx(()=>[...n[9]||(n[9]=[e.createTextVNode("Paid",-1)])]),_:1}),e.createVNode(J,{"model-value":o.paid,type:"number",min:"0",step:"1",class:"no-spinner","onUpdate:modelValue":i=>q(o.id,i)},null,8,["model-value","onUpdate:modelValue"])],2)],2)])],2)]))),128))]))])}}}),It={class:"space-y-5 md:mt-5"},Ft={class:"space-y-3"},Ot={class:"mt-4 text-red-400"},Lt={class:"list-disc pl-4"},Mt={key:0},At={key:1},Pt={key:2},ke="",Ut=e.defineComponent({__name:"NewReservationDialog",props:{agendaData:{}},setup($){const P=$,{params:w}=fe.useModuleRoute(),{config:L}=fe.useModule(),{log:Z,logError:R}=fe.useLogs(),V=fe.useFirebaseIntegration(L.project),E=e.computed(()=>w.value?.id??w.id??""),T=e.inject("agendaData",e.ref({})),I=e.computed(()=>P.agendaData??T.value??{}),h=e.ref(!1),S=e.ref(!1),M=e.ref({});let O=0;const B=e.ref([]),q=/^([01]\d|2[0-3]):[0-5]\d$/,k=e.ref([]),G=e.ref(null),U=e.computed(()=>Object.values(M.value).some(t=>t.status==="checking")),u=e.computed(()=>Object.values(M.value).some(t=>t.status==="unavailable")),b=()=>I.value?.resources?.[0]?.id??"",g=()=>I.value?.pricingOptions?.find(t=>t.isDefault===!0)?.id??I.value?.pricingOptions?.[0]?.id??"",x=()=>{const t=new Date,s=t.getFullYear(),c=`${t.getMonth()+1}`.padStart(2,"0"),o=`${t.getDate()}`.padStart(2,"0");return`${s}-${c}-${o}`},N=t=>{let s=t?.pricingOption??g(),c=I.value?.pricingOptions?.find(f=>f.id===s)?.price??0;typeof c=="string"&&(c=Number(c));let o=t?.paid??c;return typeof o=="string"&&(o=Number(o)),{id:`reservation_${Date.now()}_${Math.random().toString(36).substring(2,9)}`,spots:Number(t?.spots)||1,paid:Number.isFinite(o)?o:0,resourceId:t?.resourceId??b(),pricingOption:s,date:t?.date??x(),dateValue:t?.dateValue,startTime:t?.startTime??ke}},X=()=>{k.value=[N()]},ae=t=>(!t.date||t.date===x())&&t.startTime===ke,se=()=>{const t=k.value[k.value.length-1];k.value=[...k.value,N(t?{...t}:void 0)]},te=t=>I.value?.pricingOptions?.find(s=>s.id===t.pricingOption),K=t=>I.value?.resources?.find(s=>s.id===t.resourceId),oe=()=>{const t=Number(I.value?.maxTicketsPerReservation);return Number.isFinite(t)&&t>0?t:null},Y=t=>`Reservation ${t+1}`,ne=t=>{const s=String(t.date||"").trim(),c=String(t.startTime||"").trim(),o=String(t.resourceId||"").trim();return!s||!c||!o?"":`${o}_${s}_${c}`},m=()=>{const t=[],s=new Map,c=oe();return k.value.forEach((o,f)=>{const i=Y(f),F=String(o.date||"").trim(),A=String(o.startTime||"").trim(),y=String(o.resourceId||"").trim(),Q=String(o.pricingOption||"").trim(),ue=Number(o.spots),de=Number(o.paid);F||t.push(`${i}: please select a date.`),A?q.test(A)||t.push(`${i}: please enter a valid time.`):t.push(`${i}: please select a time.`),y?K(o)||t.push(`${i}: the selected resource is no longer available.`):t.push(`${i}: please select a resource.`),Q?te(o)||t.push(`${i}: the selected type is no longer available.`):t.push(`${i}: please select a type.`),!Number.isFinite(ue)||ue<=0?t.push(`${i}: spots must be at least 1.`):c!==null&&ue>c&&t.push(`${i}: spots cannot be more than ${c}.`),(!Number.isFinite(de)||de<0)&&t.push(`${i}: paid amount must be 0 or higher.`);const ie=ne(o);if(ie){const me=s.get(ie);me!==void 0?t.push(`${i}: duplicate of ${Y(me).toLowerCase()}.`):s.set(ie,f)}}),t},D=t=>{const s=t.startTimes.map(c=>N({date:t.date?`${t.date}`:"",dateValue:t.date,pricingOption:t.pricingOptionId,resourceId:t.resourceId,spots:t.spots,paid:t.paid,startTime:c}));if(s.length!==0){if(k.value.length===1&&ae(k.value[0])){k.value=s;return}k.value=[...k.value,...s]}},z=t=>{if(!t||!q.test(t))return null;const[s,c]=t.split(":").map(Number);return s*60+c},ce=t=>{const s=(t%1440+1440)%1440,c=Math.floor(s/60),o=s%60;return`${c.toString().padStart(2,"0")}:${o.toString().padStart(2,"0")}`},le=t=>{if(!t.startTime||!t.pricingOption)return"";const s=te(t),c=Number(s?.duration);if(!Number.isFinite(c)||c<=0)return t.startTime;const o=z(t.startTime);return o===null?"":ce(o+c)},r=t=>{const s=Number(t.spots);return Number.isFinite(s)&&s>0?s:1},l=t=>{const s=Number(K(t)?.capacity);return Number.isFinite(s)&&s>0?s:1},_=t=>{const s=String(t.date||"").trim(),c=String(t.resourceId||"").trim(),o=z(t.startTime),f=z(le(t));return!s||!c||!K(t)||!te(t)||o===null||f===null||f<=o?null:{reservation:t,date:s,resourceId:c,startMinutes:o,endMinutes:f,capacity:l(t),requestedSpots:r(t)}},W=t=>["approved","needs_approval"].includes(t?.status),a=(t,s,c,o)=>t<o&&s>c,n=t=>`${t} ${t===1?"spot":"spots"}`,d=(t,s,c)=>t<c?{status:"unavailable",message:`Not enough spots: ${n(Math.max(t,0))} open, needs ${n(c)}.`}:{status:"available",message:`Available: ${t} of ${s} ${s===1?"spot":"spots"} open, ${n(t-c)} will remain.`},v=t=>t?.id||t?.orderId||"",C=(t,s)=>{const c=[];for(let o=0;o<t.length;o+=s)c.push(t.slice(o,o+s));return c},H=async t=>{const s=new Map,c=[];for(const o of C(t,10)){const f=[{field:"status",operator:"==",value:"confirmed"},{field:"flattenedReservationDates",operator:"array-contains-any",value:o}];E.value&&f.unshift({field:"agendaId",operator:"==",value:E.value});const i=await V.find(L.reservationsCollection,{filters:f});for(const F of i||[]){const A=v(F);A?s.set(A,F):c.push(F)}}return[...s.values(),...c]},j=(t,s)=>{let c=0;for(const o of t)for(const f of o?.reservations||[]){if(!W(f)||f?.date!==s.date||f?.resourceId!==s.resourceId)continue;const i=z(f?.timeslot?.startTime),F=z(f?.timeslot?.endTime);if(i===null||F===null||F<=i||!a(s.startMinutes,s.endMinutes,i,F))continue;const A=Number(f?.spots);c+=Number.isFinite(A)&&A>0?A:1}return c},p=t=>{let s=0;for(const c of k.value){if(c.id===t.reservation.id)continue;const o=_(c);o&&o.date===t.date&&o.resourceId===t.resourceId&&a(t.startMinutes,t.endMinutes,o.startMinutes,o.endMinutes)&&(s+=o.requestedSpots)}return s},re=async()=>{const t=++O,s=k.value.map(_).filter(o=>!!o),c=s.reduce((o,f)=>(o[f.reservation.id]={status:"checking",message:"Checking availability..."},o),{});if(M.value=c,!h.value||s.length===0)return c;try{const o=Array.from(new Set(s.map(F=>`${F.resourceId}_${F.date}`))),f=await H(o);if(t!==O)return null;const i=s.reduce((F,A)=>{const y=j(f,A)+p(A),Q=A.capacity-y;return F[A.reservation.id]=d(Q,A.capacity,A.requestedSpots),F},{});return M.value=i,i}catch(o){if(t!==O)return null;console.error("Error checking new reservation availability:",o);const f=s.reduce((i,F)=>(i[F.reservation.id]={status:"error",message:"Could not check availability for this reservation."},i),{});return M.value=f,f}},J=t=>t?k.value.flatMap((s,c)=>{const o=t[s.id];return o?o.status==="unavailable"?[`${Y(c)}: ${o.message}`]:o.status==="error"?[`${Y(c)}: availability could not be checked.`]:[]:[]}):["Could not check availability before creating the reservation."];e.watch(h,async t=>{t?(B.value=[],X(),await e.nextTick(),G.value?.reset()):(O+=1,M.value={})}),e.watch(k,()=>{h.value&&re()},{deep:!0});const ge=()=>{const t=[];B.value=[];const s=G.value,c=s?s.validateForm():!1;return s||t.push("Customer information form is unavailable."),k.value.length===0&&t.push("Please add at least one reservation."),t.push(...m()),B.value=t,t.length===0&&c},ve=async()=>{const t=G.value;if(!t||!ge())return;const s=await re(),c=J(s);if(c.length>0){B.value=c;return}let o=!1;try{S.value=!0;const f=t.getCustomerInfo(),i=k.value.map(y=>{const Q=Number(y.paid)||0,ue=Number(y.spots)||1,de=te(y),ie=K(y),me=y.date;return{paidAmount:Q,flattenedReservationDate:`${y.resourceId}_${me}`,flattenedReservation:`${y.resourceId}_${me}_${y.startTime.replace(":","")}`,reservation:{status:"approved",totalPrice:Number(Q.toFixed(2)),basePrice:Number((Q/ue).toFixed(2)),addOnsPrice:0,addOns:[],date:me,id:`res_${Date.now()}_${Math.random().toString(36).substring(2,9)}`,pricingOption:{duration:de?.duration||"",id:de?.id||"",name:de?.name||"",price:de?.price||""},pricingOptionId:y.pricingOption,resource:{avatarLabel:ie?.avatarLabel||"",color:ie?.color||"",description:ie?.description||"",id:ie?.id||"",name:ie?.name||""},resourceId:y.resourceId,spots:ue,timeslot:{startTime:y.startTime,endTime:le(y)}}}}),F=Number(i.reduce((y,Q)=>y+Q.paidAmount,0).toFixed(2)),A={agendaId:E.value,customerInfo:f,metadata:{},amountPaid:F,amountDue:0,subtotal:F,total:F,createdAt:new Date,updatedAt:new Date,discount:0,flattenedReservationDates:Array.from(new Set(i.map(y=>y.flattenedReservationDate))),flattenedReservations:i.map(y=>y.flattenedReservation),paymentStatus:"paid",paymentType:"full",reservations:i.map(y=>y.reservation),status:"confirmed"};await V.add(L.reservationsCollection,A),o=!0,Z(`${i.length} ${i.length>1?"reservations":"reservation"} created in Studio`,{agendaId:E.value,reservationIds:i.map(y=>y.reservation.id),amountPaid:F,reservations:i.map(y=>`${y.reservation.resource.name}: ${y.reservation.date} ${y.reservation.timeslot.startTime}`)})}catch(f){R("Failed to create reservation in Studio",{error:f instanceof Error?f.message:String(f),agendaId:E.value}),console.error("Error creating reservation:",f)}finally{S.value=!1,o&&(h.value=!1)}};return(t,s)=>{const c=e.resolveComponent("Button"),o=e.resolveComponent("ResponsiveModalTrigger"),f=e.resolveComponent("ResponsiveModalTitle"),i=e.resolveComponent("ResponsiveModalHeader"),F=e.resolveComponent("ResponsiveModalFooter"),A=e.resolveComponent("ResponsiveModalScrollContent"),y=e.resolveComponent("ResponsiveModal");return e.openBlock(),e.createBlock(y,{open:h.value,"onUpdate:open":s[1]||(s[1]=Q=>h.value=Q)},{default:e.withCtx(()=>[e.createVNode(o,{"as-child":""},{default:e.withCtx(()=>[e.createVNode(c,null,{default:e.withCtx(()=>[e.createVNode(e.unref(ee.Plus),{class:"size-4"}),s[2]||(s[2]=e.createTextVNode(" Add Reservation ",-1))]),_:1})]),_:1}),e.createVNode(A,{class:"@container/modal sm:max-w-7xl"},{default:e.withCtx(()=>[e.createVNode(i,null,{default:e.withCtx(()=>[e.createVNode(f,null,{default:e.withCtx(()=>[...s[3]||(s[3]=[e.createTextVNode("Create new reservation",-1)])]),_:1})]),_:1}),e.createElementVNode("div",It,[e.createVNode(Te,{ref_key:"customerInformationRef",ref:G,agendaData:I.value},null,8,["agendaData"]),s[5]||(s[5]=e.createElementVNode("div",{class:"w-full h-[1px] bg-border my-8"},null,-1)),e.createElementVNode("div",Ft,[s[4]||(s[4]=e.createElementVNode("div",{class:"flex items-center justify-between gap-3"},[e.createElementVNode("h2",{class:"text-sm font-medium"},"Reservations")],-1)),e.createVNode(Rt,{modelValue:k.value,"onUpdate:modelValue":s[0]||(s[0]=Q=>k.value=Q),agendaData:I.value,"availability-by-reservation":M.value,onAdd:se,onQuickAdd:D},null,8,["modelValue","agendaData","availability-by-reservation"])]),e.createElementVNode("div",Ot,[e.createElementVNode("ul",Lt,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(B.value,Q=>(e.openBlock(),e.createElementBlock("li",{key:Q},e.toDisplayString(Q),1))),128))])])]),e.createVNode(F,{class:"gap-2"},{default:e.withCtx(()=>[e.createVNode(c,{onClick:ve,disabled:S.value||U.value||u.value},{default:e.withCtx(()=>[S.value?(e.openBlock(),e.createElementBlock("span",Mt,"Creating...")):U.value?(e.openBlock(),e.createElementBlock("span",At,"Checking availability...")):(e.openBlock(),e.createElementBlock("span",Pt,e.toDisplayString(k.value.length>1?`Create ${k.value.length} reservations`:"Create reservation"),1))]),_:1},8,["disabled"])]),_:1})]),_:1})]),_:1},8,["open"])}}});exports._sfc_main=Ut;
|