@zorgo/next 1.0.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 (64) hide show
  1. package/README.md +19 -0
  2. package/dist/cli.d.mts +5 -0
  3. package/dist/cli.d.ts +5 -0
  4. package/dist/cli.js +2 -0
  5. package/dist/cli.mjs +2 -0
  6. package/dist/components.d.mts +337 -0
  7. package/dist/components.d.ts +337 -0
  8. package/dist/components.js +1996 -0
  9. package/dist/components.js.map +1 -0
  10. package/dist/components.mjs +1962 -0
  11. package/dist/components.mjs.map +1 -0
  12. package/dist/index.d.mts +305 -0
  13. package/dist/index.d.ts +305 -0
  14. package/dist/index.js +2 -0
  15. package/dist/index.mjs +2 -0
  16. package/dist/seo.d.mts +30 -0
  17. package/dist/seo.d.ts +30 -0
  18. package/dist/seo.js +82 -0
  19. package/dist/seo.js.map +1 -0
  20. package/dist/seo.mjs +56 -0
  21. package/dist/seo.mjs.map +1 -0
  22. package/dist/slugs.d.mts +1 -0
  23. package/dist/slugs.d.ts +1 -0
  24. package/dist/slugs.js +47 -0
  25. package/dist/slugs.js.map +1 -0
  26. package/dist/slugs.mjs +19 -0
  27. package/dist/slugs.mjs.map +1 -0
  28. package/dist/tree/.env.gen.ts +27 -0
  29. package/dist/tree/README.md +0 -0
  30. package/dist/tree/app/api/zorgo-token/route.ts +11 -0
  31. package/dist/tree/app/apple-icon.tsx.gen.ts +54 -0
  32. package/dist/tree/app/checkout/page.tsx +10 -0
  33. package/dist/tree/app/components/Footer.tsx +50 -0
  34. package/dist/tree/app/components/Header.tsx +128 -0
  35. package/dist/tree/app/components/ModalHost.tsx +56 -0
  36. package/dist/tree/app/components/ModalRegistry.tsx +113 -0
  37. package/dist/tree/app/components/TestCard.tsx +35 -0
  38. package/dist/tree/app/components/index.ts +3 -0
  39. package/dist/tree/app/error.tsx +10 -0
  40. package/dist/tree/app/global-error.tsx +12 -0
  41. package/dist/tree/app/globals.css.gen.ts +123 -0
  42. package/dist/tree/app/icon.tsx.gen.ts +87 -0
  43. package/dist/tree/app/layout.tsx.gen.ts +55 -0
  44. package/dist/tree/app/locations/page.tsx +30 -0
  45. package/dist/tree/app/manifest.ts.gen.ts +39 -0
  46. package/dist/tree/app/menu/[slug]/ItemCustomizationClient.tsx +18 -0
  47. package/dist/tree/app/menu/[slug]/page.tsx +78 -0
  48. package/dist/tree/app/menu/page.tsx +36 -0
  49. package/dist/tree/app/not-found.tsx +8 -0
  50. package/dist/tree/app/opengraph-image.tsx.gen.ts +82 -0
  51. package/dist/tree/app/page.tsx +19 -0
  52. package/dist/tree/app/privacy/page.tsx.gen.ts +15 -0
  53. package/dist/tree/app/robots.ts +9 -0
  54. package/dist/tree/app/sitemap.ts +26 -0
  55. package/dist/tree/app/terms/page.tsx.gen.ts +16 -0
  56. package/dist/tree/gitignore +44 -0
  57. package/dist/tree/lib/zorgoSiteToken.ts +20 -0
  58. package/dist/tree/next.config.ts +14 -0
  59. package/dist/tree/open-next.config.ts +4 -0
  60. package/dist/tree/package.json.gen.ts +24 -0
  61. package/dist/tree/postcss.config.mjs +7 -0
  62. package/dist/tree/scripts/prebuild.ts +448 -0
  63. package/dist/tree/tsconfig.json +35 -0
  64. package/package.json +72 -0
