@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.
- package/README.md +19 -0
- package/dist/cli.d.mts +5 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +2 -0
- package/dist/cli.mjs +2 -0
- package/dist/components.d.mts +337 -0
- package/dist/components.d.ts +337 -0
- package/dist/components.js +1996 -0
- package/dist/components.js.map +1 -0
- package/dist/components.mjs +1962 -0
- package/dist/components.mjs.map +1 -0
- package/dist/index.d.mts +305 -0
- package/dist/index.d.ts +305 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +2 -0
- package/dist/seo.d.mts +30 -0
- package/dist/seo.d.ts +30 -0
- package/dist/seo.js +82 -0
- package/dist/seo.js.map +1 -0
- package/dist/seo.mjs +56 -0
- package/dist/seo.mjs.map +1 -0
- package/dist/slugs.d.mts +1 -0
- package/dist/slugs.d.ts +1 -0
- package/dist/slugs.js +47 -0
- package/dist/slugs.js.map +1 -0
- package/dist/slugs.mjs +19 -0
- package/dist/slugs.mjs.map +1 -0
- package/dist/tree/.env.gen.ts +27 -0
- package/dist/tree/README.md +0 -0
- package/dist/tree/app/api/zorgo-token/route.ts +11 -0
- package/dist/tree/app/apple-icon.tsx.gen.ts +54 -0
- package/dist/tree/app/checkout/page.tsx +10 -0
- package/dist/tree/app/components/Footer.tsx +50 -0
- package/dist/tree/app/components/Header.tsx +128 -0
- package/dist/tree/app/components/ModalHost.tsx +56 -0
- package/dist/tree/app/components/ModalRegistry.tsx +113 -0
- package/dist/tree/app/components/TestCard.tsx +35 -0
- package/dist/tree/app/components/index.ts +3 -0
- package/dist/tree/app/error.tsx +10 -0
- package/dist/tree/app/global-error.tsx +12 -0
- package/dist/tree/app/globals.css.gen.ts +123 -0
- package/dist/tree/app/icon.tsx.gen.ts +87 -0
- package/dist/tree/app/layout.tsx.gen.ts +55 -0
- package/dist/tree/app/locations/page.tsx +30 -0
- package/dist/tree/app/manifest.ts.gen.ts +39 -0
- package/dist/tree/app/menu/[slug]/ItemCustomizationClient.tsx +18 -0
- package/dist/tree/app/menu/[slug]/page.tsx +78 -0
- package/dist/tree/app/menu/page.tsx +36 -0
- package/dist/tree/app/not-found.tsx +8 -0
- package/dist/tree/app/opengraph-image.tsx.gen.ts +82 -0
- package/dist/tree/app/page.tsx +19 -0
- package/dist/tree/app/privacy/page.tsx.gen.ts +15 -0
- package/dist/tree/app/robots.ts +9 -0
- package/dist/tree/app/sitemap.ts +26 -0
- package/dist/tree/app/terms/page.tsx.gen.ts +16 -0
- package/dist/tree/gitignore +44 -0
- package/dist/tree/lib/zorgoSiteToken.ts +20 -0
- package/dist/tree/next.config.ts +14 -0
- package/dist/tree/open-next.config.ts +4 -0
- package/dist/tree/package.json.gen.ts +24 -0
- package/dist/tree/postcss.config.mjs +7 -0
- package/dist/tree/scripts/prebuild.ts +448 -0
- package/dist/tree/tsconfig.json +35 -0
- 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
|