@@ -0,0 +1,1962 @@
1
+ "use client";
2
+
3
+ // src/components/CookieConsent.tsx
4
+ import { useEffect as useEffect2, useState as useState2 } from "react";
5
+
6
+ // ../../node_modules/@headlessui/react/dist/utils/env.js
7
+ var i = Object.defineProperty;
8
+ var d = (t6, e, n3) => e in t6 ? i(t6, e, { enumerable: true, configurable: true, writable: true, value: n3 }) : t6[e] = n3;
9
+ var r = (t6, e, n3) => (d(t6, typeof e != "symbol" ? e + "" : e, n3), n3);
10
+ var o = class {
11
+ constructor() {
12
+ r(this, "current", this.detect());
13
+ r(this, "handoffState", "pending");
14
+ r(this, "currentId", 0);
15
+ }
16
+ set(e) {
17
+ this.current !== e && (this.handoffState = "pending", this.currentId = 0, this.current = e);
18
+ }
19
+ reset() {
20
+ this.set(this.detect());
21
+ }
22
+ nextId() {
23
+ return ++this.currentId;
24
+ }
25
+ get isServer() {
26
+ return this.current === "server";
27
+ }
28
+ get isClient() {
29
+ return this.current === "client";
30
+ }
31
+ detect() {
32
+ return typeof window == "undefined" || typeof document == "undefined" ? "server" : "client";
33
+ }
34
+ handoff() {
35
+ this.handoffState === "pending" && (this.handoffState = "complete");
36
+ }
37
+ get isHandoffComplete() {
38
+ return this.handoffState === "complete";
39
+ }
40
+ };
41
+ var s = new o();
42
+
43
+ // ../../node_modules/@headlessui/react/dist/hooks/use-disposables.js
44
+ import { useEffect as s2, useState as o3 } from "react";
45
+
46
+ // ../../node_modules/@headlessui/react/dist/utils/micro-task.js
47
+ function t(e) {
48
+ typeof queueMicrotask == "function" ? queueMicrotask(e) : Promise.resolve().then(e).catch((o5) => setTimeout(() => {
49
+ throw o5;
50
+ }));
51
+ }
52
+
53
+ // ../../node_modules/@headlessui/react/dist/utils/disposables.js
54
+ function o2() {
55
+ let s5 = [], r4 = { addEventListener(e, t6, n3, i4) {
56
+ return e.addEventListener(t6, n3, i4), r4.add(() => e.removeEventListener(t6, n3, i4));
57
+ }, requestAnimationFrame(...e) {
58
+ let t6 = requestAnimationFrame(...e);
59
+ return r4.add(() => cancelAnimationFrame(t6));
60
+ }, nextFrame(...e) {
61
+ return r4.requestAnimationFrame(() => r4.requestAnimationFrame(...e));
62
+ }, setTimeout(...e) {
63
+ let t6 = setTimeout(...e);
64
+ return r4.add(() => clearTimeout(t6));
65
+ }, microTask(...e) {
66
+ let t6 = { current: true };
67
+ return t(() => {
68
+ t6.current && e[0]();
69
+ }), r4.add(() => {
70
+ t6.current = false;
71
+ });
72
+ }, style(e, t6, n3) {
73
+ let i4 = e.style.getPropertyValue(t6);
74
+ return Object.assign(e.style, { [t6]: n3 }), this.add(() => {
75
+ Object.assign(e.style, { [t6]: i4 });
76
+ });
77
+ }, group(e) {
78
+ let t6 = o2();
79
+ return e(t6), this.add(() => t6.dispose());
80
+ }, add(e) {
81
+ return s5.includes(e) || s5.push(e), () => {
82
+ let t6 = s5.indexOf(e);
83
+ if (t6 >= 0) for (let n3 of s5.splice(t6, 1)) n3();
84
+ };
85
+ }, dispose() {
86
+ for (let e of s5.splice(0)) e();
87
+ } };
88
+ return r4;
89
+ }
90
+
91
+ // ../../node_modules/@headlessui/react/dist/hooks/use-disposables.js
92
+ function p() {
93
+ let [e] = o3(o2);
94
+ return s2(() => () => e.dispose(), [e]), e;
95
+ }
96
+
97
+ // ../../node_modules/@headlessui/react/dist/hooks/use-event.js
98
+ import a from "react";
99
+
100
+ // ../../node_modules/@headlessui/react/dist/hooks/use-latest-value.js
101
+ import { useRef as t2 } from "react";
102
+
103
+ // ../../node_modules/@headlessui/react/dist/hooks/use-iso-morphic-effect.js
104
+ import { useEffect as f, useLayoutEffect as c } from "react";
105
+ var n = (e, t6) => {
106
+ s.isServer ? f(e, t6) : c(e, t6);
107
+ };
108
+
109
+ // ../../node_modules/@headlessui/react/dist/hooks/use-latest-value.js
110
+ function s3(e) {
111
+ let r4 = t2(e);
112
+ return n(() => {
113
+ r4.current = e;
114
+ }, [e]), r4;
115
+ }
116
+
117
+ // ../../node_modules/@headlessui/react/dist/hooks/use-event.js
118
+ var o4 = function(t6) {
119
+ let e = s3(t6);
120
+ return a.useCallback((...r4) => e.current(...r4), [e]);
121
+ };
122
+
123
+ // ../../node_modules/@headlessui/react/dist/utils/render.js
124
+ import E, { Fragment as j, cloneElement as v, createElement as S, forwardRef as w, isValidElement as k, useCallback as x, useRef as M } from "react";
125
+
126
+ // ../../node_modules/@headlessui/react/dist/utils/class-names.js
127
+ function t3(...r4) {
128
+ return Array.from(new Set(r4.flatMap((n3) => typeof n3 == "string" ? n3.split(" ") : []))).filter(Boolean).join(" ");
129
+ }
130
+
131
+ // ../../node_modules/@headlessui/react/dist/utils/match.js
132
+ function u(r4, n3, ...a2) {
133
+ if (r4 in n3) {
134
+ let e = n3[r4];
135
+ return typeof e == "function" ? e(...a2) : e;
136
+ }
137
+ let t6 = new Error(`Tried to handle "${r4}" but there is no handler defined. Only defined handlers are: ${Object.keys(n3).map((e) => `"${e}"`).join(", ")}.`);
138
+ throw Error.captureStackTrace && Error.captureStackTrace(t6, u), t6;
139
+ }
140
+
141
+ // ../../node_modules/@headlessui/react/dist/utils/render.js
142
+ var A = ((a2) => (a2[a2.None = 0] = "None", a2[a2.RenderStrategy = 1] = "RenderStrategy", a2[a2.Static = 2] = "Static", a2))(A || {});
143
+ var C = ((e) => (e[e.Unmount = 0] = "Unmount", e[e.Hidden = 1] = "Hidden", e))(C || {});
144
+ function K() {
145
+ let n3 = $();
146
+ return x((r4) => U({ mergeRefs: n3, ...r4 }), [n3]);
147
+ }
148
+ function U({ ourProps: n3, theirProps: r4, slot: e, defaultTag: a2, features: s5, visible: t6 = true, name: l4, mergeRefs: i4 }) {
149
+ i4 = i4 != null ? i4 : I;
150
+ let o5 = P(r4, n3);
151
+ if (t6) return F(o5, e, a2, l4, i4);
152
+ let y2 = s5 != null ? s5 : 0;
153
+ if (y2 & 2) {
154
+ let { static: f3 = false, ...u4 } = o5;
155
+ if (f3) return F(u4, e, a2, l4, i4);
156
+ }
157
+ if (y2 & 1) {
158
+ let { unmount: f3 = true, ...u4 } = o5;
159
+ return u(f3 ? 0 : 1, { [0]() {
160
+ return null;
161
+ }, [1]() {
162
+ return F({ ...u4, hidden: true, style: { display: "none" } }, e, a2, l4, i4);
163
+ } });
164
+ }
165
+ return F(o5, e, a2, l4, i4);
166
+ }
167
+ function F(n3, r4 = {}, e, a2, s5) {
168
+ let { as: t6 = e, children: l4, refName: i4 = "ref", ...o5 } = h(n3, ["unmount", "static"]), y2 = n3.ref !== void 0 ? { [i4]: n3.ref } : {}, f3 = typeof l4 == "function" ? l4(r4) : l4;
169
+ "className" in o5 && o5.className && typeof o5.className == "function" && (o5.className = o5.className(r4)), o5["aria-labelledby"] && o5["aria-labelledby"] === o5.id && (o5["aria-labelledby"] = void 0);
170
+ let u4 = {};
171
+ if (r4) {
172
+ let d3 = false, p2 = [];
173
+ for (let [c6, T2] of Object.entries(r4)) typeof T2 == "boolean" && (d3 = true), T2 === true && p2.push(c6.replace(/([A-Z])/g, (g) => `-${g.toLowerCase()}`));
174
+ if (d3) {
175
+ u4["data-headlessui-state"] = p2.join(" ");
176
+ for (let c6 of p2) u4[`data-${c6}`] = "";
177
+ }
178
+ }
179
+ if (b(t6) && (Object.keys(m(o5)).length > 0 || Object.keys(m(u4)).length > 0)) if (!k(f3) || Array.isArray(f3) && f3.length > 1 || D(f3)) {
180
+ if (Object.keys(m(o5)).length > 0) throw new Error(['Passing props on "Fragment"!', "", `The current component <${a2} /> is rendering a "Fragment".`, "However we need to passthrough the following props:", Object.keys(m(o5)).concat(Object.keys(m(u4))).map((d3) => ` - ${d3}`).join(`
181
+ `), "", "You can apply a few solutions:", ['Add an `as="..."` prop, to ensure that we render an actual element instead of a "Fragment".', "Render a single element as the child so that we can forward the props onto that element."].map((d3) => ` - ${d3}`).join(`
182
+ `)].join(`
183
+ `));
184
+ } else {
185
+ let d3 = f3.props, p2 = d3 == null ? void 0 : d3.className, c6 = typeof p2 == "function" ? (...R) => t3(p2(...R), o5.className) : t3(p2, o5.className), T2 = c6 ? { className: c6 } : {}, g = P(f3.props, m(h(o5, ["ref"])));
186
+ for (let R in u4) R in g && delete u4[R];
187
+ return v(f3, Object.assign({}, g, u4, y2, { ref: s5(H(f3), y2.ref) }, T2));
188
+ }
189
+ return S(t6, Object.assign({}, h(o5, ["ref"]), !b(t6) && y2, !b(t6) && u4), f3);
190
+ }
191
+ function $() {
192
+ let n3 = M([]), r4 = x((e) => {
193
+ for (let a2 of n3.current) a2 != null && (typeof a2 == "function" ? a2(e) : a2.current = e);
194
+ }, []);
195
+ return (...e) => {
196
+ if (!e.every((a2) => a2 == null)) return n3.current = e, r4;
197
+ };
198
+ }
199
+ function I(...n3) {
200
+ return n3.every((r4) => r4 == null) ? void 0 : (r4) => {
201
+ for (let e of n3) e != null && (typeof e == "function" ? e(r4) : e.current = r4);
202
+ };
203
+ }
204
+ function P(...n3) {
205
+ var a2;
206
+ if (n3.length === 0) return {};
207
+ if (n3.length === 1) return n3[0];
208
+ let r4 = {}, e = {};
209
+ for (let s5 of n3) for (let t6 in s5) t6.startsWith("on") && typeof s5[t6] == "function" ? ((a2 = e[t6]) != null || (e[t6] = []), e[t6].push(s5[t6])) : r4[t6] = s5[t6];
210
+ if (r4.disabled || r4["aria-disabled"]) for (let s5 in e) /^(on(?:Click|Pointer|Mouse|Key)(?:Down|Up|Press)?)$/.test(s5) && (e[s5] = [(t6) => {
211
+ var l4;
212
+ return (l4 = t6 == null ? void 0 : t6.preventDefault) == null ? void 0 : l4.call(t6);
213
+ }]);
214
+ for (let s5 in e) Object.assign(r4, { [s5](t6, ...l4) {
215
+ let i4 = e[s5];
216
+ for (let o5 of i4) {
217
+ if ((t6 instanceof Event || (t6 == null ? void 0 : t6.nativeEvent) instanceof Event) && t6.defaultPrevented) return;
218
+ o5(t6, ...l4);
219
+ }
220
+ } });
221
+ return r4;
222
+ }
223
+ function Y(n3) {
224
+ var r4;
225
+ return Object.assign(w(n3), { displayName: (r4 = n3.displayName) != null ? r4 : n3.name });
226
+ }
227
+ function m(n3) {
228
+ let r4 = Object.assign({}, n3);
229
+ for (let e in r4) r4[e] === void 0 && delete r4[e];
230
+ return r4;
231
+ }
232
+ function h(n3, r4 = []) {
233
+ let e = Object.assign({}, n3);
234
+ for (let a2 of r4) a2 in e && delete e[a2];
235
+ return e;
236
+ }
237
+ function H(n3) {
238
+ return E.version.split(".")[0] >= "19" ? n3.props.ref : n3.ref;
239
+ }
240
+ function b(n3) {
241
+ return n3 === j || n3 === /* @__PURE__ */ Symbol.for("react.fragment");
242
+ }
243
+ function D(n3) {
244
+ return b(n3.type);
245
+ }
246
+
247
+ // ../../node_modules/@headlessui/react/dist/hooks/use-sync-refs.js
248
+ import { useEffect as l, useRef as i2 } from "react";
249
+ var u2 = /* @__PURE__ */ Symbol();
250
+ function y(...t6) {
251
+ let n3 = i2(t6);
252
+ l(() => {
253
+ n3.current = t6;
254
+ }, [t6]);
255
+ let c6 = o4((e) => {
256
+ for (let o5 of n3.current) o5 != null && (typeof o5 == "function" ? o5(e) : o5.current = e);
257
+ });
258
+ return t6.every((e) => e == null || (e == null ? void 0 : e[u2])) ? void 0 : c6;
259
+ }
260
+
261
+ // ../../node_modules/@headlessui/react/dist/hooks/use-transition.js
262
+ import { useRef as c3, useState as b3 } from "react";
263
+
264
+ // ../../node_modules/@headlessui/react/dist/hooks/use-flags.js
265
+ import { useCallback as t4, useState as b2 } from "react";
266
+ function c2(u4 = 0) {
267
+ let [r4, a2] = b2(u4), g = t4((e) => a2(e), []), s5 = t4((e) => a2((l4) => l4 | e), []), m2 = t4((e) => (r4 & e) === e, [r4]), n3 = t4((e) => a2((l4) => l4 & ~e), []), F2 = t4((e) => a2((l4) => l4 ^ e), []);
268
+ return { flags: r4, setFlag: g, addFlag: s5, hasFlag: m2, removeFlag: n3, toggleFlag: F2 };
269
+ }
270
+
271
+ // ../../node_modules/@headlessui/react/dist/hooks/use-transition.js
272
+ var T;
273
+ var S2;
274
+ typeof process != "undefined" && typeof globalThis != "undefined" && typeof Element != "undefined" && ((T = process == null ? void 0 : process.env) == null ? void 0 : T["NODE_ENV"]) === "test" && typeof ((S2 = Element == null ? void 0 : Element.prototype) == null ? void 0 : S2.getAnimations) == "undefined" && (Element.prototype.getAnimations = function() {
275
+ return console.warn(["Headless UI has polyfilled `Element.prototype.getAnimations` for your tests.", "Please install a proper polyfill e.g. `jsdom-testing-mocks`, to silence these warnings.", "", "Example usage:", "```js", "import { mockAnimationsApi } from 'jsdom-testing-mocks'", "mockAnimationsApi()", "```"].join(`
276
+ `)), [];
277
+ });
278
+ var A2 = ((i4) => (i4[i4.None = 0] = "None", i4[i4.Closed = 1] = "Closed", i4[i4.Enter = 2] = "Enter", i4[i4.Leave = 4] = "Leave", i4))(A2 || {});
279
+ function x2(e) {
280
+ let r4 = {};
281
+ for (let t6 in e) e[t6] === true && (r4[`data-${t6}`] = "");
282
+ return r4;
283
+ }
284
+ function N(e, r4, t6, n3) {
285
+ let [i4, a2] = b3(t6), { hasFlag: s5, addFlag: o5, removeFlag: l4 } = c2(e && i4 ? 3 : 0), u4 = c3(false), f3 = c3(false), E2 = p();
286
+ return n(() => {
287
+ var d3;
288
+ if (e) {
289
+ if (t6 && a2(true), !r4) {
290
+ t6 && o5(3);
291
+ return;
292
+ }
293
+ return (d3 = n3 == null ? void 0 : n3.start) == null || d3.call(n3, t6), C2(r4, { inFlight: u4, prepare() {
294
+ f3.current ? f3.current = false : f3.current = u4.current, u4.current = true, !f3.current && (t6 ? (o5(3), l4(4)) : (o5(4), l4(2)));
295
+ }, run() {
296
+ f3.current ? t6 ? (l4(3), o5(4)) : (l4(4), o5(3)) : t6 ? l4(1) : o5(1);
297
+ }, done() {
298
+ var p2;
299
+ f3.current && D2(r4) || (u4.current = false, l4(7), t6 || a2(false), (p2 = n3 == null ? void 0 : n3.end) == null || p2.call(n3, t6));
300
+ } });
301
+ }
302
+ }, [e, t6, r4, E2]), e ? [i4, { closed: s5(1), enter: s5(2), leave: s5(4), transition: s5(2) || s5(4) }] : [t6, { closed: void 0, enter: void 0, leave: void 0, transition: void 0 }];
303
+ }
304
+ function C2(e, { prepare: r4, run: t6, done: n3, inFlight: i4 }) {
305
+ let a2 = o2();
306
+ return j2(e, { prepare: r4, inFlight: i4 }), a2.nextFrame(() => {
307
+ t6(), a2.requestAnimationFrame(() => {
308
+ a2.add(M2(e, n3));
309
+ });
310
+ }), a2.dispose;
311
+ }
312
+ function M2(e, r4) {
313
+ var a2, s5;
314
+ let t6 = o2();
315
+ if (!e) return t6.dispose;
316
+ let n3 = false;
317
+ t6.add(() => {
318
+ n3 = true;
319
+ });
320
+ let i4 = (s5 = (a2 = e.getAnimations) == null ? void 0 : a2.call(e).filter((o5) => o5 instanceof CSSTransition)) != null ? s5 : [];
321
+ return i4.length === 0 ? (r4(), t6.dispose) : (Promise.allSettled(i4.map((o5) => o5.finished)).then(() => {
322
+ n3 || r4();
323
+ }), t6.dispose);
324
+ }
325
+ function j2(e, { inFlight: r4, prepare: t6 }) {
326
+ if (r4 != null && r4.current) {
327
+ t6();
328
+ return;
329
+ }
330
+ let n3 = e.style.transition;
331
+ e.style.transition = "none", t6(), e.offsetHeight, e.style.transition = n3;
332
+ }
333
+ function D2(e) {
334
+ var t6, n3;
335
+ return ((n3 = (t6 = e.getAnimations) == null ? void 0 : t6.call(e)) != null ? n3 : []).some((i4) => i4 instanceof CSSTransition && i4.playState !== "finished");
336
+ }
337
+
338
+ // ../../node_modules/@headlessui/react/dist/internal/open-closed.js
339
+ import r2, { createContext as l2, useContext as d2 } from "react";
340
+ var n2 = l2(null);
341
+ n2.displayName = "OpenClosedContext";
342
+ var i3 = ((e) => (e[e.Open = 1] = "Open", e[e.Closed = 2] = "Closed", e[e.Closing = 4] = "Closing", e[e.Opening = 8] = "Opening", e))(i3 || {});
343
+ function u3() {
344
+ return d2(n2);
345
+ }
346
+ function c4({ value: o5, children: t6 }) {
347
+ return r2.createElement(n2.Provider, { value: o5 }, t6);
348
+ }
349
+
350
+ // ../../node_modules/@headlessui/react/dist/hooks/use-server-handoff-complete.js
351
+ import * as t5 from "react";
352
+ function s4() {
353
+ let r4 = typeof document == "undefined";
354
+ return "useSyncExternalStore" in t5 ? ((o5) => o5.useSyncExternalStore)(t5)(() => () => {
355
+ }, () => false, () => !r4) : false;
356
+ }
357
+ function l3() {
358
+ let r4 = s4(), [e, n3] = t5.useState(s.isHandoffComplete);
359
+ return e && s.isHandoffComplete === false && n3(false), t5.useEffect(() => {
360
+ e !== true && n3(true);
361
+ }, [e]), t5.useEffect(() => s.handoff(), []), r4 ? false : e;
362
+ }
363
+
364
+ // ../../node_modules/@headlessui/react/dist/hooks/use-is-mounted.js
365
+ import { useRef as r3 } from "react";
366
+ function f2() {
367
+ let e = r3(false);
368
+ return n(() => (e.current = true, () => {
369
+ e.current = false;
370
+ }), []), e;
371
+ }
372
+
373
+ // ../../node_modules/@headlessui/react/dist/components/transition/transition.js
374
+ import c5, { Fragment as k2, createContext as ne, useContext as q, useEffect as ge, useMemo as ie, useRef as b4, useState as O } from "react";
375
+ function ue(e) {
376
+ var t6;
377
+ return !!(e.enter || e.enterFrom || e.enterTo || e.leave || e.leaveFrom || e.leaveTo) || !b((t6 = e.as) != null ? t6 : de) || c5.Children.count(e.children) === 1;
378
+ }
379
+ var V = ne(null);
380
+ V.displayName = "TransitionContext";
381
+ var De = ((n3) => (n3.Visible = "visible", n3.Hidden = "hidden", n3))(De || {});
382
+ function He() {
383
+ let e = q(V);
384
+ if (e === null) throw new Error("A <Transition.Child /> is used but it is missing a parent <Transition /> or <Transition.Root />.");
385
+ return e;
386
+ }
387
+ function Ae() {
388
+ let e = q(w2);
389
+ if (e === null) throw new Error("A <Transition.Child /> is used but it is missing a parent <Transition /> or <Transition.Root />.");
390
+ return e;
391
+ }
392
+ var w2 = ne(null);
393
+ w2.displayName = "NestingContext";
394
+ function M3(e) {
395
+ return "children" in e ? M3(e.children) : e.current.filter(({ el: t6 }) => t6.current !== null).filter(({ state: t6 }) => t6 === "visible").length > 0;
396
+ }
397
+ function Te(e, t6) {
398
+ let n3 = s3(e), l4 = b4([]), S3 = f2(), R = p(), d3 = o4((o5, i4 = C.Hidden) => {
399
+ let a2 = l4.current.findIndex(({ el: s5 }) => s5 === o5);
400
+ a2 !== -1 && (u(i4, { [C.Unmount]() {
401
+ l4.current.splice(a2, 1);
402
+ }, [C.Hidden]() {
403
+ l4.current[a2].state = "hidden";
404
+ } }), R.microTask(() => {
405
+ var s5;
406
+ !M3(l4) && S3.current && ((s5 = n3.current) == null || s5.call(n3));
407
+ }));
408
+ }), y2 = o4((o5) => {
409
+ let i4 = l4.current.find(({ el: a2 }) => a2 === o5);
410
+ return i4 ? i4.state !== "visible" && (i4.state = "visible") : l4.current.push({ el: o5, state: "visible" }), () => d3(o5, C.Unmount);
411
+ }), C3 = b4([]), p2 = b4(Promise.resolve()), h2 = b4({ enter: [], leave: [] }), g = o4((o5, i4, a2) => {
412
+ C3.current.splice(0), t6 && (t6.chains.current[i4] = t6.chains.current[i4].filter(([s5]) => s5 !== o5)), t6 == null || t6.chains.current[i4].push([o5, new Promise((s5) => {
413
+ C3.current.push(s5);
414
+ })]), t6 == null || t6.chains.current[i4].push([o5, new Promise((s5) => {
415
+ Promise.all(h2.current[i4].map(([r4, f3]) => f3)).then(() => s5());
416
+ })]), i4 === "enter" ? p2.current = p2.current.then(() => t6 == null ? void 0 : t6.wait.current).then(() => a2(i4)) : a2(i4);
417
+ }), v2 = o4((o5, i4, a2) => {
418
+ Promise.all(h2.current[i4].splice(0).map(([s5, r4]) => r4)).then(() => {
419
+ var s5;
420
+ (s5 = C3.current.shift()) == null || s5();
421
+ }).then(() => a2(i4));
422
+ });
423
+ return ie(() => ({ children: l4, register: y2, unregister: d3, onStart: g, onStop: v2, wait: p2, chains: h2 }), [y2, d3, l4, g, v2, h2, p2]);
424
+ }
425
+ var de = k2;
426
+ var fe = A.RenderStrategy;
427
+ function Fe(e, t6) {
428
+ var ee, te;
429
+ let { transition: n3 = true, beforeEnter: l4, afterEnter: S3, beforeLeave: R, afterLeave: d3, enter: y2, enterFrom: C3, enterTo: p2, entered: h2, leave: g, leaveFrom: v2, leaveTo: o5, ...i4 } = e, [a2, s5] = O(null), r4 = b4(null), f3 = ue(e), U2 = y(...f3 ? [r4, t6, s5] : t6 === null ? [] : [t6]), H2 = (ee = i4.unmount) == null || ee ? C.Unmount : C.Hidden, { show: u4, appear: z, initial: K2 } = He(), [m2, j3] = O(u4 ? "visible" : "hidden"), Q = Ae(), { register: A3, unregister: F2 } = Q;
430
+ n(() => A3(r4), [A3, r4]), n(() => {
431
+ if (H2 === C.Hidden && r4.current) {
432
+ if (u4 && m2 !== "visible") {
433
+ j3("visible");
434
+ return;
435
+ }
436
+ return u(m2, { ["hidden"]: () => F2(r4), ["visible"]: () => A3(r4) });
437
+ }
438
+ }, [m2, r4, A3, F2, u4, H2]);
439
+ let G = l3();
440
+ n(() => {
441
+ if (f3 && G && m2 === "visible" && r4.current === null) throw new Error("Did you forget to passthrough the `ref` to the actual DOM node?");
442
+ }, [r4, m2, G, f3]);
443
+ let ce = K2 && !z, Y2 = z && u4 && K2, B = b4(false), I2 = Te(() => {
444
+ B.current || (j3("hidden"), F2(r4));
445
+ }, Q), Z = o4((W) => {
446
+ B.current = true;
447
+ let L = W ? "enter" : "leave";
448
+ I2.onStart(r4, L, (_) => {
449
+ _ === "enter" ? l4 == null || l4() : _ === "leave" && (R == null || R());
450
+ });
451
+ }), $2 = o4((W) => {
452
+ let L = W ? "enter" : "leave";
453
+ B.current = false, I2.onStop(r4, L, (_) => {
454
+ _ === "enter" ? S3 == null || S3() : _ === "leave" && (d3 == null || d3());
455
+ }), L === "leave" && !M3(I2) && (j3("hidden"), F2(r4));
456
+ });
457
+ ge(() => {
458
+ f3 && n3 || (Z(u4), $2(u4));
459
+ }, [u4, f3, n3]);
460
+ let pe = /* @__PURE__ */ (() => !(!n3 || !f3 || !G || ce))(), [, T2] = N(pe, a2, u4, { start: Z, end: $2 }), Ce = m({ ref: U2, className: ((te = t3(i4.className, Y2 && y2, Y2 && C3, T2.enter && y2, T2.enter && T2.closed && C3, T2.enter && !T2.closed && p2, T2.leave && g, T2.leave && !T2.closed && v2, T2.leave && T2.closed && o5, !T2.transition && u4 && h2)) == null ? void 0 : te.trim()) || void 0, ...x2(T2) }), N2 = 0;
461
+ m2 === "visible" && (N2 |= i3.Open), m2 === "hidden" && (N2 |= i3.Closed), u4 && m2 === "hidden" && (N2 |= i3.Opening), !u4 && m2 === "visible" && (N2 |= i3.Closing);
462
+ let he = K();
463
+ return c5.createElement(w2.Provider, { value: I2 }, c5.createElement(c4, { value: N2 }, he({ ourProps: Ce, theirProps: i4, defaultTag: de, features: fe, visible: m2 === "visible", name: "Transition.Child" })));
464
+ }
465
+ function Ie(e, t6) {
466
+ let { show: n3, appear: l4 = false, unmount: S3 = true, ...R } = e, d3 = b4(null), y2 = ue(e), C3 = y(...y2 ? [d3, t6] : t6 === null ? [] : [t6]);
467
+ l3();
468
+ let p2 = u3();
469
+ if (n3 === void 0 && p2 !== null && (n3 = (p2 & i3.Open) === i3.Open), n3 === void 0) throw new Error("A <Transition /> is used but it is missing a `show={true | false}` prop.");
470
+ let [h2, g] = O(n3 ? "visible" : "hidden"), v2 = Te(() => {
471
+ n3 || g("hidden");
472
+ }), [o5, i4] = O(true), a2 = b4([n3]);
473
+ n(() => {
474
+ o5 !== false && a2.current[a2.current.length - 1] !== n3 && (a2.current.push(n3), i4(false));
475
+ }, [a2, n3]);
476
+ let s5 = ie(() => ({ show: n3, appear: l4, initial: o5 }), [n3, l4, o5]);
477
+ n(() => {
478
+ n3 ? g("visible") : !M3(v2) && d3.current !== null && g("hidden");
479
+ }, [n3, v2]);
480
+ let r4 = { unmount: S3 }, f3 = o4(() => {
481
+ var u4;
482
+ o5 && i4(false), (u4 = e.beforeEnter) == null || u4.call(e);
483
+ }), U2 = o4(() => {
484
+ var u4;
485
+ o5 && i4(false), (u4 = e.beforeLeave) == null || u4.call(e);
486
+ }), H2 = K();
487
+ return c5.createElement(w2.Provider, { value: v2 }, c5.createElement(V.Provider, { value: s5 }, H2({ ourProps: { ...r4, as: k2, children: c5.createElement(me, { ref: C3, ...r4, ...R, beforeEnter: f3, beforeLeave: U2 }) }, theirProps: {}, defaultTag: k2, features: fe, visible: h2 === "visible", name: "Transition" })));
488
+ }
489
+ function Le(e, t6) {
490
+ let n3 = q(V) !== null, l4 = u3() !== null;
491
+ return c5.createElement(c5.Fragment, null, !n3 && l4 ? c5.createElement(X, { ref: t6, ...e }) : c5.createElement(me, { ref: t6, ...e }));
492
+ }
493
+ var X = Y(Ie);
494
+ var me = Y(Fe);
495
+ var Oe = Y(Le);
496
+ var Ke = Object.assign(X, { Child: Oe, Root: X });
497
+
498
+ // src/components/CookieConsent.tsx
499
+ import { useCustomer } from "@zorgo/next";
500
+ import { jsx, jsxs } from "react/jsx-runtime";
501
+ function CookieConsent() {
502
+ const { consentAnswered, setConsent } = useCustomer();
503
+ const [mounted, setMounted] = useState2(false);
504
+ useEffect2(() => {
505
+ setMounted(true);
506
+ }, []);
507
+ if (!mounted) return null;
508
+ return /* @__PURE__ */ jsx(
509
+ Ke,
510
+ {
511
+ show: !consentAnswered,
512
+ enter: "transition-opacity duration-300",
513
+ enterFrom: "opacity-0",
514
+ enterTo: "opacity-100",
515
+ leave: "transition-opacity duration-200",
516
+ leaveFrom: "opacity-100",
517
+ leaveTo: "opacity-0",
518
+ children: /* @__PURE__ */ jsxs(
519
+ "div",
520
+ {
521
+ className: "fixed inset-x-0 bottom-0 z-[9999] flex flex-col items-center justify-center gap-4 bg-black/85 px-6 py-4 text-center text-sm text-white backdrop-blur md:flex-row",
522
+ role: "alert",
523
+ "aria-live": "polite",
524
+ children: [
525
+ /* @__PURE__ */ jsx("p", { className: "m-0", children: "We use cookies to improve your experience and collect anonymous usage data." }),
526
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-wrap items-center justify-center gap-2", children: [
527
+ /* @__PURE__ */ jsx(
528
+ "button",
529
+ {
530
+ type: "button",
531
+ className: "whitespace-nowrap rounded-md px-4 py-2 text-sm font-medium text-zinc-500 hover:border-zinc-600 hover:bg-zinc-900 hover:text-zinc-400",
532
+ onClick: () => setConsent(false),
533
+ children: "Reject"
534
+ }
535
+ ),
536
+ /* @__PURE__ */ jsx(
537
+ "button",
538
+ {
539
+ type: "button",
540
+ className: "whitespace-nowrap rounded-md bg-white px-5 py-2 text-sm font-semibold text-black transition-colors hover:bg-gray-400",
541
+ onClick: () => setConsent(true),
542
+ children: "Accept"
543
+ }
544
+ )
545
+ ] })
546
+ ]
547
+ }
548
+ )
549
+ }
550
+ );
551
+ }
552
+
553
+ // src/components/Breadcrumbs.tsx
554
+ import Link from "next/link";
555
+ import { ChevronRight } from "lucide-react";
556
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
557
+ function cn(...parts) {
558
+ return parts.filter(Boolean).join(" ");
559
+ }
560
+ var BREADCRUMBS_DEFAULT_ITEM_CLASSES = {
561
+ baseContainer: "flex flex-row items-center gap-2 text-sm opacity-75",
562
+ crumbLink: "hover:opacity-75 transition-all duration-300 underline-offset-2 hover:underline",
563
+ crumbText: "font-semibold",
564
+ separator: "h-4 w-4 opacity-50"
565
+ };
566
+ function mergeBreadcrumbsItemClasses(overrides) {
567
+ const d3 = BREADCRUMBS_DEFAULT_ITEM_CLASSES;
568
+ return {
569
+ baseContainer: cn(d3.baseContainer, overrides?.baseContainer),
570
+ crumbLink: cn(d3.crumbLink, overrides?.crumbLink),
571
+ crumbText: cn(d3.crumbText, overrides?.crumbText),
572
+ separator: cn(d3.separator, overrides?.separator)
573
+ };
574
+ }
575
+ function Breadcrumbs({
576
+ items,
577
+ itemClasses
578
+ }) {
579
+ const slots = mergeBreadcrumbsItemClasses(itemClasses);
580
+ return /* @__PURE__ */ jsx2("nav", { "aria-label": "Breadcrumb", className: slots.baseContainer, children: items.map((item, index) => /* @__PURE__ */ jsxs2("span", { className: "flex flex-row items-center gap-2", children: [
581
+ index > 0 && /* @__PURE__ */ jsx2(ChevronRight, { className: slots.separator }),
582
+ item.href ? /* @__PURE__ */ jsx2(Link, { href: item.href, className: slots.crumbLink, children: item.label }) : /* @__PURE__ */ jsx2("span", { className: slots.crumbText, children: item.label })
583
+ ] }, `${item.label}-${index}`)) });
584
+ }
585
+
586
+ // src/components/GridMenu.tsx
587
+ import Link2 from "next/link";
588
+ import { useMenu } from "@zorgo/next";
589
+ import { menuItemSlug } from "@zorgo/next/slugs";
590
+ import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
591
+ function cn2(...parts) {
592
+ return parts.filter(Boolean).join(" ");
593
+ }
594
+ function money(cents) {
595
+ return `$${(cents / 100).toFixed(2)}`;
596
+ }
597
+ var GRID_MENU_DEFAULT_ITEM_CLASSES = {
598
+ baseContainer: "flex flex-col gap-16",
599
+ categoryContainer: "flex flex-col gap-8",
600
+ categoryTitle: "text-4xl text-center font-extrabold text-primary",
601
+ itemCardContainer: "flex flex-row flex-wrap gap-8 content-center justify-center py-4 max-w-7xl mx-auto",
602
+ itemCard: "flex flex-col gap-4 no-underline w-60 hover:translate-y-[-2px] hover:opacity-75 transition-all duration-300",
603
+ itemCardImage: "w-full aspect-square bg-background-recessed rounded-2xl overflow-hidden",
604
+ itemCardTextContainer: "flex flex-col opacity-75 px-4 w-full",
605
+ itemCardName: "text-xl font-semibold",
606
+ itemCardPrice: "text-lg",
607
+ itemCardOldPrice: "text-lg line-through opacity-60"
608
+ };
609
+ function mergeGridMenuItemClasses(overrides) {
610
+ const d3 = GRID_MENU_DEFAULT_ITEM_CLASSES;
611
+ return {
612
+ baseContainer: cn2(d3.baseContainer, overrides?.baseContainer),
613
+ categoryContainer: cn2(
614
+ d3.categoryContainer,
615
+ overrides?.categoryContainer
616
+ ),
617
+ categoryTitle: cn2(d3.categoryTitle, overrides?.categoryTitle),
618
+ itemCardContainer: cn2(
619
+ d3.itemCardContainer,
620
+ overrides?.itemCardContainer
621
+ ),
622
+ itemCard: cn2(d3.itemCard, overrides?.itemCard),
623
+ itemCardImage: cn2(d3.itemCardImage, overrides?.itemCardImage),
624
+ itemCardTextContainer: cn2(
625
+ d3.itemCardTextContainer,
626
+ overrides?.itemCardTextContainer
627
+ ),
628
+ itemCardName: cn2(d3.itemCardName, overrides?.itemCardName),
629
+ itemCardPrice: cn2(d3.itemCardPrice, overrides?.itemCardPrice),
630
+ itemCardOldPrice: cn2(d3.itemCardOldPrice, overrides?.itemCardOldPrice)
631
+ };
632
+ }
633
+ function GridMenu({
634
+ items,
635
+ categories,
636
+ itemClasses
637
+ }) {
638
+ const { getItemImageUrl } = useMenu();
639
+ const slots = mergeGridMenuItemClasses(itemClasses);
640
+ return /* @__PURE__ */ jsx3("div", { className: slots.baseContainer, children: categories.map((category) => {
641
+ const itemsInCategory = items.filter(
642
+ (item) => item.category_id === category.category_id
643
+ );
644
+ if (itemsInCategory.length === 0) {
645
+ return null;
646
+ }
647
+ return /* @__PURE__ */ jsxs3(
648
+ "div",
649
+ {
650
+ className: slots.categoryContainer,
651
+ children: [
652
+ /* @__PURE__ */ jsx3("h1", { className: slots.categoryTitle, children: category.name }),
653
+ /* @__PURE__ */ jsx3("div", { className: slots.itemCardContainer, children: itemsInCategory.map((item) => /* @__PURE__ */ jsx3(
654
+ ItemCard,
655
+ {
656
+ item,
657
+ imageUrl: getItemImageUrl(item.image_path),
658
+ slots
659
+ },
660
+ item.base_item_id
661
+ )) })
662
+ ]
663
+ },
664
+ category.category_id
665
+ );
666
+ }) });
667
+ }
668
+ function ItemCard({
669
+ item,
670
+ imageUrl,
671
+ slots
672
+ }) {
673
+ const variant = item.variants[0];
674
+ const onSale = variant?.display_price != null && variant.display_price < variant.price;
675
+ return /* @__PURE__ */ jsxs3(
676
+ Link2,
677
+ {
678
+ href: `/menu/${menuItemSlug(item.name, item.base_item_id)}`,
679
+ className: slots.itemCard,
680
+ children: [
681
+ /* @__PURE__ */ jsx3("div", { className: slots.itemCardImage, children: imageUrl && // eslint-disable-next-line @next/next/no-img-element
682
+ /* @__PURE__ */ jsx3(
683
+ "img",
684
+ {
685
+ src: imageUrl,
686
+ alt: item.name,
687
+ className: "w-full h-full object-cover"
688
+ }
689
+ ) }),
690
+ /* @__PURE__ */ jsxs3("div", { className: slots.itemCardTextContainer, children: [
691
+ /* @__PURE__ */ jsx3("p", { className: slots.itemCardName, children: item.name }),
692
+ variant && /* @__PURE__ */ jsx3(Fragment, { children: onSale ? /* @__PURE__ */ jsxs3(Fragment, { children: [
693
+ /* @__PURE__ */ jsx3("p", { className: slots.itemCardPrice, children: money(variant.display_price) }),
694
+ /* @__PURE__ */ jsx3("p", { className: slots.itemCardOldPrice, children: money(variant.price) })
695
+ ] }) : /* @__PURE__ */ jsx3("p", { className: slots.itemCardPrice, children: money(variant.price) }) })
696
+ ] })
697
+ ]
698
+ }
699
+ );
700
+ }
701
+
702
+ // src/components/AccordionMenu.tsx
703
+ import Link3 from "next/link";
704
+ import { useState as useState3 } from "react";
705
+ import { ChevronDown, ChevronUp } from "lucide-react";
706
+ import { menuItemSlug as menuItemSlug2 } from "@zorgo/next/slugs";
707
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
708
+ function cn3(...parts) {
709
+ return parts.filter(Boolean).join(" ");
710
+ }
711
+ function money2(cents) {
712
+ return `$${(cents / 100).toFixed(2)}`;
713
+ }
714
+ var ACCORDION_MENU_DEFAULT_ITEM_CLASSES = {
715
+ baseContainer: "flex flex-col gap-4",
716
+ categoryContainer: "flex flex-col gap-4 p-4 bg-background-elevated border-3 border-foreground/[15%] rounded-xl shadow-sm",
717
+ categoryTrigger: "flex flex-row items-center justify-between p-4",
718
+ categoryTitle: "text-2xl font-bold",
719
+ categoryIndicator: "h-8 w-8",
720
+ itemsContainer: "flex-col gap-4",
721
+ itemCard: "flex items-center justify-between gap-4 p-4 bg-background rounded-xl hover:translate-x-1 transition-all duration-300",
722
+ itemCardTextContainer: "flex flex-col gap-2 opacity-75",
723
+ itemCardName: "text-lg font-semibold",
724
+ itemCardDescription: "text-lg opacity-75",
725
+ itemCardPriceContainer: "flex flex-col gap-2 opacity-75",
726
+ itemCardPrice: "text-lg font-semibold",
727
+ itemCardOldPrice: "text-lg opacity-75 line-through"
728
+ };
729
+ function mergeAccordionMenuItemClasses(overrides) {
730
+ const d3 = ACCORDION_MENU_DEFAULT_ITEM_CLASSES;
731
+ return {
732
+ baseContainer: cn3(d3.baseContainer, overrides?.baseContainer),
733
+ categoryContainer: cn3(
734
+ d3.categoryContainer,
735
+ overrides?.categoryContainer
736
+ ),
737
+ categoryTrigger: cn3(d3.categoryTrigger, overrides?.categoryTrigger),
738
+ categoryTitle: cn3(d3.categoryTitle, overrides?.categoryTitle),
739
+ categoryIndicator: cn3(
740
+ d3.categoryIndicator,
741
+ overrides?.categoryIndicator
742
+ ),
743
+ itemsContainer: cn3(d3.itemsContainer, overrides?.itemsContainer),
744
+ itemCard: cn3(d3.itemCard, overrides?.itemCard),
745
+ itemCardTextContainer: cn3(
746
+ d3.itemCardTextContainer,
747
+ overrides?.itemCardTextContainer
748
+ ),
749
+ itemCardName: cn3(d3.itemCardName, overrides?.itemCardName),
750
+ itemCardDescription: cn3(
751
+ d3.itemCardDescription,
752
+ overrides?.itemCardDescription
753
+ ),
754
+ itemCardPriceContainer: cn3(
755
+ d3.itemCardPriceContainer,
756
+ overrides?.itemCardPriceContainer
757
+ ),
758
+ itemCardPrice: cn3(d3.itemCardPrice, overrides?.itemCardPrice),
759
+ itemCardOldPrice: cn3(d3.itemCardOldPrice, overrides?.itemCardOldPrice)
760
+ };
761
+ }
762
+ function AccordionMenu({
763
+ items,
764
+ categories,
765
+ itemClasses
766
+ }) {
767
+ const slots = mergeAccordionMenuItemClasses(itemClasses);
768
+ return /* @__PURE__ */ jsx4("div", { className: slots.baseContainer, children: categories.map((category) => {
769
+ const itemsInCategory = items.filter(
770
+ (item) => item.category_id === category.category_id
771
+ );
772
+ if (itemsInCategory.length === 0) {
773
+ return null;
774
+ }
775
+ return /* @__PURE__ */ jsx4(
776
+ MenuCategory,
777
+ {
778
+ category,
779
+ itemsInCategory,
780
+ slots
781
+ },
782
+ category.category_id
783
+ );
784
+ }) });
785
+ }
786
+ function MenuCategory({
787
+ category,
788
+ itemsInCategory,
789
+ slots
790
+ }) {
791
+ const [isExpanded, setIsExpanded] = useState3(false);
792
+ return /* @__PURE__ */ jsxs4("div", { className: slots.categoryContainer, children: [
793
+ /* @__PURE__ */ jsxs4(
794
+ "button",
795
+ {
796
+ type: "button",
797
+ onClick: () => setIsExpanded(!isExpanded),
798
+ className: slots.categoryTrigger,
799
+ children: [
800
+ /* @__PURE__ */ jsx4("h2", { className: slots.categoryTitle, children: category.name }),
801
+ isExpanded ? /* @__PURE__ */ jsx4(ChevronUp, { className: slots.categoryIndicator }) : /* @__PURE__ */ jsx4(ChevronDown, { className: slots.categoryIndicator })
802
+ ]
803
+ }
804
+ ),
805
+ /* @__PURE__ */ jsx4(
806
+ "div",
807
+ {
808
+ className: cn3(
809
+ isExpanded ? "flex" : "hidden",
810
+ slots.itemsContainer
811
+ ),
812
+ children: itemsInCategory.map((item) => /* @__PURE__ */ jsx4(
813
+ ItemCard2,
814
+ {
815
+ item,
816
+ slots
817
+ },
818
+ item.base_item_id
819
+ ))
820
+ }
821
+ )
822
+ ] });
823
+ }
824
+ function ItemCard2({
825
+ item,
826
+ slots
827
+ }) {
828
+ const variant = item.variants[0];
829
+ const onSale = variant?.display_price != null && variant.display_price < variant.price;
830
+ return /* @__PURE__ */ jsxs4(
831
+ Link3,
832
+ {
833
+ href: `/menu/${menuItemSlug2(item.name, item.base_item_id)}`,
834
+ className: slots.itemCard,
835
+ children: [
836
+ /* @__PURE__ */ jsxs4("div", { className: slots.itemCardTextContainer, children: [
837
+ /* @__PURE__ */ jsx4("p", { className: slots.itemCardName, children: item.name }),
838
+ item.description && /* @__PURE__ */ jsx4("p", { className: slots.itemCardDescription, children: item.description })
839
+ ] }),
840
+ variant && /* @__PURE__ */ jsx4("div", { className: slots.itemCardPriceContainer, children: onSale ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
841
+ /* @__PURE__ */ jsx4("p", { className: slots.itemCardPrice, children: money2(variant.display_price) }),
842
+ /* @__PURE__ */ jsx4("p", { className: slots.itemCardOldPrice, children: money2(variant.price) })
843
+ ] }) : /* @__PURE__ */ jsx4("p", { className: slots.itemCardPrice, children: money2(variant.price) }) })
844
+ ]
845
+ }
846
+ );
847
+ }
848
+
849
+ // src/components/ItemCustomizationForm.tsx
850
+ import { Minus, Plus } from "lucide-react";
851
+ import { useItemCustomization, useMenu as useMenu2 } from "@zorgo/next";
852
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
853
+ function cn4(...parts) {
854
+ return parts.filter(Boolean).join(" ");
855
+ }
856
+ function money3(cents) {
857
+ return `$${(cents / 100).toFixed(2)}`;
858
+ }
859
+ var ITEM_CUSTOMIZATION_FORM_DEFAULT_ITEM_CLASSES = {
860
+ baseContainer: "flex flex-col gap-8",
861
+ title: "text-4xl font-extrabold text-primary",
862
+ description: "opacity-70 text-xl",
863
+ section: "flex flex-col gap-2 shadow-sm rounded-xl p-4 bg-background-elevated border-3 border-foreground/[15%]",
864
+ sectionTitle: "font-bold text-2xl py-4",
865
+ optionsRow: "flex flex-row flex-wrap gap-2",
866
+ optionButton: "flex flex-col items-start gap-0.5 p-3 px-4 rounded-xl border-3 text-lg hover:translate-y-[-2px] transition-all duration-300",
867
+ optionButtonSelected: "bg-background-recessed border-transparent",
868
+ optionButtonUnselected: "bg-background-elevated border-foreground/[15%]",
869
+ optionButtonLabel: "font-semibold leading-tight",
870
+ optionButtonUpcharge: "opacity-60",
871
+ servingsRow: "flex flex-row items-center justify-between gap-4 text-xl",
872
+ servingsLabel: "opacity-75",
873
+ servingsControls: "flex flex-row items-center gap-2",
874
+ incrementButton: "bg-background text-foreground w-10 h-10 rounded-xl flex items-center justify-center hover:bg-foreground hover:text-background transition-all duration-300",
875
+ servingsValue: "w-8 md:w-12 font-semibold opacity-75 text-center",
876
+ ruleError: "text-sm text-red-500",
877
+ commentsTextarea: "p-4 rounded-xl border-3 border-foreground/[15%] outline-none resize-none",
878
+ quantityRow: "flex flex-row items-center gap-4 text-xl",
879
+ submitButton: "bg-primary text-primary-foreground p-4 rounded-xl text-lg font-semibold hover:bg-primary/80 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-300",
880
+ notFound: ""
881
+ };
882
+ function mergeItemCustomizationFormItemClasses(overrides) {
883
+ const d3 = ITEM_CUSTOMIZATION_FORM_DEFAULT_ITEM_CLASSES;
884
+ return {
885
+ baseContainer: cn4(d3.baseContainer, overrides?.baseContainer),
886
+ title: cn4(d3.title, overrides?.title),
887
+ description: cn4(d3.description, overrides?.description),
888
+ section: cn4(d3.section, overrides?.section),
889
+ sectionTitle: cn4(d3.sectionTitle, overrides?.sectionTitle),
890
+ optionsRow: cn4(d3.optionsRow, overrides?.optionsRow),
891
+ optionButton: cn4(d3.optionButton, overrides?.optionButton),
892
+ optionButtonSelected: cn4(
893
+ d3.optionButtonSelected,
894
+ overrides?.optionButtonSelected
895
+ ),
896
+ optionButtonUnselected: cn4(
897
+ d3.optionButtonUnselected,
898
+ overrides?.optionButtonUnselected
899
+ ),
900
+ optionButtonLabel: cn4(
901
+ d3.optionButtonLabel,
902
+ overrides?.optionButtonLabel
903
+ ),
904
+ optionButtonUpcharge: cn4(
905
+ d3.optionButtonUpcharge,
906
+ overrides?.optionButtonUpcharge
907
+ ),
908
+ servingsRow: cn4(d3.servingsRow, overrides?.servingsRow),
909
+ servingsLabel: cn4(d3.servingsLabel, overrides?.servingsLabel),
910
+ servingsControls: cn4(d3.servingsControls, overrides?.servingsControls),
911
+ incrementButton: cn4(d3.incrementButton, overrides?.incrementButton),
912
+ servingsValue: cn4(d3.servingsValue, overrides?.servingsValue),
913
+ ruleError: cn4(d3.ruleError, overrides?.ruleError),
914
+ commentsTextarea: cn4(d3.commentsTextarea, overrides?.commentsTextarea),
915
+ quantityRow: cn4(d3.quantityRow, overrides?.quantityRow),
916
+ submitButton: cn4(d3.submitButton, overrides?.submitButton),
917
+ notFound: cn4(d3.notFound, overrides?.notFound)
918
+ };
919
+ }
920
+ function ItemCustomizationForm({
921
+ baseItemId,
922
+ seed,
923
+ editIndex,
924
+ itemClasses,
925
+ onSubmitSuccess
926
+ }) {
927
+ const slots = mergeItemCustomizationFormItemClasses(itemClasses);
928
+ const {
929
+ item,
930
+ variant,
931
+ variants,
932
+ setVariant,
933
+ ruleGroups,
934
+ unmetRule,
935
+ canSubmit,
936
+ submit,
937
+ quantity,
938
+ setQuantity,
939
+ comments,
940
+ setComments,
941
+ setComponentServings,
942
+ price,
943
+ salePrice,
944
+ isEditMode,
945
+ draft
946
+ } = useItemCustomization(baseItemId, seed, editIndex);
947
+ const { categories } = useMenu2();
948
+ if (!item) {
949
+ return /* @__PURE__ */ jsx5("div", { className: slots.notFound, children: "Item not found." });
950
+ }
951
+ const category = categories.find(
952
+ (c6) => c6.category_id === item.category_id
953
+ );
954
+ return /* @__PURE__ */ jsxs5("div", { className: slots.baseContainer, children: [
955
+ /* @__PURE__ */ jsx5(
956
+ Breadcrumbs,
957
+ {
958
+ items: [
959
+ { label: "Menu", href: "/menu" },
960
+ ...category ? [{ label: category.name }] : [],
961
+ { label: item.name }
962
+ ]
963
+ }
964
+ ),
965
+ /* @__PURE__ */ jsx5("h1", { className: slots.title, children: item.name }),
966
+ item.description && /* @__PURE__ */ jsx5("p", { className: slots.description, children: item.description }),
967
+ variants.length > 1 && /* @__PURE__ */ jsxs5("div", { className: slots.section, children: [
968
+ /* @__PURE__ */ jsx5("h2", { className: slots.sectionTitle, children: "Variants" }),
969
+ /* @__PURE__ */ jsx5("div", { className: slots.optionsRow, children: variants.map((v2) => /* @__PURE__ */ jsx5(
970
+ OptionButton,
971
+ {
972
+ label: v2.name,
973
+ subtext: money3(v2.price),
974
+ selected: v2.item_id === variant.item_id,
975
+ onClick: () => setVariant(v2),
976
+ slots
977
+ },
978
+ v2.item_id
979
+ )) })
980
+ ] }),
981
+ (variant.components?.length ?? 0) > 0 && /* @__PURE__ */ jsxs5("div", { className: slots.section, children: [
982
+ /* @__PURE__ */ jsx5("h2", { className: slots.sectionTitle, children: "Includes" }),
983
+ /* @__PURE__ */ jsx5("div", { className: slots.optionsRow, children: variant.components.map((component) => {
984
+ const defaultServings = component.servings_per_item ?? 1;
985
+ const servings = draft?.components?.find(
986
+ (c6) => c6.id === component.id
987
+ )?.quantity_servings ?? defaultServings;
988
+ const selected = servings > 0;
989
+ return /* @__PURE__ */ jsx5(
990
+ OptionButton,
991
+ {
992
+ label: component.name,
993
+ selected,
994
+ onClick: () => setComponentServings(
995
+ component.id,
996
+ selected ? 0 : defaultServings
997
+ ),
998
+ slots
999
+ },
1000
+ component.id
1001
+ );
1002
+ }) })
1003
+ ] }),
1004
+ ruleGroups.map((rule) => /* @__PURE__ */ jsxs5("div", { className: slots.section, children: [
1005
+ /* @__PURE__ */ jsx5("h2", { className: slots.sectionTitle, children: rule.group_name }),
1006
+ /* @__PURE__ */ jsx5("div", { className: slots.optionsRow, children: rule.options.map((option) => /* @__PURE__ */ jsx5(
1007
+ OptionButton,
1008
+ {
1009
+ label: option.name,
1010
+ subtext: option.upcharge > 0 ? `+${money3(option.upcharge)}` : void 0,
1011
+ selected: option.selected,
1012
+ onClick: option.toggle,
1013
+ slots
1014
+ },
1015
+ option.key
1016
+ )) }),
1017
+ rule.message() && /* @__PURE__ */ jsx5("p", { className: slots.ruleError, children: rule.message() })
1018
+ ] }, rule.rule_id)),
1019
+ /* @__PURE__ */ jsxs5("div", { className: slots.section, children: [
1020
+ /* @__PURE__ */ jsx5("h2", { className: slots.sectionTitle, children: "Comments" }),
1021
+ /* @__PURE__ */ jsx5(
1022
+ "textarea",
1023
+ {
1024
+ value: comments,
1025
+ onChange: (e) => setComments(e.target.value),
1026
+ placeholder: "Special instructions...",
1027
+ className: slots.commentsTextarea,
1028
+ rows: 2
1029
+ }
1030
+ )
1031
+ ] }),
1032
+ /* @__PURE__ */ jsxs5("div", { className: slots.section, children: [
1033
+ /* @__PURE__ */ jsx5("h2", { className: slots.sectionTitle, children: "How many?" }),
1034
+ /* @__PURE__ */ jsxs5("div", { className: slots.quantityRow, children: [
1035
+ /* @__PURE__ */ jsx5(
1036
+ "button",
1037
+ {
1038
+ type: "button",
1039
+ className: slots.incrementButton,
1040
+ onClick: () => setQuantity((q2) => Math.max(1, q2 - 1)),
1041
+ children: /* @__PURE__ */ jsx5(Minus, { className: "h-4 w-4" })
1042
+ }
1043
+ ),
1044
+ /* @__PURE__ */ jsx5("p", { className: slots.servingsValue, children: quantity }),
1045
+ /* @__PURE__ */ jsx5(
1046
+ "button",
1047
+ {
1048
+ type: "button",
1049
+ className: slots.incrementButton,
1050
+ onClick: () => setQuantity((q2) => q2 + 1),
1051
+ children: /* @__PURE__ */ jsx5(Plus, { className: "h-4 w-4" })
1052
+ }
1053
+ )
1054
+ ] })
1055
+ ] }),
1056
+ /* @__PURE__ */ jsx5(
1057
+ "button",
1058
+ {
1059
+ type: "button",
1060
+ disabled: !canSubmit,
1061
+ onClick: () => {
1062
+ submit();
1063
+ onSubmitSuccess?.();
1064
+ },
1065
+ className: slots.submitButton,
1066
+ children: unmetRule ? `Choose ${unmetRule.group_name}` : `${isEditMode ? "Save changes" : "Add to cart"} \u2014 ${money3(salePrice ?? price)}`
1067
+ }
1068
+ )
1069
+ ] });
1070
+ }
1071
+ function OptionButton({
1072
+ label,
1073
+ subtext,
1074
+ selected,
1075
+ onClick,
1076
+ slots
1077
+ }) {
1078
+ return /* @__PURE__ */ jsxs5(
1079
+ "button",
1080
+ {
1081
+ type: "button",
1082
+ onClick,
1083
+ className: cn4(
1084
+ slots.optionButton,
1085
+ selected ? slots.optionButtonSelected : slots.optionButtonUnselected
1086
+ ),
1087
+ children: [
1088
+ /* @__PURE__ */ jsx5("span", { className: slots.optionButtonLabel, children: label }),
1089
+ subtext && /* @__PURE__ */ jsx5("span", { className: slots.optionButtonUpcharge, children: subtext })
1090
+ ]
1091
+ }
1092
+ );
1093
+ }
1094
+
1095
+ // src/components/FindLocation.tsx
1096
+ import { useMemo, useState as useState4 } from "react";
1097
+ import { Search } from "lucide-react";
1098
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1099
+ function cn5(...parts) {
1100
+ return parts.filter(Boolean).join(" ");
1101
+ }
1102
+ function searchableText(location) {
1103
+ return `${location.name} ${location.address ?? ""}`.toLowerCase();
1104
+ }
1105
+ function matchRank(location, query) {
1106
+ const text = searchableText(location);
1107
+ const q2 = query.trim().toLowerCase();
1108
+ if (!q2) return 0;
1109
+ if (text.startsWith(q2) || location.name.toLowerCase().startsWith(q2)) {
1110
+ return 0;
1111
+ }
1112
+ if (text.includes(q2)) return 1;
1113
+ return 2;
1114
+ }
1115
+ function rankLocations(locations, query, pinnedLocationId) {
1116
+ const q2 = query.trim();
1117
+ const ranked = q2 ? [...locations].sort((a2, b5) => {
1118
+ const rankDiff = matchRank(a2, q2) - matchRank(b5, q2);
1119
+ if (rankDiff !== 0) return rankDiff;
1120
+ return a2.name.localeCompare(b5.name);
1121
+ }) : [...locations];
1122
+ if (pinnedLocationId == null) return ranked;
1123
+ const pinnedIndex = ranked.findIndex(
1124
+ (location) => location.location_id === pinnedLocationId
1125
+ );
1126
+ if (pinnedIndex <= 0) return ranked;
1127
+ const [pinned] = ranked.splice(pinnedIndex, 1);
1128
+ if (!pinned) return ranked;
1129
+ return [pinned, ...ranked];
1130
+ }
1131
+ var FIND_LOCATION_DEFAULT_ITEM_CLASSES = {
1132
+ baseContainer: "flex flex-col gap-6",
1133
+ searchContainer: "relative flex items-center",
1134
+ searchIcon: "absolute left-4 h-5 w-5 text-foreground opacity-50 pointer-events-none",
1135
+ searchInput: "w-full rounded-xl bg-background-recessed opacity-75 py-3 pl-12 pr-4 text-lg text-foreground placeholder:opacity-50 outline-none focus:opacity-100 transition-all duration-300",
1136
+ noMatchesMessage: "text-center opacity-75 text-sm",
1137
+ emptyMessage: "text-center opacity-75 py-8",
1138
+ list: "flex flex-col gap-3",
1139
+ locationRow: "flex items-center justify-between gap-4 p-4 rounded-xl border-3 border-foreground/[15%] shadow-sm hover:translate-x-1 transition-all duration-300 w-full",
1140
+ locationRowSelected: "bg-background-elevated",
1141
+ locationRowUnselected: "bg-background-recessed",
1142
+ locationButton: "flex flex-col gap-1 text-left flex-1 min-w-0",
1143
+ locationName: "text-lg font-semibold text-foreground",
1144
+ locationAddress: "text-base opacity-75 whitespace-pre-line",
1145
+ selectButton: "text-lg font-semibold px-4 py-3 rounded-xl bg-primary text-primary-foreground hover:opacity-75 transition-all duration-300 shrink-0"
1146
+ };
1147
+ function mergeFindLocationItemClasses(overrides) {
1148
+ const d3 = FIND_LOCATION_DEFAULT_ITEM_CLASSES;
1149
+ return {
1150
+ baseContainer: cn5(d3.baseContainer, overrides?.baseContainer),
1151
+ searchContainer: cn5(d3.searchContainer, overrides?.searchContainer),
1152
+ searchIcon: cn5(d3.searchIcon, overrides?.searchIcon),
1153
+ searchInput: cn5(d3.searchInput, overrides?.searchInput),
1154
+ noMatchesMessage: cn5(d3.noMatchesMessage, overrides?.noMatchesMessage),
1155
+ emptyMessage: cn5(d3.emptyMessage, overrides?.emptyMessage),
1156
+ list: cn5(d3.list, overrides?.list),
1157
+ locationRow: cn5(d3.locationRow, overrides?.locationRow),
1158
+ locationRowSelected: cn5(
1159
+ d3.locationRowSelected,
1160
+ overrides?.locationRowSelected
1161
+ ),
1162
+ locationRowUnselected: cn5(
1163
+ d3.locationRowUnselected,
1164
+ overrides?.locationRowUnselected
1165
+ ),
1166
+ locationButton: cn5(d3.locationButton, overrides?.locationButton),
1167
+ locationName: cn5(d3.locationName, overrides?.locationName),
1168
+ locationAddress: cn5(d3.locationAddress, overrides?.locationAddress),
1169
+ selectButton: cn5(d3.selectButton, overrides?.selectButton)
1170
+ };
1171
+ }
1172
+ function FindLocation({
1173
+ locations,
1174
+ initialSelected,
1175
+ onSelect,
1176
+ itemClasses
1177
+ }) {
1178
+ const [query, setQuery] = useState4("");
1179
+ const [selected, setSelected] = useState4(
1180
+ () => initialSelected ?? null
1181
+ );
1182
+ const slots = mergeFindLocationItemClasses(itemClasses);
1183
+ const pinnedLocationId = initialSelected?.location_id;
1184
+ const ranked = useMemo(
1185
+ () => rankLocations(locations, query, pinnedLocationId),
1186
+ [locations, query, pinnedLocationId]
1187
+ );
1188
+ const trimmedQuery = query.trim();
1189
+ const noMatches = trimmedQuery.length > 0 && locations.every((location) => matchRank(location, trimmedQuery) === 2);
1190
+ return /* @__PURE__ */ jsxs6("div", { className: slots.baseContainer, children: [
1191
+ /* @__PURE__ */ jsxs6("div", { className: slots.searchContainer, children: [
1192
+ /* @__PURE__ */ jsx6(Search, { className: slots.searchIcon, strokeWidth: 2 }),
1193
+ /* @__PURE__ */ jsx6(
1194
+ "input",
1195
+ {
1196
+ type: "search",
1197
+ value: query,
1198
+ onChange: (e) => setQuery(e.target.value),
1199
+ placeholder: "Search by name or address",
1200
+ className: slots.searchInput,
1201
+ "aria-label": "Search locations"
1202
+ }
1203
+ )
1204
+ ] }),
1205
+ noMatches && /* @__PURE__ */ jsxs6("p", { className: slots.noMatchesMessage, children: [
1206
+ "No locations match \u201C",
1207
+ trimmedQuery,
1208
+ "\u201D. Showing all locations anyway."
1209
+ ] }),
1210
+ ranked.length === 0 ? /* @__PURE__ */ jsx6("p", { className: slots.emptyMessage, children: "No locations available." }) : /* @__PURE__ */ jsx6("ul", { className: slots.list, children: ranked.map((location) => {
1211
+ const isSelected = selected?.location_id === location.location_id;
1212
+ return /* @__PURE__ */ jsxs6(
1213
+ "li",
1214
+ {
1215
+ className: cn5(
1216
+ slots.locationRow,
1217
+ isSelected ? slots.locationRowSelected : slots.locationRowUnselected
1218
+ ),
1219
+ children: [
1220
+ /* @__PURE__ */ jsxs6(
1221
+ "button",
1222
+ {
1223
+ type: "button",
1224
+ onClick: () => setSelected(location),
1225
+ "aria-pressed": isSelected,
1226
+ className: slots.locationButton,
1227
+ children: [
1228
+ /* @__PURE__ */ jsx6("p", { className: slots.locationName, children: location.name }),
1229
+ location.address && /* @__PURE__ */ jsx6("p", { className: slots.locationAddress, children: location.address })
1230
+ ]
1231
+ }
1232
+ ),
1233
+ isSelected && /* @__PURE__ */ jsx6(
1234
+ "button",
1235
+ {
1236
+ type: "button",
1237
+ onClick: () => onSelect(location),
1238
+ className: slots.selectButton,
1239
+ children: "Select"
1240
+ }
1241
+ )
1242
+ ]
1243
+ },
1244
+ location.location_id
1245
+ );
1246
+ }) })
1247
+ ] });
1248
+ }
1249
+
1250
+ // src/components/CheckoutForm.tsx
1251
+ import { useEffect as useEffect3, useState as useState5 } from "react";
1252
+ import Link4 from "next/link";
1253
+ import {
1254
+ Elements,
1255
+ PaymentElement,
1256
+ useElements,
1257
+ useStripe
1258
+ } from "@stripe/react-stripe-js";
1259
+ import { Minus as Minus2, Pencil, Plus as Plus2 } from "lucide-react";
1260
+ import {
1261
+ useCart,
1262
+ useCustomer as useCustomer2,
1263
+ useLocation,
1264
+ useModal,
1265
+ usePayment,
1266
+ usePromotions
1267
+ } from "@zorgo/next";
1268
+ import {
1269
+ DynamicFormShell,
1270
+ NameFields,
1271
+ PhoneField,
1272
+ EmailField,
1273
+ FieldError,
1274
+ CheckboxField,
1275
+ SubmitButton
1276
+ } from "@zorgo/next";
1277
+ import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1278
+ function money4(cents) {
1279
+ return `$${(cents / 100).toFixed(2)}`;
1280
+ }
1281
+ function cn6(...parts) {
1282
+ return parts.filter(Boolean).join(" ");
1283
+ }
1284
+ var CHECKOUT_FORM_DEFAULT_ITEM_CLASSES = {
1285
+ shell: "",
1286
+ shellInner: "max-w-2xl mx-auto w-full flex flex-col gap-6",
1287
+ pageTitle: "text-4xl font-extrabold text-primary text-center mb-8",
1288
+ primaryButton: "text-lg font-semibold px-4 py-3 rounded-xl bg-primary text-primary-foreground hover:opacity-75 transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed",
1289
+ secondaryButton: "text-lg font-semibold px-4 py-3 rounded-xl bg-background-recessed text-foreground border-3 border-foreground/[15%] hover:opacity-75 transition-all duration-300",
1290
+ incrementButton: "bg-background-recessed text-foreground w-10 h-10 rounded-xl flex items-center justify-center hover:bg-foreground hover:text-background transition-all duration-300",
1291
+ surface: "rounded-xl bg-background-elevated border-3 border-foreground/[15%] shadow-sm",
1292
+ fieldInput: "w-full bg-transparent outline-none text-lg font-semibold text-foreground placeholder:opacity-50",
1293
+ fieldContainer: "flex flex-col gap-1 w-full p-4 rounded-xl bg-background-elevated border-3 border-foreground/[15%]",
1294
+ fieldLabel: "text-xl opacity-50 text-foreground",
1295
+ fieldError: "text-xl text-red-500",
1296
+ statusPanel: "flex flex-col gap-6 items-center text-center p-8 w-full",
1297
+ statusTitle: "text-3xl font-semibold",
1298
+ statusMessage: "text-xl max-w-md opacity-60",
1299
+ statusMessageError: "text-xl max-w-md text-red-500",
1300
+ statusActions: "w-full max-w-sm flex flex-col gap-3",
1301
+ stepSection: "flex flex-col gap-6",
1302
+ sectionTitle: "text-3xl font-semibold mt-8",
1303
+ cartList: "flex flex-col gap-3",
1304
+ totals: "flex flex-col gap-2 p-4",
1305
+ totalsRow: "flex flex-row justify-between text-xl opacity-75",
1306
+ totalsDivider: "h-[2px] bg-foreground/20 rounded-xl w-full",
1307
+ totalsTotalRow: "flex flex-row justify-between text-2xl font-semibold pt-2",
1308
+ form: "flex flex-col gap-4 w-full",
1309
+ formActions: "flex flex-row items-center justify-between gap-3",
1310
+ submitError: "text-sm text-red-500",
1311
+ paymentSurface: "p-4",
1312
+ steps: "flex flex-row items-center gap-2 w-full",
1313
+ stepBadge: "w-10 h-10 rounded-full flex items-center justify-center text-xl font-semibold transition-all duration-300",
1314
+ stepBadgeActive: "bg-foreground text-background",
1315
+ stepBadgeInactive: "bg-background-recessed text-foreground opacity-60",
1316
+ stepLabel: "text-xl transition-all duration-300",
1317
+ stepLabelActive: "font-semibold",
1318
+ stepLabelInactive: "opacity-60",
1319
+ stepDivider: "flex-1 h-[2px] transition-all duration-300",
1320
+ stepDividerActive: "bg-foreground",
1321
+ stepDividerInactive: "bg-foreground/15",
1322
+ cartLine: "flex flex-row items-start justify-between gap-4 p-4 w-full",
1323
+ cartLineName: "text-xl font-semibold text-foreground",
1324
+ cartLineSelection: "text-lg opacity-50",
1325
+ cartLinePrice: "text-lg font-semibold opacity-75",
1326
+ cartLineControls: "flex flex-col flex-col-reverse md:flex-row items-center gap-3 shrink-0",
1327
+ cartLineQuantity: "w-8 text-xl font-semibold text-center",
1328
+ promoApplied: "flex flex-row items-center justify-between gap-4 p-4 w-full",
1329
+ promoAppliedLabel: "flex-1 text-lg font-semibold",
1330
+ promoRow: "flex flex-row gap-3",
1331
+ promoInput: "flex-1 rounded-xl bg-background-recessed border-3 border-transparent py-3 px-4 text-lg font-semibold text-foreground placeholder:opacity-50 outline-none focus:border-foreground/15 transition-all duration-300",
1332
+ promoError: "text-xl text-red-500"
1333
+ };
1334
+ function mergeCheckoutFormItemClasses(overrides) {
1335
+ const d3 = CHECKOUT_FORM_DEFAULT_ITEM_CLASSES;
1336
+ return {
1337
+ shell: cn6(d3.shell, overrides?.shell),
1338
+ shellInner: cn6(d3.shellInner, overrides?.shellInner),
1339
+ pageTitle: cn6(d3.pageTitle, overrides?.pageTitle),
1340
+ primaryButton: cn6(d3.primaryButton, overrides?.primaryButton),
1341
+ secondaryButton: cn6(d3.secondaryButton, overrides?.secondaryButton),
1342
+ incrementButton: cn6(d3.incrementButton, overrides?.incrementButton),
1343
+ surface: cn6(d3.surface, overrides?.surface),
1344
+ fieldInput: cn6(d3.fieldInput, overrides?.fieldInput),
1345
+ fieldContainer: cn6(d3.fieldContainer, overrides?.fieldContainer),
1346
+ fieldLabel: cn6(d3.fieldLabel, overrides?.fieldLabel),
1347
+ fieldError: cn6(d3.fieldError, overrides?.fieldError),
1348
+ statusPanel: cn6(d3.statusPanel, overrides?.statusPanel),
1349
+ statusTitle: cn6(d3.statusTitle, overrides?.statusTitle),
1350
+ statusMessage: cn6(d3.statusMessage, overrides?.statusMessage),
1351
+ statusMessageError: cn6(
1352
+ d3.statusMessageError,
1353
+ overrides?.statusMessageError
1354
+ ),
1355
+ statusActions: cn6(d3.statusActions, overrides?.statusActions),
1356
+ stepSection: cn6(d3.stepSection, overrides?.stepSection),
1357
+ sectionTitle: cn6(d3.sectionTitle, overrides?.sectionTitle),
1358
+ cartList: cn6(d3.cartList, overrides?.cartList),
1359
+ totals: cn6(d3.totals, overrides?.totals),
1360
+ totalsRow: cn6(d3.totalsRow, overrides?.totalsRow),
1361
+ totalsDivider: cn6(d3.totalsDivider, overrides?.totalsDivider),
1362
+ totalsTotalRow: cn6(d3.totalsTotalRow, overrides?.totalsTotalRow),
1363
+ form: cn6(d3.form, overrides?.form),
1364
+ formActions: cn6(d3.formActions, overrides?.formActions),
1365
+ submitError: cn6(d3.submitError, overrides?.submitError),
1366
+ paymentSurface: cn6(d3.paymentSurface, overrides?.paymentSurface),
1367
+ steps: cn6(d3.steps, overrides?.steps),
1368
+ stepBadge: cn6(d3.stepBadge, overrides?.stepBadge),
1369
+ stepBadgeActive: cn6(d3.stepBadgeActive, overrides?.stepBadgeActive),
1370
+ stepBadgeInactive: cn6(
1371
+ d3.stepBadgeInactive,
1372
+ overrides?.stepBadgeInactive
1373
+ ),
1374
+ stepLabel: cn6(d3.stepLabel, overrides?.stepLabel),
1375
+ stepLabelActive: cn6(d3.stepLabelActive, overrides?.stepLabelActive),
1376
+ stepLabelInactive: cn6(
1377
+ d3.stepLabelInactive,
1378
+ overrides?.stepLabelInactive
1379
+ ),
1380
+ stepDivider: cn6(d3.stepDivider, overrides?.stepDivider),
1381
+ stepDividerActive: cn6(
1382
+ d3.stepDividerActive,
1383
+ overrides?.stepDividerActive
1384
+ ),
1385
+ stepDividerInactive: cn6(
1386
+ d3.stepDividerInactive,
1387
+ overrides?.stepDividerInactive
1388
+ ),
1389
+ cartLine: cn6(d3.cartLine, overrides?.cartLine),
1390
+ cartLineName: cn6(d3.cartLineName, overrides?.cartLineName),
1391
+ cartLineSelection: cn6(
1392
+ d3.cartLineSelection,
1393
+ overrides?.cartLineSelection
1394
+ ),
1395
+ cartLinePrice: cn6(d3.cartLinePrice, overrides?.cartLinePrice),
1396
+ cartLineControls: cn6(d3.cartLineControls, overrides?.cartLineControls),
1397
+ cartLineQuantity: cn6(d3.cartLineQuantity, overrides?.cartLineQuantity),
1398
+ promoApplied: cn6(d3.promoApplied, overrides?.promoApplied),
1399
+ promoAppliedLabel: cn6(
1400
+ d3.promoAppliedLabel,
1401
+ overrides?.promoAppliedLabel
1402
+ ),
1403
+ promoRow: cn6(d3.promoRow, overrides?.promoRow),
1404
+ promoInput: cn6(d3.promoInput, overrides?.promoInput),
1405
+ promoError: cn6(d3.promoError, overrides?.promoError)
1406
+ };
1407
+ }
1408
+ function CheckoutForm({
1409
+ itemClasses,
1410
+ homeHref = "/",
1411
+ menuHref = "/menu",
1412
+ checkoutHref = "/checkout"
1413
+ }) {
1414
+ const slots = mergeCheckoutFormItemClasses(itemClasses);
1415
+ const {
1416
+ clientSecret,
1417
+ stripe,
1418
+ elementOptions,
1419
+ isReady,
1420
+ isLoading,
1421
+ error,
1422
+ getReturnStatus
1423
+ } = usePayment();
1424
+ const { isEmpty, resetCart } = useCart();
1425
+ const { currentLocation, needsLocationSelection } = useLocation({
1426
+ promptLocationSelection: true
1427
+ });
1428
+ const { open } = useModal();
1429
+ const [returnStatus, setReturnStatus] = useState5(null);
1430
+ useEffect3(() => {
1431
+ if (window.location.search.includes("redirect_status")) {
1432
+ const status = getReturnStatus(window.location.href);
1433
+ setReturnStatus(status);
1434
+ if (status.succeeded) resetCart();
1435
+ }
1436
+ }, []);
1437
+ if (returnStatus) {
1438
+ return /* @__PURE__ */ jsx7(Shell, { slots, children: returnStatus.succeeded ? /* @__PURE__ */ jsx7(
1439
+ StatusPanel,
1440
+ {
1441
+ slots,
1442
+ title: "You're all set",
1443
+ message: "Payment successful. Thank you!",
1444
+ action: /* @__PURE__ */ jsx7(
1445
+ Link4,
1446
+ {
1447
+ href: homeHref,
1448
+ className: cn6(
1449
+ slots.primaryButton,
1450
+ "block w-full text-center"
1451
+ ),
1452
+ children: "Back home"
1453
+ }
1454
+ )
1455
+ }
1456
+ ) : /* @__PURE__ */ jsx7(
1457
+ StatusPanel,
1458
+ {
1459
+ slots,
1460
+ title: "Payment didn't go through",
1461
+ message: returnStatus.error,
1462
+ tone: "error",
1463
+ action: /* @__PURE__ */ jsx7(
1464
+ Link4,
1465
+ {
1466
+ href: checkoutHref,
1467
+ className: cn6(
1468
+ slots.primaryButton,
1469
+ "block w-full text-center"
1470
+ ),
1471
+ children: "Try again"
1472
+ }
1473
+ )
1474
+ }
1475
+ ) });
1476
+ }
1477
+ if (isEmpty && !isLoading && !clientSecret) {
1478
+ return /* @__PURE__ */ jsx7(Shell, { slots, children: /* @__PURE__ */ jsx7(
1479
+ StatusPanel,
1480
+ {
1481
+ slots,
1482
+ title: "Your cart is empty",
1483
+ message: "Add something from the menu to get started.",
1484
+ action: /* @__PURE__ */ jsx7(
1485
+ Link4,
1486
+ {
1487
+ href: menuHref,
1488
+ className: cn6(
1489
+ slots.primaryButton,
1490
+ "block w-full text-center"
1491
+ ),
1492
+ children: "Browse the menu"
1493
+ }
1494
+ )
1495
+ }
1496
+ ) });
1497
+ }
1498
+ if (error) {
1499
+ return /* @__PURE__ */ jsx7(Shell, { slots, children: /* @__PURE__ */ jsx7(
1500
+ StatusPanel,
1501
+ {
1502
+ slots,
1503
+ title: "Something went wrong",
1504
+ message: error,
1505
+ tone: "error",
1506
+ action: /* @__PURE__ */ jsx7(
1507
+ Link4,
1508
+ {
1509
+ href: menuHref,
1510
+ className: cn6(
1511
+ slots.primaryButton,
1512
+ "block w-full text-center"
1513
+ ),
1514
+ children: "Back to menu"
1515
+ }
1516
+ )
1517
+ }
1518
+ ) });
1519
+ }
1520
+ if (needsLocationSelection) {
1521
+ return /* @__PURE__ */ jsx7(Shell, { slots, children: /* @__PURE__ */ jsx7(
1522
+ StatusPanel,
1523
+ {
1524
+ slots,
1525
+ title: "Choose a location",
1526
+ message: "Please choose a location to continue checkout.",
1527
+ action: /* @__PURE__ */ jsx7(
1528
+ "button",
1529
+ {
1530
+ type: "button",
1531
+ onClick: () => open("FIND_LOCATION_MODAL"),
1532
+ className: cn6(slots.primaryButton, "w-full"),
1533
+ children: "Select a location"
1534
+ }
1535
+ )
1536
+ }
1537
+ ) });
1538
+ }
1539
+ if (isReady && elementOptions) {
1540
+ return /* @__PURE__ */ jsx7(Shell, { slots, children: /* @__PURE__ */ jsx7(
1541
+ Elements,
1542
+ {
1543
+ stripe,
1544
+ options: elementOptions,
1545
+ children: /* @__PURE__ */ jsx7(PaymentStep, { slots, checkoutHref })
1546
+ },
1547
+ currentLocation?.stripe_account_id
1548
+ ) });
1549
+ }
1550
+ return /* @__PURE__ */ jsx7(Shell, { slots, children: /* @__PURE__ */ jsx7(DetailsStep, { slots }) });
1551
+ }
1552
+ function StatusPanel({
1553
+ title,
1554
+ message,
1555
+ action,
1556
+ tone = "default",
1557
+ slots
1558
+ }) {
1559
+ return /* @__PURE__ */ jsxs7("div", { className: cn6(slots.statusPanel, slots.surface), children: [
1560
+ /* @__PURE__ */ jsx7("h2", { className: slots.statusTitle, children: title }),
1561
+ message && /* @__PURE__ */ jsx7(
1562
+ "p",
1563
+ {
1564
+ className: tone === "error" ? slots.statusMessageError : slots.statusMessage,
1565
+ children: message
1566
+ }
1567
+ ),
1568
+ /* @__PURE__ */ jsx7("div", { className: slots.statusActions, children: action })
1569
+ ] });
1570
+ }
1571
+ function DetailsStep({ slots }) {
1572
+ const {
1573
+ items,
1574
+ subtotal,
1575
+ discount,
1576
+ tax,
1577
+ serviceFee,
1578
+ total,
1579
+ removeItem,
1580
+ resetCart
1581
+ } = useCart();
1582
+ const { customer, setCustomer } = useCustomer2();
1583
+ const { startCheckout } = usePayment();
1584
+ const [submitError, setSubmitError] = useState5();
1585
+ const fieldContainerClass = slots.fieldContainer;
1586
+ const fieldStyleProps = {
1587
+ fieldClassName: slots.fieldInput,
1588
+ containerClassName: fieldContainerClass,
1589
+ fieldLabelClassName: slots.fieldLabel,
1590
+ fieldErrorClassName: slots.fieldError
1591
+ };
1592
+ const handleSubmit = async (values) => {
1593
+ const filledCustomer = {
1594
+ first_name: values.firstName,
1595
+ last_name: values.lastName,
1596
+ phone: values.phone,
1597
+ email: values.email,
1598
+ allow_marketing: values.marketingConsent
1599
+ };
1600
+ setCustomer(filledCustomer);
1601
+ try {
1602
+ await startCheckout();
1603
+ } catch (err) {
1604
+ setSubmitError(
1605
+ err instanceof Error ? err.message : "Could not start payment."
1606
+ );
1607
+ }
1608
+ };
1609
+ return /* @__PURE__ */ jsxs7("div", { className: slots.stepSection, children: [
1610
+ /* @__PURE__ */ jsx7(Steps, { current: 1, slots }),
1611
+ /* @__PURE__ */ jsx7("h2", { className: slots.sectionTitle, children: "Your order" }),
1612
+ /* @__PURE__ */ jsx7("div", { className: slots.cartList, children: items.map((item, index) => /* @__PURE__ */ jsx7(
1613
+ CartLine,
1614
+ {
1615
+ item,
1616
+ index,
1617
+ onRemove: () => removeItem(index),
1618
+ slots
1619
+ },
1620
+ `${item.item_id}-${index}`
1621
+ )) }),
1622
+ /* @__PURE__ */ jsxs7("div", { className: cn6(slots.totals, slots.surface), children: [
1623
+ /* @__PURE__ */ jsxs7("div", { className: slots.totalsRow, children: [
1624
+ /* @__PURE__ */ jsx7("span", { children: "Subtotal" }),
1625
+ /* @__PURE__ */ jsx7("span", { children: money4(subtotal) })
1626
+ ] }),
1627
+ discount > 0 && /* @__PURE__ */ jsxs7("div", { className: slots.totalsRow, children: [
1628
+ /* @__PURE__ */ jsx7("span", { children: "Discount" }),
1629
+ /* @__PURE__ */ jsx7("span", { children: money4(-discount) })
1630
+ ] }),
1631
+ /* @__PURE__ */ jsxs7("div", { className: slots.totalsRow, children: [
1632
+ /* @__PURE__ */ jsx7("span", { children: "Tax" }),
1633
+ /* @__PURE__ */ jsx7("span", { children: money4(tax) })
1634
+ ] }),
1635
+ serviceFee > 0 && /* @__PURE__ */ jsxs7("div", { className: slots.totalsRow, children: [
1636
+ /* @__PURE__ */ jsx7("span", { children: "Service fee" }),
1637
+ /* @__PURE__ */ jsx7("span", { children: serviceFee })
1638
+ ] }),
1639
+ /* @__PURE__ */ jsx7("div", { className: slots.totalsDivider }),
1640
+ /* @__PURE__ */ jsxs7("div", { className: slots.totalsTotalRow, children: [
1641
+ /* @__PURE__ */ jsx7("span", { children: "Total" }),
1642
+ /* @__PURE__ */ jsx7("span", { children: money4(total) })
1643
+ ] })
1644
+ ] }),
1645
+ /* @__PURE__ */ jsx7(PromoCode, { slots }),
1646
+ /* @__PURE__ */ jsx7("h2", { className: slots.sectionTitle, children: "Contact information" }),
1647
+ /* @__PURE__ */ jsxs7(DynamicFormShell, { onSubmit: handleSubmit, className: slots.form, children: [
1648
+ /* @__PURE__ */ jsx7(
1649
+ NameFields,
1650
+ {
1651
+ firstNameInitialValue: customer.first_name ?? "",
1652
+ lastNameInitialValue: customer.last_name ?? "",
1653
+ fieldClassName: slots.fieldInput,
1654
+ fieldLabelClassName: slots.fieldLabel,
1655
+ fieldErrorClassName: slots.fieldError,
1656
+ childClassName: cn6(
1657
+ fieldContainerClass,
1658
+ "md:flex-1 md:min-w-0"
1659
+ )
1660
+ }
1661
+ ),
1662
+ /* @__PURE__ */ jsxs7("div", { className: "flex flex-col w-full gap-1", children: [
1663
+ /* @__PURE__ */ jsx7(
1664
+ PhoneField,
1665
+ {
1666
+ initialValue: customer.phone ?? "",
1667
+ showError: false,
1668
+ ...fieldStyleProps
1669
+ }
1670
+ ),
1671
+ /* @__PURE__ */ jsx7(FieldError, { name: "phone", className: slots.fieldError })
1672
+ ] }),
1673
+ /* @__PURE__ */ jsxs7("div", { className: "flex flex-col w-full gap-1", children: [
1674
+ /* @__PURE__ */ jsx7(
1675
+ EmailField,
1676
+ {
1677
+ initialValue: customer.email ?? "",
1678
+ showError: false,
1679
+ ...fieldStyleProps
1680
+ }
1681
+ ),
1682
+ /* @__PURE__ */ jsx7(FieldError, { name: "email", className: slots.fieldError })
1683
+ ] }),
1684
+ /* @__PURE__ */ jsx7(
1685
+ CheckboxField,
1686
+ {
1687
+ fieldId: "termsAccepted",
1688
+ required: true,
1689
+ requiredText: "You must agree to the terms of service to continue.",
1690
+ fieldErrorClassName: slots.fieldError,
1691
+ children: "I have read and agree to the terms of service."
1692
+ }
1693
+ ),
1694
+ /* @__PURE__ */ jsx7(CheckboxField, { fieldId: "marketingConsent", required: false, children: "I consent to receive promotions via text and email." }),
1695
+ submitError && /* @__PURE__ */ jsx7("p", { className: slots.submitError, children: submitError }),
1696
+ /* @__PURE__ */ jsxs7("div", { className: slots.formActions, children: [
1697
+ /* @__PURE__ */ jsx7(
1698
+ "button",
1699
+ {
1700
+ type: "button",
1701
+ onClick: resetCart,
1702
+ className: slots.secondaryButton,
1703
+ children: "Clear cart"
1704
+ }
1705
+ ),
1706
+ /* @__PURE__ */ jsx7(
1707
+ SubmitButton,
1708
+ {
1709
+ label: "Continue to payment",
1710
+ loadingLabel: "Setting up...",
1711
+ className: cn6("flex-1", slots.primaryButton)
1712
+ }
1713
+ )
1714
+ ] })
1715
+ ] })
1716
+ ] });
1717
+ }
1718
+ function PaymentStep({
1719
+ slots,
1720
+ checkoutHref
1721
+ }) {
1722
+ const stripe = useStripe();
1723
+ const elements = useElements();
1724
+ const {
1725
+ total,
1726
+ clientSecret,
1727
+ submitPayment,
1728
+ paymentElementOptions,
1729
+ getReturnUrl,
1730
+ resetCheckout
1731
+ } = usePayment();
1732
+ const { customer } = useCustomer2();
1733
+ const [submitError, setSubmitError] = useState5();
1734
+ const handleSubmit = async () => {
1735
+ if (!stripe || !elements || !clientSecret) return;
1736
+ const { error } = await elements.submit();
1737
+ if (error) {
1738
+ setSubmitError(error.message ?? "Please check your card details.");
1739
+ throw error;
1740
+ }
1741
+ const returnUrl = `${getReturnUrl()}${checkoutHref.startsWith("/") ? checkoutHref : `/${checkoutHref}`}`;
1742
+ const result = await submitPayment(
1743
+ stripe,
1744
+ elements,
1745
+ clientSecret,
1746
+ returnUrl,
1747
+ customer
1748
+ );
1749
+ if (!result.success) setSubmitError(result.error);
1750
+ };
1751
+ return /* @__PURE__ */ jsxs7("div", { className: slots.stepSection, children: [
1752
+ /* @__PURE__ */ jsx7(Steps, { current: 2, slots }),
1753
+ /* @__PURE__ */ jsxs7(DynamicFormShell, { onSubmit: handleSubmit, className: slots.form, children: [
1754
+ /* @__PURE__ */ jsx7("div", { className: cn6(slots.paymentSurface, slots.surface), children: /* @__PURE__ */ jsx7(PaymentElement, { options: paymentElementOptions }) }),
1755
+ submitError && /* @__PURE__ */ jsx7("p", { className: slots.submitError, children: submitError }),
1756
+ /* @__PURE__ */ jsxs7("div", { className: slots.formActions, children: [
1757
+ /* @__PURE__ */ jsx7(
1758
+ "button",
1759
+ {
1760
+ type: "button",
1761
+ onClick: resetCheckout,
1762
+ className: slots.secondaryButton,
1763
+ children: "Back to order"
1764
+ }
1765
+ ),
1766
+ /* @__PURE__ */ jsx7(
1767
+ SubmitButton,
1768
+ {
1769
+ label: `Pay ${money4(total ?? 0)}`,
1770
+ loadingLabel: "Processing...",
1771
+ className: cn6("flex-1", slots.primaryButton)
1772
+ }
1773
+ )
1774
+ ] })
1775
+ ] })
1776
+ ] });
1777
+ }
1778
+ function Steps({ current, slots }) {
1779
+ const labels = ["Your details", "Payment"];
1780
+ return /* @__PURE__ */ jsx7("div", { className: slots.steps, children: labels.map((label, i4) => {
1781
+ const n3 = i4 + 1;
1782
+ const active = n3 <= current;
1783
+ return /* @__PURE__ */ jsxs7("div", { className: "contents", children: [
1784
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
1785
+ /* @__PURE__ */ jsx7(
1786
+ "div",
1787
+ {
1788
+ className: cn6(
1789
+ slots.stepBadge,
1790
+ active ? slots.stepBadgeActive : slots.stepBadgeInactive
1791
+ ),
1792
+ children: n3
1793
+ }
1794
+ ),
1795
+ /* @__PURE__ */ jsx7(
1796
+ "p",
1797
+ {
1798
+ className: cn6(
1799
+ slots.stepLabel,
1800
+ active ? slots.stepLabelActive : slots.stepLabelInactive
1801
+ ),
1802
+ children: label
1803
+ }
1804
+ )
1805
+ ] }),
1806
+ i4 < labels.length - 1 && /* @__PURE__ */ jsx7(
1807
+ "div",
1808
+ {
1809
+ className: cn6(
1810
+ slots.stepDivider,
1811
+ current > n3 ? slots.stepDividerActive : slots.stepDividerInactive
1812
+ )
1813
+ }
1814
+ )
1815
+ ] }, label);
1816
+ }) });
1817
+ }
1818
+ function CartLine({
1819
+ item,
1820
+ index,
1821
+ onRemove,
1822
+ slots
1823
+ }) {
1824
+ const { open } = useModal();
1825
+ const { updateItem, getItemTotal } = useCart();
1826
+ const setQuantity = (next) => next < 1 ? onRemove() : updateItem({ ...item, quantity: next }, index);
1827
+ return /* @__PURE__ */ jsxs7("div", { className: cn6(slots.cartLine, slots.surface), children: [
1828
+ /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-1 flex-1 min-w-0", children: [
1829
+ /* @__PURE__ */ jsx7("p", { className: slots.cartLineName, children: item.name }),
1830
+ (() => {
1831
+ const added = (item.selections ?? []).flatMap((rs) => rs.selections.map((s5) => s5.name));
1832
+ const removed = (item.components ?? []).filter((c6) => c6.quantity_servings === 0).map((c6) => c6.name);
1833
+ return /* @__PURE__ */ jsxs7(Fragment3, { children: [
1834
+ added.length > 0 && /* @__PURE__ */ jsxs7("p", { className: slots.cartLineSelection, children: [
1835
+ "Add ",
1836
+ added.join(", ")
1837
+ ] }),
1838
+ removed.length > 0 && /* @__PURE__ */ jsxs7("p", { className: slots.cartLineSelection, children: [
1839
+ "Remove ",
1840
+ removed.join(", ")
1841
+ ] }),
1842
+ item.comments && /* @__PURE__ */ jsxs7("p", { className: slots.cartLineSelection, children: [
1843
+ "Comments: ",
1844
+ item.comments
1845
+ ] })
1846
+ ] });
1847
+ })(),
1848
+ /* @__PURE__ */ jsx7("p", { className: slots.cartLinePrice, children: money4(getItemTotal(item)) })
1849
+ ] }),
1850
+ /* @__PURE__ */ jsxs7("div", { className: slots.cartLineControls, children: [
1851
+ /* @__PURE__ */ jsx7(
1852
+ "button",
1853
+ {
1854
+ type: "button",
1855
+ "aria-label": "Edit item",
1856
+ className: slots.incrementButton,
1857
+ onClick: () => open("EDIT_ITEM_MODAL", {
1858
+ baseItemId: item.base_item_id,
1859
+ seed: item,
1860
+ editIndex: index
1861
+ }),
1862
+ children: /* @__PURE__ */ jsx7(Pencil, { className: "w-5 h-5" })
1863
+ }
1864
+ ),
1865
+ /* @__PURE__ */ jsx7(
1866
+ "button",
1867
+ {
1868
+ type: "button",
1869
+ className: slots.incrementButton,
1870
+ onClick: () => setQuantity(item.quantity - 1),
1871
+ children: /* @__PURE__ */ jsx7(Minus2, { className: "w-5 h-5" })
1872
+ }
1873
+ ),
1874
+ /* @__PURE__ */ jsx7("p", { className: slots.cartLineQuantity, children: item.quantity }),
1875
+ /* @__PURE__ */ jsx7(
1876
+ "button",
1877
+ {
1878
+ type: "button",
1879
+ className: slots.incrementButton,
1880
+ onClick: () => setQuantity(item.quantity + 1),
1881
+ children: /* @__PURE__ */ jsx7(Plus2, { className: "w-5 h-5" })
1882
+ }
1883
+ )
1884
+ ] })
1885
+ ] });
1886
+ }
1887
+ function PromoCode({ slots }) {
1888
+ const { promoCode, appliedPromo, applyPromo, removePromo, error, loading } = usePromotions();
1889
+ const [draft, setDraft] = useState5("");
1890
+ if (appliedPromo) {
1891
+ return /* @__PURE__ */ jsxs7("div", { className: cn6(slots.promoApplied, slots.surface), children: [
1892
+ /* @__PURE__ */ jsxs7("span", { className: slots.promoAppliedLabel, children: [
1893
+ appliedPromo.name,
1894
+ " applied"
1895
+ ] }),
1896
+ promoCode && /* @__PURE__ */ jsx7(
1897
+ "button",
1898
+ {
1899
+ type: "button",
1900
+ onClick: removePromo,
1901
+ className: slots.secondaryButton,
1902
+ children: "Remove"
1903
+ }
1904
+ )
1905
+ ] });
1906
+ }
1907
+ return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2 w-full", children: [
1908
+ /* @__PURE__ */ jsxs7("div", { className: slots.promoRow, children: [
1909
+ /* @__PURE__ */ jsx7(
1910
+ "input",
1911
+ {
1912
+ value: draft,
1913
+ onChange: (e) => setDraft(e.target.value),
1914
+ placeholder: "Promo code",
1915
+ className: slots.promoInput
1916
+ }
1917
+ ),
1918
+ /* @__PURE__ */ jsx7(
1919
+ "button",
1920
+ {
1921
+ type: "button",
1922
+ disabled: loading || !draft.trim(),
1923
+ onClick: () => applyPromo(draft),
1924
+ className: cn6(slots.primaryButton, "shrink-0"),
1925
+ children: loading ? "Applying\u2026" : "Apply"
1926
+ }
1927
+ )
1928
+ ] }),
1929
+ error && /* @__PURE__ */ jsx7("p", { className: slots.promoError, children: error })
1930
+ ] });
1931
+ }
1932
+ function Shell({
1933
+ children,
1934
+ slots
1935
+ }) {
1936
+ return /* @__PURE__ */ jsx7("div", { className: slots.shell, children: /* @__PURE__ */ jsxs7("div", { className: slots.shellInner, children: [
1937
+ /* @__PURE__ */ jsx7("h1", { className: slots.pageTitle, children: "Checkout" }),
1938
+ children
1939
+ ] }) });
1940
+ }
1941
+ export {
1942
+ ACCORDION_MENU_DEFAULT_ITEM_CLASSES,
1943
+ AccordionMenu,
1944
+ BREADCRUMBS_DEFAULT_ITEM_CLASSES,
1945
+ Breadcrumbs,
1946
+ CHECKOUT_FORM_DEFAULT_ITEM_CLASSES,
1947
+ CheckoutForm,
1948
+ CookieConsent,
1949
+ FIND_LOCATION_DEFAULT_ITEM_CLASSES,
1950
+ FindLocation,
1951
+ GRID_MENU_DEFAULT_ITEM_CLASSES,
1952
+ GridMenu,
1953
+ ITEM_CUSTOMIZATION_FORM_DEFAULT_ITEM_CLASSES,
1954
+ ItemCustomizationForm,
1955
+ mergeAccordionMenuItemClasses,
1956
+ mergeBreadcrumbsItemClasses,
1957
+ mergeCheckoutFormItemClasses,
1958
+ mergeFindLocationItemClasses,
1959
+ mergeGridMenuItemClasses,
1960
+ mergeItemCustomizationFormItemClasses
1961
+ };
1962
+ //# sourceMappingURL=components.mjs.map