@zorgo/next 1.1.7 → 1.3.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/dist/cli.js +344 -1
- package/dist/cli.js.map +1 -0
- package/dist/cli.mjs +344 -1
- package/dist/cli.mjs.map +1 -0
- package/dist/components.d.mts +315 -87
- package/dist/components.d.ts +315 -87
- package/dist/components.js +1216 -820
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +1195 -832
- package/dist/components.mjs.map +1 -1
- package/dist/images.d.mts +36 -0
- package/dist/images.d.ts +36 -0
- package/dist/images.js +62 -0
- package/dist/images.js.map +1 -0
- package/dist/images.mjs +32 -0
- package/dist/images.mjs.map +1 -0
- package/dist/index.d.mts +175 -6
- package/dist/index.d.ts +175 -6
- package/dist/index.js +162 -1
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +162 -1
- package/dist/index.mjs.map +1 -0
- package/dist/item-page.d.mts +151 -0
- package/dist/item-page.d.ts +151 -0
- package/dist/item-page.js +166 -0
- package/dist/item-page.js.map +1 -0
- package/dist/item-page.mjs +129 -0
- package/dist/item-page.mjs.map +1 -0
- package/dist/seo.d.mts +31 -1
- package/dist/seo.d.ts +31 -1
- package/dist/server.js +541 -1
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +504 -1
- package/dist/server.mjs.map +1 -0
- package/dist/slugs.js.map +1 -1
- package/dist/slugs.mjs.map +1 -1
- package/dist/tree/app/components/ClientItemForm.tsx +7 -0
- package/dist/tree/app/components/Header.tsx +3 -0
- package/dist/tree/app/components/ModalRegistry.tsx +3 -2
- package/dist/tree/app/components/index.ts +2 -1
- package/dist/tree/app/globals.css.gen.ts +1 -0
- package/dist/tree/app/menu/[slug]/page.tsx +16 -48
- package/dist/tree/gitignore +1 -0
- package/dist/tree/image-loader.ts +4 -0
- package/dist/tree/next.config.ts +12 -0
- package/package.json +11 -1
- package/dist/cli.d.mts +0 -9
- package/dist/cli.d.ts +0 -9
- package/dist/tree/app/menu/[slug]/ItemCustomizationClient.tsx +0 -18
package/dist/components.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
// src/components/CookieConsent.tsx
|
|
3
|
+
// src/components/client/CookieConsent.tsx
|
|
4
4
|
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
5
5
|
|
|
6
6
|
// ../../node_modules/@headlessui/react/dist/utils/env.js
|
|
@@ -495,7 +495,7 @@ var me = Y(Fe);
|
|
|
495
495
|
var Oe = Y(Le);
|
|
496
496
|
var Ke = Object.assign(X, { Child: Oe, Root: X });
|
|
497
497
|
|
|
498
|
-
// src/components/CookieConsent.tsx
|
|
498
|
+
// src/components/client/CookieConsent.tsx
|
|
499
499
|
import { useCustomer } from "@zorgo/next";
|
|
500
500
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
501
501
|
function CookieConsent() {
|
|
@@ -550,45 +550,19 @@ function CookieConsent() {
|
|
|
550
550
|
);
|
|
551
551
|
}
|
|
552
552
|
|
|
553
|
-
// src/components/
|
|
553
|
+
// src/components/client/GridMenu.tsx
|
|
554
|
+
import Image from "next/image";
|
|
554
555
|
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
556
|
import { menuItemSlug } from "@zorgo/next/slugs";
|
|
590
|
-
import {
|
|
591
|
-
|
|
557
|
+
import { menuImageUrl as menuImageUrl2 } from "@zorgo/next/images";
|
|
558
|
+
|
|
559
|
+
// src/images.ts
|
|
560
|
+
import { menuImageUrl } from "@zorgo/next/images";
|
|
561
|
+
var ITEM_IMAGE_PREFIX = "/images/items/";
|
|
562
|
+
|
|
563
|
+
// src/components/client/GridMenu.tsx
|
|
564
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
565
|
+
function cn(...parts) {
|
|
592
566
|
return parts.filter(Boolean).join(" ");
|
|
593
567
|
}
|
|
594
568
|
function money(cents) {
|
|
@@ -609,25 +583,25 @@ var GRID_MENU_DEFAULT_ITEM_CLASSES = {
|
|
|
609
583
|
function mergeGridMenuItemClasses(overrides) {
|
|
610
584
|
const d3 = GRID_MENU_DEFAULT_ITEM_CLASSES;
|
|
611
585
|
return {
|
|
612
|
-
baseContainer:
|
|
613
|
-
categoryContainer:
|
|
586
|
+
baseContainer: cn(d3.baseContainer, overrides?.baseContainer),
|
|
587
|
+
categoryContainer: cn(
|
|
614
588
|
d3.categoryContainer,
|
|
615
589
|
overrides?.categoryContainer
|
|
616
590
|
),
|
|
617
|
-
categoryTitle:
|
|
618
|
-
itemCardContainer:
|
|
591
|
+
categoryTitle: cn(d3.categoryTitle, overrides?.categoryTitle),
|
|
592
|
+
itemCardContainer: cn(
|
|
619
593
|
d3.itemCardContainer,
|
|
620
594
|
overrides?.itemCardContainer
|
|
621
595
|
),
|
|
622
|
-
itemCard:
|
|
623
|
-
itemCardImage:
|
|
624
|
-
itemCardTextContainer:
|
|
596
|
+
itemCard: cn(d3.itemCard, overrides?.itemCard),
|
|
597
|
+
itemCardImage: cn(d3.itemCardImage, overrides?.itemCardImage),
|
|
598
|
+
itemCardTextContainer: cn(
|
|
625
599
|
d3.itemCardTextContainer,
|
|
626
600
|
overrides?.itemCardTextContainer
|
|
627
601
|
),
|
|
628
|
-
itemCardName:
|
|
629
|
-
itemCardPrice:
|
|
630
|
-
itemCardOldPrice:
|
|
602
|
+
itemCardName: cn(d3.itemCardName, overrides?.itemCardName),
|
|
603
|
+
itemCardPrice: cn(d3.itemCardPrice, overrides?.itemCardPrice),
|
|
604
|
+
itemCardOldPrice: cn(d3.itemCardOldPrice, overrides?.itemCardOldPrice)
|
|
631
605
|
};
|
|
632
606
|
}
|
|
633
607
|
function GridMenu({
|
|
@@ -635,26 +609,25 @@ function GridMenu({
|
|
|
635
609
|
categories,
|
|
636
610
|
itemClasses
|
|
637
611
|
}) {
|
|
638
|
-
const { getItemImageUrl } = useMenu();
|
|
639
612
|
const slots = mergeGridMenuItemClasses(itemClasses);
|
|
640
|
-
return /* @__PURE__ */
|
|
613
|
+
return /* @__PURE__ */ jsx2("div", { className: slots.baseContainer, children: categories.map((category) => {
|
|
641
614
|
const itemsInCategory = items.filter(
|
|
642
615
|
(item) => item.category_id === category.category_id
|
|
643
616
|
);
|
|
644
617
|
if (itemsInCategory.length === 0) {
|
|
645
618
|
return null;
|
|
646
619
|
}
|
|
647
|
-
return /* @__PURE__ */
|
|
620
|
+
return /* @__PURE__ */ jsxs2(
|
|
648
621
|
"div",
|
|
649
622
|
{
|
|
650
623
|
className: slots.categoryContainer,
|
|
651
624
|
children: [
|
|
652
|
-
/* @__PURE__ */
|
|
653
|
-
/* @__PURE__ */
|
|
625
|
+
/* @__PURE__ */ jsx2("h1", { className: slots.categoryTitle, children: category.name }),
|
|
626
|
+
/* @__PURE__ */ jsx2("div", { className: slots.itemCardContainer, children: itemsInCategory.map((item) => /* @__PURE__ */ jsx2(
|
|
654
627
|
ItemCard,
|
|
655
628
|
{
|
|
656
629
|
item,
|
|
657
|
-
imageUrl:
|
|
630
|
+
imageUrl: menuImageUrl2(item.images?.[0]),
|
|
658
631
|
slots
|
|
659
632
|
},
|
|
660
633
|
item.base_item_id
|
|
@@ -672,40 +645,43 @@ function ItemCard({
|
|
|
672
645
|
}) {
|
|
673
646
|
const variant = item.variants[0];
|
|
674
647
|
const onSale = variant?.display_price != null && variant.display_price < variant.price;
|
|
675
|
-
return /* @__PURE__ */
|
|
676
|
-
|
|
648
|
+
return /* @__PURE__ */ jsxs2(
|
|
649
|
+
Link,
|
|
677
650
|
{
|
|
678
651
|
href: `/menu/${menuItemSlug(item.name, item.base_item_id)}`,
|
|
679
652
|
className: slots.itemCard,
|
|
680
653
|
children: [
|
|
681
|
-
/* @__PURE__ */
|
|
682
|
-
|
|
683
|
-
"img",
|
|
654
|
+
/* @__PURE__ */ jsx2("div", { className: slots.itemCardImage, children: imageUrl && /* @__PURE__ */ jsx2(
|
|
655
|
+
Image,
|
|
684
656
|
{
|
|
685
657
|
src: imageUrl,
|
|
686
658
|
alt: item.name,
|
|
659
|
+
width: 640,
|
|
660
|
+
height: 640,
|
|
661
|
+
unoptimized: !imageUrl.startsWith(ITEM_IMAGE_PREFIX),
|
|
662
|
+
sizes: "(min-width: 1024px) 320px, (min-width: 640px) 50vw, 100vw",
|
|
687
663
|
className: "w-full h-full object-cover"
|
|
688
664
|
}
|
|
689
665
|
) }),
|
|
690
|
-
/* @__PURE__ */
|
|
691
|
-
/* @__PURE__ */
|
|
692
|
-
variant && /* @__PURE__ */
|
|
693
|
-
/* @__PURE__ */
|
|
694
|
-
/* @__PURE__ */
|
|
695
|
-
] }) : /* @__PURE__ */
|
|
666
|
+
/* @__PURE__ */ jsxs2("div", { className: slots.itemCardTextContainer, children: [
|
|
667
|
+
/* @__PURE__ */ jsx2("p", { className: slots.itemCardName, children: item.name }),
|
|
668
|
+
variant && /* @__PURE__ */ jsx2(Fragment, { children: onSale ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
669
|
+
/* @__PURE__ */ jsx2("p", { className: slots.itemCardPrice, children: money(variant.display_price) }),
|
|
670
|
+
/* @__PURE__ */ jsx2("p", { className: slots.itemCardOldPrice, children: money(variant.price) })
|
|
671
|
+
] }) : /* @__PURE__ */ jsx2("p", { className: slots.itemCardPrice, children: money(variant.price) }) })
|
|
696
672
|
] })
|
|
697
673
|
]
|
|
698
674
|
}
|
|
699
675
|
);
|
|
700
676
|
}
|
|
701
677
|
|
|
702
|
-
// src/components/AccordionMenu.tsx
|
|
703
|
-
import
|
|
678
|
+
// src/components/client/AccordionMenu.tsx
|
|
679
|
+
import Link2 from "next/link";
|
|
704
680
|
import { useState as useState3 } from "react";
|
|
705
681
|
import { ChevronDown, ChevronUp } from "lucide-react";
|
|
706
682
|
import { menuItemSlug as menuItemSlug2 } from "@zorgo/next/slugs";
|
|
707
|
-
import { Fragment as Fragment2, jsx as
|
|
708
|
-
function
|
|
683
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
684
|
+
function cn2(...parts) {
|
|
709
685
|
return parts.filter(Boolean).join(" ");
|
|
710
686
|
}
|
|
711
687
|
function money2(cents) {
|
|
@@ -729,34 +705,34 @@ var ACCORDION_MENU_DEFAULT_ITEM_CLASSES = {
|
|
|
729
705
|
function mergeAccordionMenuItemClasses(overrides) {
|
|
730
706
|
const d3 = ACCORDION_MENU_DEFAULT_ITEM_CLASSES;
|
|
731
707
|
return {
|
|
732
|
-
baseContainer:
|
|
733
|
-
categoryContainer:
|
|
708
|
+
baseContainer: cn2(d3.baseContainer, overrides?.baseContainer),
|
|
709
|
+
categoryContainer: cn2(
|
|
734
710
|
d3.categoryContainer,
|
|
735
711
|
overrides?.categoryContainer
|
|
736
712
|
),
|
|
737
|
-
categoryTrigger:
|
|
738
|
-
categoryTitle:
|
|
739
|
-
categoryIndicator:
|
|
713
|
+
categoryTrigger: cn2(d3.categoryTrigger, overrides?.categoryTrigger),
|
|
714
|
+
categoryTitle: cn2(d3.categoryTitle, overrides?.categoryTitle),
|
|
715
|
+
categoryIndicator: cn2(
|
|
740
716
|
d3.categoryIndicator,
|
|
741
717
|
overrides?.categoryIndicator
|
|
742
718
|
),
|
|
743
|
-
itemsContainer:
|
|
744
|
-
itemCard:
|
|
745
|
-
itemCardTextContainer:
|
|
719
|
+
itemsContainer: cn2(d3.itemsContainer, overrides?.itemsContainer),
|
|
720
|
+
itemCard: cn2(d3.itemCard, overrides?.itemCard),
|
|
721
|
+
itemCardTextContainer: cn2(
|
|
746
722
|
d3.itemCardTextContainer,
|
|
747
723
|
overrides?.itemCardTextContainer
|
|
748
724
|
),
|
|
749
|
-
itemCardName:
|
|
750
|
-
itemCardDescription:
|
|
725
|
+
itemCardName: cn2(d3.itemCardName, overrides?.itemCardName),
|
|
726
|
+
itemCardDescription: cn2(
|
|
751
727
|
d3.itemCardDescription,
|
|
752
728
|
overrides?.itemCardDescription
|
|
753
729
|
),
|
|
754
|
-
itemCardPriceContainer:
|
|
730
|
+
itemCardPriceContainer: cn2(
|
|
755
731
|
d3.itemCardPriceContainer,
|
|
756
732
|
overrides?.itemCardPriceContainer
|
|
757
733
|
),
|
|
758
|
-
itemCardPrice:
|
|
759
|
-
itemCardOldPrice:
|
|
734
|
+
itemCardPrice: cn2(d3.itemCardPrice, overrides?.itemCardPrice),
|
|
735
|
+
itemCardOldPrice: cn2(d3.itemCardOldPrice, overrides?.itemCardOldPrice)
|
|
760
736
|
};
|
|
761
737
|
}
|
|
762
738
|
function AccordionMenu({
|
|
@@ -765,14 +741,14 @@ function AccordionMenu({
|
|
|
765
741
|
itemClasses
|
|
766
742
|
}) {
|
|
767
743
|
const slots = mergeAccordionMenuItemClasses(itemClasses);
|
|
768
|
-
return /* @__PURE__ */
|
|
744
|
+
return /* @__PURE__ */ jsx3("div", { className: slots.baseContainer, children: categories.map((category) => {
|
|
769
745
|
const itemsInCategory = items.filter(
|
|
770
746
|
(item) => item.category_id === category.category_id
|
|
771
747
|
);
|
|
772
748
|
if (itemsInCategory.length === 0) {
|
|
773
749
|
return null;
|
|
774
750
|
}
|
|
775
|
-
return /* @__PURE__ */
|
|
751
|
+
return /* @__PURE__ */ jsx3(
|
|
776
752
|
MenuCategory,
|
|
777
753
|
{
|
|
778
754
|
category,
|
|
@@ -789,27 +765,27 @@ function MenuCategory({
|
|
|
789
765
|
slots
|
|
790
766
|
}) {
|
|
791
767
|
const [isExpanded, setIsExpanded] = useState3(false);
|
|
792
|
-
return /* @__PURE__ */
|
|
793
|
-
/* @__PURE__ */
|
|
768
|
+
return /* @__PURE__ */ jsxs3("div", { className: slots.categoryContainer, children: [
|
|
769
|
+
/* @__PURE__ */ jsxs3(
|
|
794
770
|
"button",
|
|
795
771
|
{
|
|
796
772
|
type: "button",
|
|
797
773
|
onClick: () => setIsExpanded(!isExpanded),
|
|
798
774
|
className: slots.categoryTrigger,
|
|
799
775
|
children: [
|
|
800
|
-
/* @__PURE__ */
|
|
801
|
-
isExpanded ? /* @__PURE__ */
|
|
776
|
+
/* @__PURE__ */ jsx3("h2", { className: slots.categoryTitle, children: category.name }),
|
|
777
|
+
isExpanded ? /* @__PURE__ */ jsx3(ChevronUp, { className: slots.categoryIndicator }) : /* @__PURE__ */ jsx3(ChevronDown, { className: slots.categoryIndicator })
|
|
802
778
|
]
|
|
803
779
|
}
|
|
804
780
|
),
|
|
805
|
-
/* @__PURE__ */
|
|
781
|
+
/* @__PURE__ */ jsx3(
|
|
806
782
|
"div",
|
|
807
783
|
{
|
|
808
|
-
className:
|
|
784
|
+
className: cn2(
|
|
809
785
|
isExpanded ? "flex" : "hidden",
|
|
810
786
|
slots.itemsContainer
|
|
811
787
|
),
|
|
812
|
-
children: itemsInCategory.map((item) => /* @__PURE__ */
|
|
788
|
+
children: itemsInCategory.map((item) => /* @__PURE__ */ jsx3(
|
|
813
789
|
ItemCard2,
|
|
814
790
|
{
|
|
815
791
|
item,
|
|
@@ -827,36 +803,33 @@ function ItemCard2({
|
|
|
827
803
|
}) {
|
|
828
804
|
const variant = item.variants[0];
|
|
829
805
|
const onSale = variant?.display_price != null && variant.display_price < variant.price;
|
|
830
|
-
return /* @__PURE__ */
|
|
831
|
-
|
|
806
|
+
return /* @__PURE__ */ jsxs3(
|
|
807
|
+
Link2,
|
|
832
808
|
{
|
|
833
809
|
href: `/menu/${menuItemSlug2(item.name, item.base_item_id)}`,
|
|
834
810
|
className: slots.itemCard,
|
|
835
811
|
children: [
|
|
836
|
-
/* @__PURE__ */
|
|
837
|
-
/* @__PURE__ */
|
|
838
|
-
item.description && /* @__PURE__ */
|
|
812
|
+
/* @__PURE__ */ jsxs3("div", { className: slots.itemCardTextContainer, children: [
|
|
813
|
+
/* @__PURE__ */ jsx3("p", { className: slots.itemCardName, children: item.name }),
|
|
814
|
+
item.description && /* @__PURE__ */ jsx3("p", { className: slots.itemCardDescription, children: item.description })
|
|
839
815
|
] }),
|
|
840
|
-
variant && /* @__PURE__ */
|
|
841
|
-
/* @__PURE__ */
|
|
842
|
-
/* @__PURE__ */
|
|
843
|
-
] }) : /* @__PURE__ */
|
|
816
|
+
variant && /* @__PURE__ */ jsx3("div", { className: slots.itemCardPriceContainer, children: onSale ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
817
|
+
/* @__PURE__ */ jsx3("p", { className: slots.itemCardPrice, children: money2(variant.display_price) }),
|
|
818
|
+
/* @__PURE__ */ jsx3("p", { className: slots.itemCardOldPrice, children: money2(variant.price) })
|
|
819
|
+
] }) : /* @__PURE__ */ jsx3("p", { className: slots.itemCardPrice, children: money2(variant.price) }) })
|
|
844
820
|
]
|
|
845
821
|
}
|
|
846
822
|
);
|
|
847
823
|
}
|
|
848
824
|
|
|
849
|
-
// src/components/
|
|
850
|
-
|
|
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) {
|
|
825
|
+
// src/components/client/ItemForm/classes.ts
|
|
826
|
+
function cn3(...parts) {
|
|
854
827
|
return parts.filter(Boolean).join(" ");
|
|
855
828
|
}
|
|
856
829
|
function money3(cents) {
|
|
857
830
|
return `$${(cents / 100).toFixed(2)}`;
|
|
858
831
|
}
|
|
859
|
-
var
|
|
832
|
+
var CLIENT_ITEM_FORM_DEFAULT_ITEM_CLASSES = {
|
|
860
833
|
baseContainer: "flex flex-col gap-8",
|
|
861
834
|
title: "text-4xl font-extrabold text-primary",
|
|
862
835
|
description: "opacity-70 text-xl",
|
|
@@ -874,57 +847,496 @@ var ITEM_CUSTOMIZATION_FORM_DEFAULT_ITEM_CLASSES = {
|
|
|
874
847
|
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
848
|
servingsValue: "w-8 md:w-12 font-semibold opacity-75 text-center",
|
|
876
849
|
ruleError: "text-sm text-red-500",
|
|
850
|
+
portionHint: "text-base font-normal opacity-60",
|
|
877
851
|
commentsTextarea: "p-4 rounded-xl border-3 border-foreground/[15%] outline-none resize-none",
|
|
878
852
|
quantityRow: "flex flex-row items-center gap-4 text-xl",
|
|
879
853
|
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
854
|
notFound: ""
|
|
881
855
|
};
|
|
882
|
-
function
|
|
883
|
-
const d3 =
|
|
856
|
+
function mergeClientItemFormItemClasses(overrides) {
|
|
857
|
+
const d3 = CLIENT_ITEM_FORM_DEFAULT_ITEM_CLASSES;
|
|
884
858
|
return {
|
|
885
|
-
baseContainer:
|
|
886
|
-
title:
|
|
887
|
-
description:
|
|
888
|
-
section:
|
|
889
|
-
sectionTitle:
|
|
890
|
-
optionsRow:
|
|
891
|
-
optionButton:
|
|
892
|
-
optionButtonSelected:
|
|
859
|
+
baseContainer: cn3(d3.baseContainer, overrides?.baseContainer),
|
|
860
|
+
title: cn3(d3.title, overrides?.title),
|
|
861
|
+
description: cn3(d3.description, overrides?.description),
|
|
862
|
+
section: cn3(d3.section, overrides?.section),
|
|
863
|
+
sectionTitle: cn3(d3.sectionTitle, overrides?.sectionTitle),
|
|
864
|
+
optionsRow: cn3(d3.optionsRow, overrides?.optionsRow),
|
|
865
|
+
optionButton: cn3(d3.optionButton, overrides?.optionButton),
|
|
866
|
+
optionButtonSelected: cn3(
|
|
893
867
|
d3.optionButtonSelected,
|
|
894
868
|
overrides?.optionButtonSelected
|
|
895
869
|
),
|
|
896
|
-
optionButtonUnselected:
|
|
870
|
+
optionButtonUnselected: cn3(
|
|
897
871
|
d3.optionButtonUnselected,
|
|
898
872
|
overrides?.optionButtonUnselected
|
|
899
873
|
),
|
|
900
|
-
optionButtonLabel:
|
|
874
|
+
optionButtonLabel: cn3(
|
|
901
875
|
d3.optionButtonLabel,
|
|
902
876
|
overrides?.optionButtonLabel
|
|
903
877
|
),
|
|
904
|
-
optionButtonUpcharge:
|
|
878
|
+
optionButtonUpcharge: cn3(
|
|
905
879
|
d3.optionButtonUpcharge,
|
|
906
880
|
overrides?.optionButtonUpcharge
|
|
907
881
|
),
|
|
908
|
-
servingsRow:
|
|
909
|
-
servingsLabel:
|
|
910
|
-
servingsControls:
|
|
911
|
-
incrementButton:
|
|
912
|
-
servingsValue:
|
|
913
|
-
ruleError:
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
882
|
+
servingsRow: cn3(d3.servingsRow, overrides?.servingsRow),
|
|
883
|
+
servingsLabel: cn3(d3.servingsLabel, overrides?.servingsLabel),
|
|
884
|
+
servingsControls: cn3(d3.servingsControls, overrides?.servingsControls),
|
|
885
|
+
incrementButton: cn3(d3.incrementButton, overrides?.incrementButton),
|
|
886
|
+
servingsValue: cn3(d3.servingsValue, overrides?.servingsValue),
|
|
887
|
+
ruleError: cn3(d3.ruleError, overrides?.ruleError),
|
|
888
|
+
portionHint: cn3(d3.portionHint, overrides?.portionHint),
|
|
889
|
+
commentsTextarea: cn3(d3.commentsTextarea, overrides?.commentsTextarea),
|
|
890
|
+
quantityRow: cn3(d3.quantityRow, overrides?.quantityRow),
|
|
891
|
+
submitButton: cn3(d3.submitButton, overrides?.submitButton),
|
|
892
|
+
notFound: cn3(d3.notFound, overrides?.notFound)
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
var CLIENT_ITEM_FORM_SLOTS = mergeClientItemFormItemClasses();
|
|
896
|
+
|
|
897
|
+
// src/components/client/ItemForm/ClientItemForm.tsx
|
|
898
|
+
import { useState as useState4 } from "react";
|
|
899
|
+
import { useRouter } from "next/navigation";
|
|
900
|
+
import { useItemCustomization, useMenu } from "@zorgo/next";
|
|
901
|
+
|
|
902
|
+
// src/components/client/ItemForm/Breadcrumbs.tsx
|
|
903
|
+
import Link3 from "next/link";
|
|
904
|
+
import { ChevronRight } from "lucide-react";
|
|
905
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
906
|
+
function cn4(...parts) {
|
|
907
|
+
return parts.filter(Boolean).join(" ");
|
|
908
|
+
}
|
|
909
|
+
var BREADCRUMBS_DEFAULT_ITEM_CLASSES = {
|
|
910
|
+
baseContainer: "flex flex-row items-center gap-2 text-sm opacity-75",
|
|
911
|
+
crumbLink: "hover:opacity-75 transition-all duration-300 underline-offset-2 hover:underline",
|
|
912
|
+
crumbText: "font-semibold",
|
|
913
|
+
separator: "h-4 w-4 opacity-50"
|
|
914
|
+
};
|
|
915
|
+
function mergeBreadcrumbsItemClasses(overrides) {
|
|
916
|
+
const d3 = BREADCRUMBS_DEFAULT_ITEM_CLASSES;
|
|
917
|
+
return {
|
|
918
|
+
baseContainer: cn4(d3.baseContainer, overrides?.baseContainer),
|
|
919
|
+
crumbLink: cn4(d3.crumbLink, overrides?.crumbLink),
|
|
920
|
+
crumbText: cn4(d3.crumbText, overrides?.crumbText),
|
|
921
|
+
separator: cn4(d3.separator, overrides?.separator)
|
|
918
922
|
};
|
|
919
923
|
}
|
|
920
|
-
function
|
|
924
|
+
function Breadcrumbs({
|
|
925
|
+
items,
|
|
926
|
+
itemClasses
|
|
927
|
+
}) {
|
|
928
|
+
const slots = mergeBreadcrumbsItemClasses(itemClasses);
|
|
929
|
+
return /* @__PURE__ */ jsx4("nav", { "aria-label": "Breadcrumb", className: slots.baseContainer, children: items.map((item, index) => /* @__PURE__ */ jsxs4("span", { className: "flex flex-row items-center gap-2", children: [
|
|
930
|
+
index > 0 && /* @__PURE__ */ jsx4(ChevronRight, { className: slots.separator }),
|
|
931
|
+
item.href ? /* @__PURE__ */ jsx4(Link3, { href: item.href, className: slots.crumbLink, children: item.label }) : /* @__PURE__ */ jsx4("span", { className: slots.crumbText, children: item.label })
|
|
932
|
+
] }, `${item.label}-${index}`)) });
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
// src/components/client/ItemForm/CommentsSection.tsx
|
|
936
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
937
|
+
function CommentsSection({
|
|
938
|
+
comments,
|
|
939
|
+
setComments,
|
|
940
|
+
title = "Comments",
|
|
941
|
+
placeholder = "Special instructions...",
|
|
942
|
+
rows = 2,
|
|
943
|
+
slots = CLIENT_ITEM_FORM_SLOTS
|
|
944
|
+
}) {
|
|
945
|
+
return /* @__PURE__ */ jsxs5("div", { className: slots.section, children: [
|
|
946
|
+
/* @__PURE__ */ jsx5("h2", { className: slots.sectionTitle, children: title }),
|
|
947
|
+
/* @__PURE__ */ jsx5(
|
|
948
|
+
"textarea",
|
|
949
|
+
{
|
|
950
|
+
value: comments,
|
|
951
|
+
onChange: (e) => setComments(e.target.value),
|
|
952
|
+
placeholder,
|
|
953
|
+
className: slots.commentsTextarea,
|
|
954
|
+
rows
|
|
955
|
+
}
|
|
956
|
+
)
|
|
957
|
+
] });
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
// src/components/client/ItemForm/ComponentsSection.tsx
|
|
961
|
+
import { portionLabel } from "@zorgo/next";
|
|
962
|
+
|
|
963
|
+
// src/components/client/ItemForm/OptionButton.tsx
|
|
964
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
965
|
+
function OptionButton({
|
|
966
|
+
label,
|
|
967
|
+
subtext,
|
|
968
|
+
selected,
|
|
969
|
+
onClick,
|
|
970
|
+
slots = CLIENT_ITEM_FORM_SLOTS
|
|
971
|
+
}) {
|
|
972
|
+
return /* @__PURE__ */ jsxs6(
|
|
973
|
+
"button",
|
|
974
|
+
{
|
|
975
|
+
type: "button",
|
|
976
|
+
onClick,
|
|
977
|
+
className: cn3(
|
|
978
|
+
slots.optionButton,
|
|
979
|
+
selected ? slots.optionButtonSelected : slots.optionButtonUnselected
|
|
980
|
+
),
|
|
981
|
+
children: [
|
|
982
|
+
/* @__PURE__ */ jsx6("span", { className: slots.optionButtonLabel, children: label }),
|
|
983
|
+
subtext && /* @__PURE__ */ jsx6("span", { className: slots.optionButtonUpcharge, children: subtext })
|
|
984
|
+
]
|
|
985
|
+
}
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
// src/components/client/ItemForm/ComponentsSection.tsx
|
|
990
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
991
|
+
function ComponentsSection({
|
|
992
|
+
variant,
|
|
993
|
+
draft,
|
|
994
|
+
setComponentServings,
|
|
995
|
+
activeSection = null,
|
|
996
|
+
divisions = 1,
|
|
997
|
+
scheme,
|
|
998
|
+
title = "Includes",
|
|
999
|
+
slots = CLIENT_ITEM_FORM_SLOTS
|
|
1000
|
+
}) {
|
|
1001
|
+
const components = variant.components ?? [];
|
|
1002
|
+
if (components.length === 0) return null;
|
|
1003
|
+
const portion = activeSection != null ? `${activeSection}/${divisions}` : null;
|
|
1004
|
+
return /* @__PURE__ */ jsxs7("div", { className: slots.section, children: [
|
|
1005
|
+
/* @__PURE__ */ jsx7("h2", { className: slots.sectionTitle, children: title }),
|
|
1006
|
+
/* @__PURE__ */ jsx7("div", { className: slots.optionsRow, children: components.map((component) => {
|
|
1007
|
+
const defaultServings = component.servings_per_item ?? 1;
|
|
1008
|
+
const rows = (draft?.components ?? []).filter(
|
|
1009
|
+
(c6) => c6.id === component.id
|
|
1010
|
+
);
|
|
1011
|
+
const row = rows.find((c6) => c6.portion === portion) ?? rows.find((c6) => !c6.portion);
|
|
1012
|
+
const servings = row?.quantity_servings ?? defaultServings;
|
|
1013
|
+
const selected = servings > 0;
|
|
1014
|
+
const removedElsewhere = !portion && rows.some((c6) => c6.quantity_servings === 0);
|
|
1015
|
+
return /* @__PURE__ */ jsx7(
|
|
1016
|
+
OptionButton,
|
|
1017
|
+
{
|
|
1018
|
+
label: component.name,
|
|
1019
|
+
subtext: removedElsewhere && scheme ? `No ${component.name.toLowerCase()} on ${rows.filter((c6) => c6.quantity_servings === 0).map(
|
|
1020
|
+
(c6) => portionLabel(c6.portion, scheme).toLowerCase()
|
|
1021
|
+
).join(", ")}` : void 0,
|
|
1022
|
+
selected,
|
|
1023
|
+
onClick: () => setComponentServings(
|
|
1024
|
+
component.id,
|
|
1025
|
+
selected ? 0 : defaultServings,
|
|
1026
|
+
portion
|
|
1027
|
+
),
|
|
1028
|
+
slots
|
|
1029
|
+
},
|
|
1030
|
+
component.id
|
|
1031
|
+
);
|
|
1032
|
+
}) })
|
|
1033
|
+
] });
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
// src/components/client/ItemForm/PortionPicker.tsx
|
|
1037
|
+
import {
|
|
1038
|
+
divisionsFor,
|
|
1039
|
+
portionLabel as portionLabel2,
|
|
1040
|
+
radialSectionPath
|
|
1041
|
+
} from "@zorgo/next";
|
|
1042
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1043
|
+
function cn5(...parts) {
|
|
1044
|
+
return parts.filter(Boolean).join(" ");
|
|
1045
|
+
}
|
|
1046
|
+
var SECTION_FILL = "var(--color-background-elevated, #fff)";
|
|
1047
|
+
function sectionClass(isActive, isCovered) {
|
|
1048
|
+
return cn5(
|
|
1049
|
+
"transition-all duration-200 cursor-pointer",
|
|
1050
|
+
isActive ? "fill-primary stroke-primary" : isCovered ? "fill-primary/30 stroke-foreground/20" : "stroke-foreground/20 hover:fill-primary/10"
|
|
1051
|
+
);
|
|
1052
|
+
}
|
|
1053
|
+
function RadialPicker({ divisions, active, covered = [], onSelect }) {
|
|
1054
|
+
return /* @__PURE__ */ jsx8("svg", { viewBox: "0 0 100 100", className: "w-32 h-32", role: "group", children: Array.from({ length: divisions }, (_, i4) => {
|
|
1055
|
+
const index = i4 + 1;
|
|
1056
|
+
return /* @__PURE__ */ jsx8(
|
|
1057
|
+
"path",
|
|
1058
|
+
{
|
|
1059
|
+
d: radialSectionPath(index, divisions),
|
|
1060
|
+
strokeWidth: 2,
|
|
1061
|
+
style: { fill: SECTION_FILL },
|
|
1062
|
+
className: sectionClass(active === index, covered.includes(index)),
|
|
1063
|
+
onClick: () => onSelect(active === index ? null : index)
|
|
1064
|
+
},
|
|
1065
|
+
index
|
|
1066
|
+
);
|
|
1067
|
+
}) });
|
|
1068
|
+
}
|
|
1069
|
+
function GridPicker({ divisions, active, covered = [], onSelect }) {
|
|
1070
|
+
const cols = Math.ceil(Math.sqrt(divisions));
|
|
1071
|
+
const rows = Math.ceil(divisions / cols);
|
|
1072
|
+
return /* @__PURE__ */ jsx8(
|
|
1073
|
+
"div",
|
|
1074
|
+
{
|
|
1075
|
+
className: "grid gap-1 w-32 h-32",
|
|
1076
|
+
style: {
|
|
1077
|
+
gridTemplateColumns: `repeat(${cols}, 1fr)`,
|
|
1078
|
+
gridTemplateRows: `repeat(${rows}, 1fr)`,
|
|
1079
|
+
gridAutoFlow: "column"
|
|
1080
|
+
},
|
|
1081
|
+
children: Array.from({ length: divisions }, (_, i4) => {
|
|
1082
|
+
const index = i4 + 1;
|
|
1083
|
+
return /* @__PURE__ */ jsx8(
|
|
1084
|
+
"button",
|
|
1085
|
+
{
|
|
1086
|
+
type: "button",
|
|
1087
|
+
"aria-pressed": active === index,
|
|
1088
|
+
onClick: () => onSelect(active === index ? null : index),
|
|
1089
|
+
className: cn5(
|
|
1090
|
+
"rounded-lg border-3 transition-all duration-200",
|
|
1091
|
+
active === index ? "bg-primary border-primary" : covered.includes(index) ? "bg-primary/30 border-foreground/15" : "bg-background-elevated border-foreground/15 hover:bg-primary/10"
|
|
1092
|
+
)
|
|
1093
|
+
},
|
|
1094
|
+
index
|
|
1095
|
+
);
|
|
1096
|
+
})
|
|
1097
|
+
}
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
function LinearPicker({ divisions, active, covered = [], onSelect }) {
|
|
1101
|
+
return /* @__PURE__ */ jsx8("div", { className: "flex flex-row w-full max-w-xs h-12 gap-1", children: Array.from({ length: divisions }, (_, i4) => {
|
|
1102
|
+
const index = i4 + 1;
|
|
1103
|
+
return /* @__PURE__ */ jsx8(
|
|
1104
|
+
"button",
|
|
1105
|
+
{
|
|
1106
|
+
type: "button",
|
|
1107
|
+
"aria-pressed": active === index,
|
|
1108
|
+
onClick: () => onSelect(active === index ? null : index),
|
|
1109
|
+
className: cn5(
|
|
1110
|
+
"flex-1 rounded-lg border-3 transition-all duration-200",
|
|
1111
|
+
active === index ? "bg-primary border-primary" : covered.includes(index) ? "bg-primary/30 border-foreground/15" : "bg-background-elevated border-foreground/15 hover:bg-primary/10"
|
|
1112
|
+
)
|
|
1113
|
+
},
|
|
1114
|
+
index
|
|
1115
|
+
);
|
|
1116
|
+
}) });
|
|
1117
|
+
}
|
|
1118
|
+
function CountPicker({
|
|
1119
|
+
divisions,
|
|
1120
|
+
active,
|
|
1121
|
+
covered = [],
|
|
1122
|
+
onSelect,
|
|
1123
|
+
scheme
|
|
1124
|
+
}) {
|
|
1125
|
+
return /* @__PURE__ */ jsx8("div", { className: "flex flex-row flex-wrap gap-2", children: Array.from({ length: divisions }, (_, i4) => {
|
|
1126
|
+
const index = i4 + 1;
|
|
1127
|
+
return /* @__PURE__ */ jsx8(
|
|
1128
|
+
"button",
|
|
1129
|
+
{
|
|
1130
|
+
type: "button",
|
|
1131
|
+
"aria-pressed": active === index,
|
|
1132
|
+
onClick: () => onSelect(active === index ? null : index),
|
|
1133
|
+
className: cn5(
|
|
1134
|
+
"px-4 py-2 rounded-xl border-3 font-semibold transition-all duration-200",
|
|
1135
|
+
active === index ? "bg-primary text-primary-foreground border-primary" : covered.includes(index) ? "bg-primary/30 border-foreground/15" : "bg-background-elevated border-foreground/15 hover:bg-primary/10"
|
|
1136
|
+
),
|
|
1137
|
+
children: portionLabel2(`${index}/${divisions}`, scheme)
|
|
1138
|
+
},
|
|
1139
|
+
index
|
|
1140
|
+
);
|
|
1141
|
+
}) });
|
|
1142
|
+
}
|
|
1143
|
+
function PortionPicker({
|
|
1144
|
+
scheme,
|
|
1145
|
+
divisions,
|
|
1146
|
+
active,
|
|
1147
|
+
covered,
|
|
1148
|
+
onSelect,
|
|
1149
|
+
onDivisionsChange,
|
|
1150
|
+
className
|
|
1151
|
+
}) {
|
|
1152
|
+
const cuts = divisionsFor(scheme);
|
|
1153
|
+
const shapeProps = { divisions, active, covered, onSelect };
|
|
1154
|
+
return /* @__PURE__ */ jsxs8("div", { className: cn5("flex flex-col gap-4 items-center", className), children: [
|
|
1155
|
+
cuts.length > 1 && /* @__PURE__ */ jsx8("div", { className: "flex flex-row gap-2", children: cuts.map((count) => /* @__PURE__ */ jsx8(
|
|
1156
|
+
"button",
|
|
1157
|
+
{
|
|
1158
|
+
type: "button",
|
|
1159
|
+
"aria-pressed": divisions === count,
|
|
1160
|
+
onClick: () => onDivisionsChange(count),
|
|
1161
|
+
className: cn5(
|
|
1162
|
+
"px-4 py-2 rounded-xl border-3 font-semibold transition-all duration-200",
|
|
1163
|
+
divisions === count ? "bg-primary text-primary-foreground border-primary" : "bg-background-elevated border-foreground/15 hover:bg-primary/10"
|
|
1164
|
+
),
|
|
1165
|
+
children: count === 1 ? "Whole" : `${count} parts`
|
|
1166
|
+
},
|
|
1167
|
+
count
|
|
1168
|
+
)) }),
|
|
1169
|
+
divisions > 1 && /* @__PURE__ */ jsxs8(Fragment3, { children: [
|
|
1170
|
+
scheme.geometry === "radial" && /* @__PURE__ */ jsx8(RadialPicker, { ...shapeProps }),
|
|
1171
|
+
scheme.geometry === "grid" && /* @__PURE__ */ jsx8(GridPicker, { ...shapeProps }),
|
|
1172
|
+
scheme.geometry === "linear" && /* @__PURE__ */ jsx8(LinearPicker, { ...shapeProps }),
|
|
1173
|
+
scheme.geometry === "count" && /* @__PURE__ */ jsx8(CountPicker, { ...shapeProps, scheme })
|
|
1174
|
+
] }),
|
|
1175
|
+
/* @__PURE__ */ jsx8("p", { className: "opacity-70", children: active == null ? divisions > 1 ? "Editing the whole item \u2014 tap a section to edit just that part" : "Editing the whole item" : `Editing ${portionLabel2(`${active}/${divisions}`, scheme).toLowerCase()}` })
|
|
1176
|
+
] });
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
// src/components/client/ItemForm/PortionSection.tsx
|
|
1180
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1181
|
+
function PortionSection({
|
|
1182
|
+
scheme,
|
|
1183
|
+
divisions,
|
|
1184
|
+
activeSection,
|
|
1185
|
+
setActiveSection,
|
|
1186
|
+
setDivisions,
|
|
1187
|
+
slots = CLIENT_ITEM_FORM_SLOTS
|
|
1188
|
+
}) {
|
|
1189
|
+
return /* @__PURE__ */ jsxs9("div", { className: slots.section, children: [
|
|
1190
|
+
/* @__PURE__ */ jsx9("h2", { className: slots.sectionTitle, children: scheme.name }),
|
|
1191
|
+
/* @__PURE__ */ jsx9(
|
|
1192
|
+
PortionPicker,
|
|
1193
|
+
{
|
|
1194
|
+
scheme,
|
|
1195
|
+
divisions,
|
|
1196
|
+
active: activeSection,
|
|
1197
|
+
onSelect: setActiveSection,
|
|
1198
|
+
onDivisionsChange: setDivisions
|
|
1199
|
+
}
|
|
1200
|
+
)
|
|
1201
|
+
] });
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
// src/components/client/ItemForm/QuantitySection.tsx
|
|
1205
|
+
import { Minus, Plus } from "lucide-react";
|
|
1206
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1207
|
+
function QuantitySection({
|
|
1208
|
+
quantity,
|
|
1209
|
+
setQuantity,
|
|
1210
|
+
title = "How many?",
|
|
1211
|
+
slots = CLIENT_ITEM_FORM_SLOTS
|
|
1212
|
+
}) {
|
|
1213
|
+
return /* @__PURE__ */ jsxs10("div", { className: slots.section, children: [
|
|
1214
|
+
/* @__PURE__ */ jsx10("h2", { className: slots.sectionTitle, children: title }),
|
|
1215
|
+
/* @__PURE__ */ jsxs10("div", { className: slots.quantityRow, children: [
|
|
1216
|
+
/* @__PURE__ */ jsx10(
|
|
1217
|
+
"button",
|
|
1218
|
+
{
|
|
1219
|
+
type: "button",
|
|
1220
|
+
className: slots.incrementButton,
|
|
1221
|
+
onClick: () => setQuantity((q2) => q2 - 1),
|
|
1222
|
+
children: /* @__PURE__ */ jsx10(Minus, { className: "h-4 w-4" })
|
|
1223
|
+
}
|
|
1224
|
+
),
|
|
1225
|
+
/* @__PURE__ */ jsx10("p", { className: slots.servingsValue, children: quantity }),
|
|
1226
|
+
/* @__PURE__ */ jsx10(
|
|
1227
|
+
"button",
|
|
1228
|
+
{
|
|
1229
|
+
type: "button",
|
|
1230
|
+
className: slots.incrementButton,
|
|
1231
|
+
onClick: () => setQuantity((q2) => q2 + 1),
|
|
1232
|
+
children: /* @__PURE__ */ jsx10(Plus, { className: "h-4 w-4" })
|
|
1233
|
+
}
|
|
1234
|
+
)
|
|
1235
|
+
] })
|
|
1236
|
+
] });
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
// src/components/client/ItemForm/RuleSection.tsx
|
|
1240
|
+
import { parsePortionKey, portionLabel as portionLabel3 } from "@zorgo/next";
|
|
1241
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1242
|
+
function RuleSection({
|
|
1243
|
+
rule,
|
|
1244
|
+
activeSection = null,
|
|
1245
|
+
divisions = 1,
|
|
1246
|
+
scheme,
|
|
1247
|
+
placeOption,
|
|
1248
|
+
slots = CLIENT_ITEM_FORM_SLOTS
|
|
1249
|
+
}) {
|
|
1250
|
+
const portion = rule.portionable && activeSection != null ? `${activeSection}/${divisions}` : null;
|
|
1251
|
+
return /* @__PURE__ */ jsxs11("div", { className: slots.section, children: [
|
|
1252
|
+
/* @__PURE__ */ jsxs11("h2", { className: slots.sectionTitle, children: [
|
|
1253
|
+
rule.group_name,
|
|
1254
|
+
activeSection != null && !rule.portionable && /* @__PURE__ */ jsx11("span", { className: slots.portionHint, children: " \u2014 whole item only" })
|
|
1255
|
+
] }),
|
|
1256
|
+
/* @__PURE__ */ jsx11("div", { className: slots.optionsRow, children: rule.options.map((option) => /* @__PURE__ */ jsx11(
|
|
1257
|
+
OptionButton,
|
|
1258
|
+
{
|
|
1259
|
+
label: option.name,
|
|
1260
|
+
subtext: (
|
|
1261
|
+
// where it sits beats what it costs — the price is
|
|
1262
|
+
// already in the running total
|
|
1263
|
+
option.portion && scheme ? portionLabel3(option.portion, scheme) : option.upcharge > 0 ? `+${money3(option.upcharge)}` : void 0
|
|
1264
|
+
),
|
|
1265
|
+
selected: option.selected,
|
|
1266
|
+
onClick: () => placeOption ? placeOption(
|
|
1267
|
+
rule.rule_id,
|
|
1268
|
+
parsePortionKey(option.key).baseKey,
|
|
1269
|
+
portion,
|
|
1270
|
+
rule.max
|
|
1271
|
+
) : option.toggle(),
|
|
1272
|
+
slots
|
|
1273
|
+
},
|
|
1274
|
+
parsePortionKey(option.key).baseKey
|
|
1275
|
+
)) }),
|
|
1276
|
+
rule.message() && /* @__PURE__ */ jsx11("p", { className: slots.ruleError, children: rule.message() })
|
|
1277
|
+
] });
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
// src/components/client/ItemForm/SubmitButton.tsx
|
|
1281
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1282
|
+
function SubmitButton({
|
|
1283
|
+
canSubmit,
|
|
1284
|
+
unmetRule,
|
|
1285
|
+
price,
|
|
1286
|
+
salePrice,
|
|
1287
|
+
isEditMode,
|
|
1288
|
+
onSubmit,
|
|
1289
|
+
slots = CLIENT_ITEM_FORM_SLOTS
|
|
1290
|
+
}) {
|
|
1291
|
+
return /* @__PURE__ */ jsx12(
|
|
1292
|
+
"button",
|
|
1293
|
+
{
|
|
1294
|
+
type: "button",
|
|
1295
|
+
disabled: !canSubmit,
|
|
1296
|
+
onClick: onSubmit,
|
|
1297
|
+
className: slots.submitButton,
|
|
1298
|
+
children: unmetRule ? `Choose ${unmetRule.group_name}` : `${isEditMode ? "Save changes" : "Add to cart"} \u2014 ${money3(salePrice ?? price)}`
|
|
1299
|
+
}
|
|
1300
|
+
);
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
// src/components/client/ItemForm/VariantSection.tsx
|
|
1304
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1305
|
+
function VariantSection({
|
|
1306
|
+
variants,
|
|
1307
|
+
variant,
|
|
1308
|
+
setVariant,
|
|
1309
|
+
title = "Variants",
|
|
1310
|
+
slots = CLIENT_ITEM_FORM_SLOTS
|
|
1311
|
+
}) {
|
|
1312
|
+
if (variants.length <= 1) return null;
|
|
1313
|
+
return /* @__PURE__ */ jsxs12("div", { className: slots.section, children: [
|
|
1314
|
+
/* @__PURE__ */ jsx13("h2", { className: slots.sectionTitle, children: title }),
|
|
1315
|
+
/* @__PURE__ */ jsx13("div", { className: slots.optionsRow, children: variants.map((v2) => /* @__PURE__ */ jsx13(
|
|
1316
|
+
OptionButton,
|
|
1317
|
+
{
|
|
1318
|
+
label: v2.name,
|
|
1319
|
+
subtext: money3(v2.price),
|
|
1320
|
+
selected: v2.item_id === variant.item_id,
|
|
1321
|
+
onClick: () => setVariant(v2),
|
|
1322
|
+
slots
|
|
1323
|
+
},
|
|
1324
|
+
v2.item_id
|
|
1325
|
+
)) })
|
|
1326
|
+
] });
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
// src/components/client/ItemForm/ClientItemForm.tsx
|
|
1330
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1331
|
+
function ClientItemForm({
|
|
921
1332
|
baseItemId,
|
|
922
1333
|
seed,
|
|
923
1334
|
editIndex,
|
|
924
1335
|
itemClasses,
|
|
925
1336
|
onSubmitSuccess
|
|
926
1337
|
}) {
|
|
927
|
-
const
|
|
1338
|
+
const router = useRouter();
|
|
1339
|
+
const slots = mergeClientItemFormItemClasses(itemClasses);
|
|
928
1340
|
const {
|
|
929
1341
|
item,
|
|
930
1342
|
variant,
|
|
@@ -942,17 +1354,21 @@ function ItemCustomizationForm({
|
|
|
942
1354
|
price,
|
|
943
1355
|
salePrice,
|
|
944
1356
|
isEditMode,
|
|
945
|
-
draft
|
|
1357
|
+
draft,
|
|
1358
|
+
portionScheme,
|
|
1359
|
+
placeOption,
|
|
1360
|
+
recutSelections
|
|
946
1361
|
} = useItemCustomization(baseItemId, seed, editIndex);
|
|
947
|
-
const { categories } =
|
|
1362
|
+
const { categories } = useMenu();
|
|
1363
|
+
const [cut, setCut] = useState4(1);
|
|
1364
|
+
const [activeSection, setActiveSection] = useState4(null);
|
|
1365
|
+
const divisions = portionScheme ? Math.min(Math.max(cut, portionScheme.min_divisions), portionScheme.max_divisions) : 1;
|
|
948
1366
|
if (!item) {
|
|
949
|
-
return /* @__PURE__ */
|
|
1367
|
+
return /* @__PURE__ */ jsx14("div", { className: slots.notFound, children: "Item not found." });
|
|
950
1368
|
}
|
|
951
|
-
const category = categories.find(
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
return /* @__PURE__ */ jsxs5("div", { className: slots.baseContainer, children: [
|
|
955
|
-
/* @__PURE__ */ jsx5(
|
|
1369
|
+
const category = categories.find((c6) => c6.category_id === item.category_id);
|
|
1370
|
+
return /* @__PURE__ */ jsxs13("div", { className: slots.baseContainer, children: [
|
|
1371
|
+
/* @__PURE__ */ jsx14(
|
|
956
1372
|
Breadcrumbs,
|
|
957
1373
|
{
|
|
958
1374
|
items: [
|
|
@@ -962,141 +1378,98 @@ function ItemCustomizationForm({
|
|
|
962
1378
|
]
|
|
963
1379
|
}
|
|
964
1380
|
),
|
|
965
|
-
/* @__PURE__ */
|
|
966
|
-
item.description && /* @__PURE__ */
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1381
|
+
/* @__PURE__ */ jsx14("h1", { className: slots.title, children: item.name }),
|
|
1382
|
+
item.description && /* @__PURE__ */ jsx14("p", { className: slots.description, children: item.description }),
|
|
1383
|
+
/* @__PURE__ */ jsx14(
|
|
1384
|
+
VariantSection,
|
|
1385
|
+
{
|
|
1386
|
+
variants,
|
|
1387
|
+
variant,
|
|
1388
|
+
setVariant,
|
|
1389
|
+
slots
|
|
1390
|
+
}
|
|
1391
|
+
),
|
|
1392
|
+
/* @__PURE__ */ jsx14(
|
|
1393
|
+
ComponentsSection,
|
|
1394
|
+
{
|
|
1395
|
+
variant,
|
|
1396
|
+
draft,
|
|
1397
|
+
setComponentServings,
|
|
1398
|
+
activeSection,
|
|
1399
|
+
divisions,
|
|
1400
|
+
scheme: portionScheme,
|
|
1401
|
+
slots
|
|
1402
|
+
}
|
|
1403
|
+
),
|
|
1404
|
+
portionScheme && /* @__PURE__ */ jsx14(
|
|
1405
|
+
PortionSection,
|
|
1406
|
+
{
|
|
1407
|
+
scheme: portionScheme,
|
|
1408
|
+
divisions,
|
|
1409
|
+
activeSection,
|
|
1410
|
+
setActiveSection,
|
|
1411
|
+
setDivisions: (next) => {
|
|
1412
|
+
recutSelections(next);
|
|
1413
|
+
setCut(next);
|
|
1414
|
+
setActiveSection(
|
|
1415
|
+
(s5) => s5 != null && (next === 1 || s5 > next) ? null : s5
|
|
1416
|
+
);
|
|
977
1417
|
},
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
(
|
|
982
|
-
|
|
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",
|
|
1418
|
+
slots
|
|
1419
|
+
}
|
|
1420
|
+
),
|
|
1421
|
+
ruleGroups.map((rule) => /* @__PURE__ */ jsx14(
|
|
1422
|
+
RuleSection,
|
|
1058
1423
|
{
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1424
|
+
rule,
|
|
1425
|
+
activeSection,
|
|
1426
|
+
divisions,
|
|
1427
|
+
scheme: portionScheme,
|
|
1428
|
+
placeOption,
|
|
1429
|
+
slots
|
|
1430
|
+
},
|
|
1431
|
+
rule.rule_id
|
|
1432
|
+
)),
|
|
1433
|
+
/* @__PURE__ */ jsx14(
|
|
1434
|
+
CommentsSection,
|
|
1435
|
+
{
|
|
1436
|
+
comments,
|
|
1437
|
+
setComments,
|
|
1438
|
+
slots
|
|
1439
|
+
}
|
|
1440
|
+
),
|
|
1441
|
+
/* @__PURE__ */ jsx14(
|
|
1442
|
+
QuantitySection,
|
|
1443
|
+
{
|
|
1444
|
+
quantity,
|
|
1445
|
+
setQuantity,
|
|
1446
|
+
slots
|
|
1447
|
+
}
|
|
1448
|
+
),
|
|
1449
|
+
/* @__PURE__ */ jsx14(
|
|
1450
|
+
SubmitButton,
|
|
1451
|
+
{
|
|
1452
|
+
canSubmit,
|
|
1453
|
+
unmetRule,
|
|
1454
|
+
price,
|
|
1455
|
+
salePrice,
|
|
1456
|
+
isEditMode,
|
|
1457
|
+
onSubmit: () => {
|
|
1062
1458
|
submit();
|
|
1063
|
-
onSubmitSuccess
|
|
1459
|
+
if (onSubmitSuccess) onSubmitSuccess();
|
|
1460
|
+
else router.push("/menu");
|
|
1064
1461
|
},
|
|
1065
|
-
|
|
1066
|
-
children: unmetRule ? `Choose ${unmetRule.group_name}` : `${isEditMode ? "Save changes" : "Add to cart"} \u2014 ${money3(salePrice ?? price)}`
|
|
1462
|
+
slots
|
|
1067
1463
|
}
|
|
1068
1464
|
)
|
|
1069
1465
|
] });
|
|
1070
1466
|
}
|
|
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
1467
|
|
|
1095
|
-
// src/components/FindLocation.tsx
|
|
1096
|
-
import { useMemo, useState as
|
|
1468
|
+
// src/components/client/FindLocation.tsx
|
|
1469
|
+
import { useMemo, useState as useState5 } from "react";
|
|
1097
1470
|
import { Search } from "lucide-react";
|
|
1098
|
-
import { jsx as
|
|
1099
|
-
function
|
|
1471
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1472
|
+
function cn6(...parts) {
|
|
1100
1473
|
return parts.filter(Boolean).join(" ");
|
|
1101
1474
|
}
|
|
1102
1475
|
function searchableText(location) {
|
|
@@ -1147,26 +1520,26 @@ var FIND_LOCATION_DEFAULT_ITEM_CLASSES = {
|
|
|
1147
1520
|
function mergeFindLocationItemClasses(overrides) {
|
|
1148
1521
|
const d3 = FIND_LOCATION_DEFAULT_ITEM_CLASSES;
|
|
1149
1522
|
return {
|
|
1150
|
-
baseContainer:
|
|
1151
|
-
searchContainer:
|
|
1152
|
-
searchIcon:
|
|
1153
|
-
searchInput:
|
|
1154
|
-
noMatchesMessage:
|
|
1155
|
-
emptyMessage:
|
|
1156
|
-
list:
|
|
1157
|
-
locationRow:
|
|
1158
|
-
locationRowSelected:
|
|
1523
|
+
baseContainer: cn6(d3.baseContainer, overrides?.baseContainer),
|
|
1524
|
+
searchContainer: cn6(d3.searchContainer, overrides?.searchContainer),
|
|
1525
|
+
searchIcon: cn6(d3.searchIcon, overrides?.searchIcon),
|
|
1526
|
+
searchInput: cn6(d3.searchInput, overrides?.searchInput),
|
|
1527
|
+
noMatchesMessage: cn6(d3.noMatchesMessage, overrides?.noMatchesMessage),
|
|
1528
|
+
emptyMessage: cn6(d3.emptyMessage, overrides?.emptyMessage),
|
|
1529
|
+
list: cn6(d3.list, overrides?.list),
|
|
1530
|
+
locationRow: cn6(d3.locationRow, overrides?.locationRow),
|
|
1531
|
+
locationRowSelected: cn6(
|
|
1159
1532
|
d3.locationRowSelected,
|
|
1160
1533
|
overrides?.locationRowSelected
|
|
1161
1534
|
),
|
|
1162
|
-
locationRowUnselected:
|
|
1535
|
+
locationRowUnselected: cn6(
|
|
1163
1536
|
d3.locationRowUnselected,
|
|
1164
1537
|
overrides?.locationRowUnselected
|
|
1165
1538
|
),
|
|
1166
|
-
locationButton:
|
|
1167
|
-
locationName:
|
|
1168
|
-
locationAddress:
|
|
1169
|
-
selectButton:
|
|
1539
|
+
locationButton: cn6(d3.locationButton, overrides?.locationButton),
|
|
1540
|
+
locationName: cn6(d3.locationName, overrides?.locationName),
|
|
1541
|
+
locationAddress: cn6(d3.locationAddress, overrides?.locationAddress),
|
|
1542
|
+
selectButton: cn6(d3.selectButton, overrides?.selectButton)
|
|
1170
1543
|
};
|
|
1171
1544
|
}
|
|
1172
1545
|
function FindLocation({
|
|
@@ -1175,8 +1548,8 @@ function FindLocation({
|
|
|
1175
1548
|
onSelect,
|
|
1176
1549
|
itemClasses
|
|
1177
1550
|
}) {
|
|
1178
|
-
const [query, setQuery] =
|
|
1179
|
-
const [selected, setSelected] =
|
|
1551
|
+
const [query, setQuery] = useState5("");
|
|
1552
|
+
const [selected, setSelected] = useState5(
|
|
1180
1553
|
() => initialSelected ?? null
|
|
1181
1554
|
);
|
|
1182
1555
|
const slots = mergeFindLocationItemClasses(itemClasses);
|
|
@@ -1187,10 +1560,10 @@ function FindLocation({
|
|
|
1187
1560
|
);
|
|
1188
1561
|
const trimmedQuery = query.trim();
|
|
1189
1562
|
const noMatches = trimmedQuery.length > 0 && locations.every((location) => matchRank(location, trimmedQuery) === 2);
|
|
1190
|
-
return /* @__PURE__ */
|
|
1191
|
-
/* @__PURE__ */
|
|
1192
|
-
/* @__PURE__ */
|
|
1193
|
-
/* @__PURE__ */
|
|
1563
|
+
return /* @__PURE__ */ jsxs14("div", { className: slots.baseContainer, children: [
|
|
1564
|
+
/* @__PURE__ */ jsxs14("div", { className: slots.searchContainer, children: [
|
|
1565
|
+
/* @__PURE__ */ jsx15(Search, { className: slots.searchIcon, strokeWidth: 2 }),
|
|
1566
|
+
/* @__PURE__ */ jsx15(
|
|
1194
1567
|
"input",
|
|
1195
1568
|
{
|
|
1196
1569
|
type: "search",
|
|
@@ -1202,22 +1575,22 @@ function FindLocation({
|
|
|
1202
1575
|
}
|
|
1203
1576
|
)
|
|
1204
1577
|
] }),
|
|
1205
|
-
noMatches && /* @__PURE__ */
|
|
1578
|
+
noMatches && /* @__PURE__ */ jsxs14("p", { className: slots.noMatchesMessage, children: [
|
|
1206
1579
|
"No locations match \u201C",
|
|
1207
1580
|
trimmedQuery,
|
|
1208
1581
|
"\u201D. Showing all locations anyway."
|
|
1209
1582
|
] }),
|
|
1210
|
-
ranked.length === 0 ? /* @__PURE__ */
|
|
1583
|
+
ranked.length === 0 ? /* @__PURE__ */ jsx15("p", { className: slots.emptyMessage, children: "No locations available." }) : /* @__PURE__ */ jsx15("ul", { className: slots.list, children: ranked.map((location) => {
|
|
1211
1584
|
const isSelected = selected?.location_id === location.location_id;
|
|
1212
|
-
return /* @__PURE__ */
|
|
1585
|
+
return /* @__PURE__ */ jsxs14(
|
|
1213
1586
|
"li",
|
|
1214
1587
|
{
|
|
1215
|
-
className:
|
|
1588
|
+
className: cn6(
|
|
1216
1589
|
slots.locationRow,
|
|
1217
1590
|
isSelected ? slots.locationRowSelected : slots.locationRowUnselected
|
|
1218
1591
|
),
|
|
1219
1592
|
children: [
|
|
1220
|
-
/* @__PURE__ */
|
|
1593
|
+
/* @__PURE__ */ jsxs14(
|
|
1221
1594
|
"button",
|
|
1222
1595
|
{
|
|
1223
1596
|
type: "button",
|
|
@@ -1225,12 +1598,12 @@ function FindLocation({
|
|
|
1225
1598
|
"aria-pressed": isSelected,
|
|
1226
1599
|
className: slots.locationButton,
|
|
1227
1600
|
children: [
|
|
1228
|
-
/* @__PURE__ */
|
|
1229
|
-
location.address && /* @__PURE__ */
|
|
1601
|
+
/* @__PURE__ */ jsx15("p", { className: slots.locationName, children: location.name }),
|
|
1602
|
+
location.address && /* @__PURE__ */ jsx15("p", { className: slots.locationAddress, children: location.address })
|
|
1230
1603
|
]
|
|
1231
1604
|
}
|
|
1232
1605
|
),
|
|
1233
|
-
isSelected && /* @__PURE__ */
|
|
1606
|
+
isSelected && /* @__PURE__ */ jsx15(
|
|
1234
1607
|
"button",
|
|
1235
1608
|
{
|
|
1236
1609
|
type: "button",
|
|
@@ -1247,40 +1620,7 @@ function FindLocation({
|
|
|
1247
1620
|
] });
|
|
1248
1621
|
}
|
|
1249
1622
|
|
|
1250
|
-
// src/components/CheckoutForm.
|
|
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
|
-
}
|
|
1623
|
+
// src/components/client/CheckoutForm/classes.ts
|
|
1284
1624
|
var CHECKOUT_FORM_DEFAULT_ITEM_CLASSES = {
|
|
1285
1625
|
shell: "",
|
|
1286
1626
|
shellInner: "max-w-2xl mx-auto w-full flex flex-col gap-6",
|
|
@@ -1333,522 +1673,208 @@ var CHECKOUT_FORM_DEFAULT_ITEM_CLASSES = {
|
|
|
1333
1673
|
};
|
|
1334
1674
|
function mergeCheckoutFormItemClasses(overrides) {
|
|
1335
1675
|
const d3 = CHECKOUT_FORM_DEFAULT_ITEM_CLASSES;
|
|
1336
|
-
return
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
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
|
-
};
|
|
1676
|
+
return Object.fromEntries(
|
|
1677
|
+
Object.keys(d3).map((key) => [
|
|
1678
|
+
key,
|
|
1679
|
+
cn3(d3[key], overrides?.[key])
|
|
1680
|
+
])
|
|
1681
|
+
);
|
|
1407
1682
|
}
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1683
|
+
var CHECKOUT_FORM_SLOTS = mergeCheckoutFormItemClasses();
|
|
1684
|
+
|
|
1685
|
+
// src/components/client/CheckoutForm/CheckoutForm.tsx
|
|
1686
|
+
import { useEffect as useEffect3, useState as useState9 } from "react";
|
|
1687
|
+
import Link4 from "next/link";
|
|
1688
|
+
import { Elements } from "@stripe/react-stripe-js";
|
|
1689
|
+
import {
|
|
1690
|
+
useCart as useCart4,
|
|
1691
|
+
useLocation,
|
|
1692
|
+
useModal as useModal2,
|
|
1693
|
+
usePayment as usePayment3
|
|
1694
|
+
} from "@zorgo/next";
|
|
1695
|
+
|
|
1696
|
+
// src/components/client/CheckoutForm/CheckoutShell.tsx
|
|
1697
|
+
import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1698
|
+
function CheckoutShell({
|
|
1699
|
+
children,
|
|
1700
|
+
title = "Checkout",
|
|
1701
|
+
slots = CHECKOUT_FORM_SLOTS
|
|
1413
1702
|
}) {
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
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,
|
|
1703
|
+
return /* @__PURE__ */ jsx16("div", { className: slots.shell, children: /* @__PURE__ */ jsxs15("div", { className: slots.shellInner, children: [
|
|
1704
|
+
/* @__PURE__ */ jsx16("h1", { className: slots.pageTitle, children: title }),
|
|
1705
|
+
children
|
|
1706
|
+
] }) });
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
// src/components/client/CheckoutForm/DetailsStep.tsx
|
|
1710
|
+
import { useState as useState7 } from "react";
|
|
1711
|
+
import { DynamicFormShell, SubmitButton as SubmitButton2 } from "@zorgo/next";
|
|
1712
|
+
import { useCart as useCart3, useCustomer as useCustomer3, usePayment } from "@zorgo/next";
|
|
1713
|
+
|
|
1714
|
+
// src/components/client/CheckoutForm/CheckoutSteps.tsx
|
|
1715
|
+
import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1716
|
+
function CheckoutSteps({
|
|
1717
|
+
current,
|
|
1718
|
+
labels = ["Your details", "Payment"],
|
|
1719
|
+
slots = CHECKOUT_FORM_SLOTS
|
|
1720
|
+
}) {
|
|
1721
|
+
return /* @__PURE__ */ jsx17("div", { className: slots.steps, children: labels.map((label, i4) => {
|
|
1722
|
+
const n3 = i4 + 1;
|
|
1723
|
+
const active = n3 <= current;
|
|
1724
|
+
return /* @__PURE__ */ jsxs16("div", { className: "contents", children: [
|
|
1725
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
|
|
1726
|
+
/* @__PURE__ */ jsx17(
|
|
1727
|
+
"div",
|
|
1486
1728
|
{
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
slots.
|
|
1490
|
-
"block w-full text-center"
|
|
1729
|
+
className: cn3(
|
|
1730
|
+
slots.stepBadge,
|
|
1731
|
+
active ? slots.stepBadgeActive : slots.stepBadgeInactive
|
|
1491
1732
|
),
|
|
1492
|
-
children:
|
|
1733
|
+
children: n3
|
|
1493
1734
|
}
|
|
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,
|
|
1735
|
+
),
|
|
1736
|
+
/* @__PURE__ */ jsx17(
|
|
1737
|
+
"p",
|
|
1508
1738
|
{
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
slots.
|
|
1512
|
-
"block w-full text-center"
|
|
1739
|
+
className: cn3(
|
|
1740
|
+
slots.stepLabel,
|
|
1741
|
+
active ? slots.stepLabelActive : slots.stepLabelInactive
|
|
1513
1742
|
),
|
|
1514
|
-
children:
|
|
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"
|
|
1743
|
+
children: label
|
|
1534
1744
|
}
|
|
1535
1745
|
)
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
) });
|
|
1549
|
-
}
|
|
1550
|
-
return /* @__PURE__ */ jsx7(Shell, { slots, children: /* @__PURE__ */ jsx7(DetailsStep, { slots }) });
|
|
1746
|
+
] }),
|
|
1747
|
+
i4 < labels.length - 1 && /* @__PURE__ */ jsx17(
|
|
1748
|
+
"div",
|
|
1749
|
+
{
|
|
1750
|
+
className: cn3(
|
|
1751
|
+
slots.stepDivider,
|
|
1752
|
+
current > n3 ? slots.stepDividerActive : slots.stepDividerInactive
|
|
1753
|
+
)
|
|
1754
|
+
}
|
|
1755
|
+
)
|
|
1756
|
+
] }, label);
|
|
1757
|
+
}) });
|
|
1551
1758
|
}
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1759
|
+
|
|
1760
|
+
// src/components/client/CheckoutForm/ConsentFields.tsx
|
|
1761
|
+
import { CheckboxField } from "@zorgo/next";
|
|
1762
|
+
import { Fragment as Fragment4, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1763
|
+
function ConsentFields({
|
|
1764
|
+
termsLabel = "I have read and agree to the terms of service.",
|
|
1765
|
+
marketingLabel = "I consent to receive promotions via text and email.",
|
|
1766
|
+
slots = CHECKOUT_FORM_SLOTS
|
|
1558
1767
|
}) {
|
|
1559
|
-
return /* @__PURE__ */
|
|
1560
|
-
/* @__PURE__ */
|
|
1561
|
-
|
|
1562
|
-
"p",
|
|
1768
|
+
return /* @__PURE__ */ jsxs17(Fragment4, { children: [
|
|
1769
|
+
/* @__PURE__ */ jsx18(
|
|
1770
|
+
CheckboxField,
|
|
1563
1771
|
{
|
|
1564
|
-
|
|
1565
|
-
|
|
1772
|
+
fieldId: "termsAccepted",
|
|
1773
|
+
required: true,
|
|
1774
|
+
requiredText: "You must agree to the terms of service to continue.",
|
|
1775
|
+
fieldErrorClassName: slots.fieldError,
|
|
1776
|
+
children: termsLabel
|
|
1566
1777
|
}
|
|
1567
1778
|
),
|
|
1568
|
-
/* @__PURE__ */
|
|
1779
|
+
/* @__PURE__ */ jsx18(CheckboxField, { fieldId: "marketingConsent", required: false, children: marketingLabel })
|
|
1569
1780
|
] });
|
|
1570
1781
|
}
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
const
|
|
1585
|
-
const fieldContainerClass = slots.fieldContainer;
|
|
1782
|
+
|
|
1783
|
+
// src/components/client/CheckoutForm/ContactFields.tsx
|
|
1784
|
+
import {
|
|
1785
|
+
NameFields,
|
|
1786
|
+
PhoneField,
|
|
1787
|
+
EmailField,
|
|
1788
|
+
FieldError
|
|
1789
|
+
} from "@zorgo/next";
|
|
1790
|
+
import { useCustomer as useCustomer2 } from "@zorgo/next";
|
|
1791
|
+
import { Fragment as Fragment5, jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1792
|
+
function ContactFields({
|
|
1793
|
+
slots = CHECKOUT_FORM_SLOTS
|
|
1794
|
+
}) {
|
|
1795
|
+
const { customer } = useCustomer2();
|
|
1586
1796
|
const fieldStyleProps = {
|
|
1587
1797
|
fieldClassName: slots.fieldInput,
|
|
1588
|
-
containerClassName:
|
|
1798
|
+
containerClassName: slots.fieldContainer,
|
|
1589
1799
|
fieldLabelClassName: slots.fieldLabel,
|
|
1590
1800
|
fieldErrorClassName: slots.fieldError
|
|
1591
1801
|
};
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
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,
|
|
1802
|
+
return /* @__PURE__ */ jsxs18(Fragment5, { children: [
|
|
1803
|
+
/* @__PURE__ */ jsx19(
|
|
1804
|
+
NameFields,
|
|
1614
1805
|
{
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
slots
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
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,
|
|
1806
|
+
firstNameInitialValue: customer.first_name ?? "",
|
|
1807
|
+
lastNameInitialValue: customer.last_name ?? "",
|
|
1808
|
+
fieldClassName: slots.fieldInput,
|
|
1809
|
+
fieldLabelClassName: slots.fieldLabel,
|
|
1810
|
+
fieldErrorClassName: slots.fieldError,
|
|
1811
|
+
childClassName: cn3(
|
|
1812
|
+
slots.fieldContainer,
|
|
1813
|
+
"md:flex-1 md:min-w-0"
|
|
1814
|
+
)
|
|
1815
|
+
}
|
|
1816
|
+
),
|
|
1817
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex flex-col w-full gap-1", children: [
|
|
1818
|
+
/* @__PURE__ */ jsx19(
|
|
1819
|
+
PhoneField,
|
|
1650
1820
|
{
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
fieldLabelClassName: slots.fieldLabel,
|
|
1655
|
-
fieldErrorClassName: slots.fieldError,
|
|
1656
|
-
childClassName: cn6(
|
|
1657
|
-
fieldContainerClass,
|
|
1658
|
-
"md:flex-1 md:min-w-0"
|
|
1659
|
-
)
|
|
1821
|
+
initialValue: customer.phone ?? "",
|
|
1822
|
+
showError: false,
|
|
1823
|
+
...fieldStyleProps
|
|
1660
1824
|
}
|
|
1661
1825
|
),
|
|
1662
|
-
/* @__PURE__ */
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
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,
|
|
1826
|
+
/* @__PURE__ */ jsx19(FieldError, { name: "phone", className: slots.fieldError })
|
|
1827
|
+
] }),
|
|
1828
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex flex-col w-full gap-1", children: [
|
|
1829
|
+
/* @__PURE__ */ jsx19(
|
|
1830
|
+
EmailField,
|
|
1686
1831
|
{
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
fieldErrorClassName: slots.fieldError,
|
|
1691
|
-
children: "I have read and agree to the terms of service."
|
|
1832
|
+
initialValue: customer.email ?? "",
|
|
1833
|
+
showError: false,
|
|
1834
|
+
...fieldStyleProps
|
|
1692
1835
|
}
|
|
1693
1836
|
),
|
|
1694
|
-
/* @__PURE__ */
|
|
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
|
-
] })
|
|
1837
|
+
/* @__PURE__ */ jsx19(FieldError, { name: "email", className: slots.fieldError })
|
|
1775
1838
|
] })
|
|
1776
1839
|
] });
|
|
1777
1840
|
}
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
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({
|
|
1841
|
+
|
|
1842
|
+
// src/components/client/CheckoutForm/OrderLine.tsx
|
|
1843
|
+
import { Minus as Minus2, Pencil, Plus as Plus2 } from "lucide-react";
|
|
1844
|
+
import { useCart, useModal } from "@zorgo/next";
|
|
1845
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1846
|
+
function OrderLine({
|
|
1819
1847
|
item,
|
|
1820
1848
|
index,
|
|
1821
1849
|
onRemove,
|
|
1822
|
-
slots
|
|
1850
|
+
slots = CHECKOUT_FORM_SLOTS
|
|
1823
1851
|
}) {
|
|
1824
1852
|
const { open } = useModal();
|
|
1825
1853
|
const { updateItem, getItemTotal } = useCart();
|
|
1826
1854
|
const setQuantity = (next) => next < 1 ? onRemove() : updateItem({ ...item, quantity: next }, index);
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
})(),
|
|
1848
|
-
/* @__PURE__ */ jsx7("p", { className: slots.cartLinePrice, children: money4(getItemTotal(item)) })
|
|
1855
|
+
const added = (item.selections ?? []).flatMap(
|
|
1856
|
+
(rs) => rs.selections.map((s5) => s5.name)
|
|
1857
|
+
);
|
|
1858
|
+
const removed = (item.components ?? []).filter((c6) => c6.quantity_servings === 0).map((c6) => c6.name);
|
|
1859
|
+
return /* @__PURE__ */ jsxs19("div", { className: cn3(slots.cartLine, slots.surface), children: [
|
|
1860
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-1 flex-1 min-w-0", children: [
|
|
1861
|
+
/* @__PURE__ */ jsx20("p", { className: slots.cartLineName, children: item.name }),
|
|
1862
|
+
added.length > 0 && /* @__PURE__ */ jsxs19("p", { className: slots.cartLineSelection, children: [
|
|
1863
|
+
"Add ",
|
|
1864
|
+
added.join(", ")
|
|
1865
|
+
] }),
|
|
1866
|
+
removed.length > 0 && /* @__PURE__ */ jsxs19("p", { className: slots.cartLineSelection, children: [
|
|
1867
|
+
"Remove ",
|
|
1868
|
+
removed.join(", ")
|
|
1869
|
+
] }),
|
|
1870
|
+
item.comments && /* @__PURE__ */ jsxs19("p", { className: slots.cartLineSelection, children: [
|
|
1871
|
+
"Comments: ",
|
|
1872
|
+
item.comments
|
|
1873
|
+
] }),
|
|
1874
|
+
/* @__PURE__ */ jsx20("p", { className: slots.cartLinePrice, children: money3(getItemTotal(item)) })
|
|
1849
1875
|
] }),
|
|
1850
|
-
/* @__PURE__ */
|
|
1851
|
-
/* @__PURE__ */
|
|
1876
|
+
/* @__PURE__ */ jsxs19("div", { className: slots.cartLineControls, children: [
|
|
1877
|
+
/* @__PURE__ */ jsx20(
|
|
1852
1878
|
"button",
|
|
1853
1879
|
{
|
|
1854
1880
|
type: "button",
|
|
@@ -1859,41 +1885,96 @@ function CartLine({
|
|
|
1859
1885
|
seed: item,
|
|
1860
1886
|
editIndex: index
|
|
1861
1887
|
}),
|
|
1862
|
-
children: /* @__PURE__ */
|
|
1888
|
+
children: /* @__PURE__ */ jsx20(Pencil, { className: "w-5 h-5" })
|
|
1863
1889
|
}
|
|
1864
1890
|
),
|
|
1865
|
-
/* @__PURE__ */
|
|
1891
|
+
/* @__PURE__ */ jsx20(
|
|
1866
1892
|
"button",
|
|
1867
1893
|
{
|
|
1868
1894
|
type: "button",
|
|
1869
1895
|
className: slots.incrementButton,
|
|
1870
1896
|
onClick: () => setQuantity(item.quantity - 1),
|
|
1871
|
-
children: /* @__PURE__ */
|
|
1897
|
+
children: /* @__PURE__ */ jsx20(Minus2, { className: "w-5 h-5" })
|
|
1872
1898
|
}
|
|
1873
1899
|
),
|
|
1874
|
-
/* @__PURE__ */
|
|
1875
|
-
/* @__PURE__ */
|
|
1900
|
+
/* @__PURE__ */ jsx20("p", { className: slots.cartLineQuantity, children: item.quantity }),
|
|
1901
|
+
/* @__PURE__ */ jsx20(
|
|
1876
1902
|
"button",
|
|
1877
1903
|
{
|
|
1878
1904
|
type: "button",
|
|
1879
1905
|
className: slots.incrementButton,
|
|
1880
1906
|
onClick: () => setQuantity(item.quantity + 1),
|
|
1881
|
-
children: /* @__PURE__ */
|
|
1907
|
+
children: /* @__PURE__ */ jsx20(Plus2, { className: "w-5 h-5" })
|
|
1882
1908
|
}
|
|
1883
1909
|
)
|
|
1884
1910
|
] })
|
|
1885
1911
|
] });
|
|
1886
1912
|
}
|
|
1887
|
-
function
|
|
1913
|
+
function OrderLines({
|
|
1914
|
+
slots = CHECKOUT_FORM_SLOTS
|
|
1915
|
+
}) {
|
|
1916
|
+
const { items, removeItem } = useCart();
|
|
1917
|
+
return /* @__PURE__ */ jsx20("div", { className: slots.cartList, children: items.map((item, index) => /* @__PURE__ */ jsx20(
|
|
1918
|
+
OrderLine,
|
|
1919
|
+
{
|
|
1920
|
+
item,
|
|
1921
|
+
index,
|
|
1922
|
+
onRemove: () => removeItem(index),
|
|
1923
|
+
slots
|
|
1924
|
+
},
|
|
1925
|
+
`${item.item_id}-${index}`
|
|
1926
|
+
)) });
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
// src/components/client/CheckoutForm/OrderTotals.tsx
|
|
1930
|
+
import { useCart as useCart2 } from "@zorgo/next";
|
|
1931
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1932
|
+
function OrderTotals({
|
|
1933
|
+
slots = CHECKOUT_FORM_SLOTS
|
|
1934
|
+
}) {
|
|
1935
|
+
const { subtotal, discount, tax, serviceFee, total } = useCart2();
|
|
1936
|
+
return /* @__PURE__ */ jsxs20("div", { className: cn3(slots.totals, slots.surface), children: [
|
|
1937
|
+
/* @__PURE__ */ jsxs20("div", { className: slots.totalsRow, children: [
|
|
1938
|
+
/* @__PURE__ */ jsx21("span", { children: "Subtotal" }),
|
|
1939
|
+
/* @__PURE__ */ jsx21("span", { children: money3(subtotal) })
|
|
1940
|
+
] }),
|
|
1941
|
+
discount > 0 && /* @__PURE__ */ jsxs20("div", { className: slots.totalsRow, children: [
|
|
1942
|
+
/* @__PURE__ */ jsx21("span", { children: "Discount" }),
|
|
1943
|
+
/* @__PURE__ */ jsx21("span", { children: money3(-discount) })
|
|
1944
|
+
] }),
|
|
1945
|
+
/* @__PURE__ */ jsxs20("div", { className: slots.totalsRow, children: [
|
|
1946
|
+
/* @__PURE__ */ jsx21("span", { children: "Tax" }),
|
|
1947
|
+
/* @__PURE__ */ jsx21("span", { children: money3(tax) })
|
|
1948
|
+
] }),
|
|
1949
|
+
serviceFee > 0 && /* @__PURE__ */ jsxs20("div", { className: slots.totalsRow, children: [
|
|
1950
|
+
/* @__PURE__ */ jsx21("span", { children: "Service fee" }),
|
|
1951
|
+
/* @__PURE__ */ jsx21("span", { children: money3(serviceFee) })
|
|
1952
|
+
] }),
|
|
1953
|
+
/* @__PURE__ */ jsx21("div", { className: slots.totalsDivider }),
|
|
1954
|
+
/* @__PURE__ */ jsxs20("div", { className: slots.totalsTotalRow, children: [
|
|
1955
|
+
/* @__PURE__ */ jsx21("span", { children: "Total" }),
|
|
1956
|
+
/* @__PURE__ */ jsx21("span", { children: money3(total) })
|
|
1957
|
+
] })
|
|
1958
|
+
] });
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
// src/components/client/CheckoutForm/PromoCode.tsx
|
|
1962
|
+
import { useState as useState6 } from "react";
|
|
1963
|
+
import { usePromotions } from "@zorgo/next";
|
|
1964
|
+
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1965
|
+
function PromoCode({
|
|
1966
|
+
placeholder = "Promo code",
|
|
1967
|
+
slots = CHECKOUT_FORM_SLOTS
|
|
1968
|
+
}) {
|
|
1888
1969
|
const { promoCode, appliedPromo, applyPromo, removePromo, error, loading } = usePromotions();
|
|
1889
|
-
const [draft, setDraft] =
|
|
1970
|
+
const [draft, setDraft] = useState6("");
|
|
1890
1971
|
if (appliedPromo) {
|
|
1891
|
-
return /* @__PURE__ */
|
|
1892
|
-
/* @__PURE__ */
|
|
1972
|
+
return /* @__PURE__ */ jsxs21("div", { className: cn3(slots.promoApplied, slots.surface), children: [
|
|
1973
|
+
/* @__PURE__ */ jsxs21("span", { className: slots.promoAppliedLabel, children: [
|
|
1893
1974
|
appliedPromo.name,
|
|
1894
1975
|
" applied"
|
|
1895
1976
|
] }),
|
|
1896
|
-
promoCode && /* @__PURE__ */
|
|
1977
|
+
promoCode && /* @__PURE__ */ jsx22(
|
|
1897
1978
|
"button",
|
|
1898
1979
|
{
|
|
1899
1980
|
type: "button",
|
|
@@ -1904,39 +1985,294 @@ function PromoCode({ slots }) {
|
|
|
1904
1985
|
)
|
|
1905
1986
|
] });
|
|
1906
1987
|
}
|
|
1907
|
-
return /* @__PURE__ */
|
|
1908
|
-
/* @__PURE__ */
|
|
1909
|
-
/* @__PURE__ */
|
|
1988
|
+
return /* @__PURE__ */ jsxs21("div", { className: "flex flex-col gap-2 w-full", children: [
|
|
1989
|
+
/* @__PURE__ */ jsxs21("div", { className: slots.promoRow, children: [
|
|
1990
|
+
/* @__PURE__ */ jsx22(
|
|
1910
1991
|
"input",
|
|
1911
1992
|
{
|
|
1912
1993
|
value: draft,
|
|
1913
1994
|
onChange: (e) => setDraft(e.target.value),
|
|
1914
|
-
placeholder
|
|
1995
|
+
placeholder,
|
|
1915
1996
|
className: slots.promoInput
|
|
1916
1997
|
}
|
|
1917
1998
|
),
|
|
1918
|
-
/* @__PURE__ */
|
|
1999
|
+
/* @__PURE__ */ jsx22(
|
|
1919
2000
|
"button",
|
|
1920
2001
|
{
|
|
1921
2002
|
type: "button",
|
|
1922
2003
|
disabled: loading || !draft.trim(),
|
|
1923
2004
|
onClick: () => applyPromo(draft),
|
|
1924
|
-
className:
|
|
2005
|
+
className: cn3(slots.primaryButton, "shrink-0"),
|
|
1925
2006
|
children: loading ? "Applying\u2026" : "Apply"
|
|
1926
2007
|
}
|
|
1927
2008
|
)
|
|
1928
2009
|
] }),
|
|
1929
|
-
error && /* @__PURE__ */
|
|
2010
|
+
error && /* @__PURE__ */ jsx22("p", { className: slots.promoError, children: error })
|
|
1930
2011
|
] });
|
|
1931
2012
|
}
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
2013
|
+
|
|
2014
|
+
// src/components/client/CheckoutForm/DetailsStep.tsx
|
|
2015
|
+
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2016
|
+
function DetailsStep({
|
|
2017
|
+
slots = CHECKOUT_FORM_SLOTS
|
|
1935
2018
|
}) {
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
]
|
|
2019
|
+
const { resetCart } = useCart3();
|
|
2020
|
+
const { setCustomer } = useCustomer3();
|
|
2021
|
+
const { startCheckout } = usePayment();
|
|
2022
|
+
const [submitError, setSubmitError] = useState7();
|
|
2023
|
+
const handleSubmit = async (values) => {
|
|
2024
|
+
const filledCustomer = {
|
|
2025
|
+
first_name: values.firstName,
|
|
2026
|
+
last_name: values.lastName,
|
|
2027
|
+
phone: values.phone,
|
|
2028
|
+
email: values.email,
|
|
2029
|
+
allow_marketing: values.marketingConsent
|
|
2030
|
+
};
|
|
2031
|
+
setCustomer(filledCustomer);
|
|
2032
|
+
try {
|
|
2033
|
+
await startCheckout();
|
|
2034
|
+
} catch (err) {
|
|
2035
|
+
setSubmitError(
|
|
2036
|
+
err instanceof Error ? err.message : "Could not start payment."
|
|
2037
|
+
);
|
|
2038
|
+
}
|
|
2039
|
+
};
|
|
2040
|
+
return /* @__PURE__ */ jsxs22("div", { className: slots.stepSection, children: [
|
|
2041
|
+
/* @__PURE__ */ jsx23(CheckoutSteps, { current: 1, slots }),
|
|
2042
|
+
/* @__PURE__ */ jsx23("h2", { className: slots.sectionTitle, children: "Your order" }),
|
|
2043
|
+
/* @__PURE__ */ jsx23(OrderLines, { slots }),
|
|
2044
|
+
/* @__PURE__ */ jsx23(OrderTotals, { slots }),
|
|
2045
|
+
/* @__PURE__ */ jsx23(PromoCode, { slots }),
|
|
2046
|
+
/* @__PURE__ */ jsx23("h2", { className: slots.sectionTitle, children: "Contact information" }),
|
|
2047
|
+
/* @__PURE__ */ jsxs22(DynamicFormShell, { onSubmit: handleSubmit, className: slots.form, children: [
|
|
2048
|
+
/* @__PURE__ */ jsx23(ContactFields, { slots }),
|
|
2049
|
+
/* @__PURE__ */ jsx23(ConsentFields, { slots }),
|
|
2050
|
+
submitError && /* @__PURE__ */ jsx23("p", { className: slots.submitError, children: submitError }),
|
|
2051
|
+
/* @__PURE__ */ jsxs22("div", { className: slots.formActions, children: [
|
|
2052
|
+
/* @__PURE__ */ jsx23(
|
|
2053
|
+
"button",
|
|
2054
|
+
{
|
|
2055
|
+
type: "button",
|
|
2056
|
+
onClick: resetCart,
|
|
2057
|
+
className: slots.secondaryButton,
|
|
2058
|
+
children: "Clear cart"
|
|
2059
|
+
}
|
|
2060
|
+
),
|
|
2061
|
+
/* @__PURE__ */ jsx23(
|
|
2062
|
+
SubmitButton2,
|
|
2063
|
+
{
|
|
2064
|
+
label: "Continue to payment",
|
|
2065
|
+
loadingLabel: "Setting up...",
|
|
2066
|
+
className: cn3("flex-1", slots.primaryButton)
|
|
2067
|
+
}
|
|
2068
|
+
)
|
|
2069
|
+
] })
|
|
2070
|
+
] })
|
|
2071
|
+
] });
|
|
2072
|
+
}
|
|
2073
|
+
|
|
2074
|
+
// src/components/client/CheckoutForm/PaymentStep.tsx
|
|
2075
|
+
import { useState as useState8 } from "react";
|
|
2076
|
+
import { PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js";
|
|
2077
|
+
import { DynamicFormShell as DynamicFormShell2, SubmitButton as SubmitButton3 } from "@zorgo/next";
|
|
2078
|
+
import { useCustomer as useCustomer4, usePayment as usePayment2 } from "@zorgo/next";
|
|
2079
|
+
import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2080
|
+
function PaymentStep({
|
|
2081
|
+
slots = CHECKOUT_FORM_SLOTS,
|
|
2082
|
+
checkoutHref = "/checkout"
|
|
2083
|
+
}) {
|
|
2084
|
+
const stripe = useStripe();
|
|
2085
|
+
const elements = useElements();
|
|
2086
|
+
const {
|
|
2087
|
+
total,
|
|
2088
|
+
clientSecret,
|
|
2089
|
+
submitPayment,
|
|
2090
|
+
paymentElementOptions,
|
|
2091
|
+
getReturnUrl,
|
|
2092
|
+
resetCheckout
|
|
2093
|
+
} = usePayment2();
|
|
2094
|
+
const { customer } = useCustomer4();
|
|
2095
|
+
const [submitError, setSubmitError] = useState8();
|
|
2096
|
+
const handleSubmit = async () => {
|
|
2097
|
+
if (!stripe || !elements || !clientSecret) return;
|
|
2098
|
+
const { error } = await elements.submit();
|
|
2099
|
+
if (error) {
|
|
2100
|
+
setSubmitError(error.message ?? "Please check your card details.");
|
|
2101
|
+
throw error;
|
|
2102
|
+
}
|
|
2103
|
+
const returnUrl = `${getReturnUrl()}${checkoutHref.startsWith("/") ? checkoutHref : `/${checkoutHref}`}`;
|
|
2104
|
+
const result = await submitPayment(
|
|
2105
|
+
stripe,
|
|
2106
|
+
elements,
|
|
2107
|
+
clientSecret,
|
|
2108
|
+
returnUrl,
|
|
2109
|
+
customer
|
|
2110
|
+
);
|
|
2111
|
+
if (!result.success) setSubmitError(result.error);
|
|
2112
|
+
};
|
|
2113
|
+
return /* @__PURE__ */ jsxs23("div", { className: slots.stepSection, children: [
|
|
2114
|
+
/* @__PURE__ */ jsx24(CheckoutSteps, { current: 2, slots }),
|
|
2115
|
+
/* @__PURE__ */ jsxs23(DynamicFormShell2, { onSubmit: handleSubmit, className: slots.form, children: [
|
|
2116
|
+
/* @__PURE__ */ jsx24("div", { className: cn3(slots.paymentSurface, slots.surface), children: /* @__PURE__ */ jsx24(PaymentElement, { options: paymentElementOptions }) }),
|
|
2117
|
+
submitError && /* @__PURE__ */ jsx24("p", { className: slots.submitError, children: submitError }),
|
|
2118
|
+
/* @__PURE__ */ jsxs23("div", { className: slots.formActions, children: [
|
|
2119
|
+
/* @__PURE__ */ jsx24(
|
|
2120
|
+
"button",
|
|
2121
|
+
{
|
|
2122
|
+
type: "button",
|
|
2123
|
+
onClick: resetCheckout,
|
|
2124
|
+
className: slots.secondaryButton,
|
|
2125
|
+
children: "Back to order"
|
|
2126
|
+
}
|
|
2127
|
+
),
|
|
2128
|
+
/* @__PURE__ */ jsx24(
|
|
2129
|
+
SubmitButton3,
|
|
2130
|
+
{
|
|
2131
|
+
label: `Pay ${money3(total ?? 0)}`,
|
|
2132
|
+
loadingLabel: "Processing...",
|
|
2133
|
+
className: cn3("flex-1", slots.primaryButton)
|
|
2134
|
+
}
|
|
2135
|
+
)
|
|
2136
|
+
] })
|
|
2137
|
+
] })
|
|
2138
|
+
] });
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
// src/components/client/CheckoutForm/StatusPanel.tsx
|
|
2142
|
+
import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2143
|
+
function StatusPanel({
|
|
2144
|
+
title,
|
|
2145
|
+
message,
|
|
2146
|
+
action,
|
|
2147
|
+
tone = "default",
|
|
2148
|
+
slots = CHECKOUT_FORM_SLOTS
|
|
2149
|
+
}) {
|
|
2150
|
+
return /* @__PURE__ */ jsxs24("div", { className: cn3(slots.statusPanel, slots.surface), children: [
|
|
2151
|
+
/* @__PURE__ */ jsx25("h2", { className: slots.statusTitle, children: title }),
|
|
2152
|
+
message && /* @__PURE__ */ jsx25(
|
|
2153
|
+
"p",
|
|
2154
|
+
{
|
|
2155
|
+
className: tone === "error" ? slots.statusMessageError : slots.statusMessage,
|
|
2156
|
+
children: message
|
|
2157
|
+
}
|
|
2158
|
+
),
|
|
2159
|
+
/* @__PURE__ */ jsx25("div", { className: slots.statusActions, children: action })
|
|
2160
|
+
] });
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
// src/components/client/CheckoutForm/CheckoutForm.tsx
|
|
2164
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
2165
|
+
function CheckoutForm({
|
|
2166
|
+
itemClasses,
|
|
2167
|
+
homeHref = "/",
|
|
2168
|
+
menuHref = "/menu",
|
|
2169
|
+
checkoutHref = "/checkout"
|
|
2170
|
+
}) {
|
|
2171
|
+
const slots = mergeCheckoutFormItemClasses(itemClasses);
|
|
2172
|
+
const {
|
|
2173
|
+
clientSecret,
|
|
2174
|
+
stripe,
|
|
2175
|
+
elementOptions,
|
|
2176
|
+
isReady,
|
|
2177
|
+
isLoading,
|
|
2178
|
+
error,
|
|
2179
|
+
getReturnStatus
|
|
2180
|
+
} = usePayment3();
|
|
2181
|
+
const { isEmpty, resetCart } = useCart4();
|
|
2182
|
+
const { currentLocation, needsLocationSelection } = useLocation({
|
|
2183
|
+
promptLocationSelection: true
|
|
2184
|
+
});
|
|
2185
|
+
const { open } = useModal2();
|
|
2186
|
+
const [returnStatus, setReturnStatus] = useState9(null);
|
|
2187
|
+
useEffect3(() => {
|
|
2188
|
+
if (window.location.search.includes("redirect_status")) {
|
|
2189
|
+
const status = getReturnStatus(window.location.href);
|
|
2190
|
+
setReturnStatus(status);
|
|
2191
|
+
if (status.succeeded) resetCart();
|
|
2192
|
+
}
|
|
2193
|
+
}, []);
|
|
2194
|
+
const linkAction = (href, label) => /* @__PURE__ */ jsx26(
|
|
2195
|
+
Link4,
|
|
2196
|
+
{
|
|
2197
|
+
href,
|
|
2198
|
+
className: cn3(slots.primaryButton, "block w-full text-center"),
|
|
2199
|
+
children: label
|
|
2200
|
+
}
|
|
2201
|
+
);
|
|
2202
|
+
if (returnStatus) {
|
|
2203
|
+
return /* @__PURE__ */ jsx26(CheckoutShell, { slots, children: returnStatus.succeeded ? /* @__PURE__ */ jsx26(
|
|
2204
|
+
StatusPanel,
|
|
2205
|
+
{
|
|
2206
|
+
slots,
|
|
2207
|
+
title: "You're all set",
|
|
2208
|
+
message: "Payment successful. Thank you!",
|
|
2209
|
+
action: linkAction(homeHref, "Back home")
|
|
2210
|
+
}
|
|
2211
|
+
) : /* @__PURE__ */ jsx26(
|
|
2212
|
+
StatusPanel,
|
|
2213
|
+
{
|
|
2214
|
+
slots,
|
|
2215
|
+
title: "Payment didn't go through",
|
|
2216
|
+
message: returnStatus.error,
|
|
2217
|
+
tone: "error",
|
|
2218
|
+
action: linkAction(checkoutHref, "Try again")
|
|
2219
|
+
}
|
|
2220
|
+
) });
|
|
2221
|
+
}
|
|
2222
|
+
if (isEmpty && !isLoading && !clientSecret) {
|
|
2223
|
+
return /* @__PURE__ */ jsx26(CheckoutShell, { slots, children: /* @__PURE__ */ jsx26(
|
|
2224
|
+
StatusPanel,
|
|
2225
|
+
{
|
|
2226
|
+
slots,
|
|
2227
|
+
title: "Your cart is empty",
|
|
2228
|
+
message: "Add something from the menu to get started.",
|
|
2229
|
+
action: linkAction(menuHref, "Browse the menu")
|
|
2230
|
+
}
|
|
2231
|
+
) });
|
|
2232
|
+
}
|
|
2233
|
+
if (error) {
|
|
2234
|
+
return /* @__PURE__ */ jsx26(CheckoutShell, { slots, children: /* @__PURE__ */ jsx26(
|
|
2235
|
+
StatusPanel,
|
|
2236
|
+
{
|
|
2237
|
+
slots,
|
|
2238
|
+
title: "Something went wrong",
|
|
2239
|
+
message: error,
|
|
2240
|
+
tone: "error",
|
|
2241
|
+
action: linkAction(menuHref, "Back to menu")
|
|
2242
|
+
}
|
|
2243
|
+
) });
|
|
2244
|
+
}
|
|
2245
|
+
if (needsLocationSelection) {
|
|
2246
|
+
return /* @__PURE__ */ jsx26(CheckoutShell, { slots, children: /* @__PURE__ */ jsx26(
|
|
2247
|
+
StatusPanel,
|
|
2248
|
+
{
|
|
2249
|
+
slots,
|
|
2250
|
+
title: "Choose a location",
|
|
2251
|
+
message: "Please choose a location to continue checkout.",
|
|
2252
|
+
action: /* @__PURE__ */ jsx26(
|
|
2253
|
+
"button",
|
|
2254
|
+
{
|
|
2255
|
+
type: "button",
|
|
2256
|
+
onClick: () => open("FIND_LOCATION_MODAL"),
|
|
2257
|
+
className: cn3(slots.primaryButton, "w-full"),
|
|
2258
|
+
children: "Select a location"
|
|
2259
|
+
}
|
|
2260
|
+
)
|
|
2261
|
+
}
|
|
2262
|
+
) });
|
|
2263
|
+
}
|
|
2264
|
+
if (isReady && elementOptions) {
|
|
2265
|
+
return /* @__PURE__ */ jsx26(CheckoutShell, { slots, children: /* @__PURE__ */ jsx26(
|
|
2266
|
+
Elements,
|
|
2267
|
+
{
|
|
2268
|
+
stripe,
|
|
2269
|
+
options: elementOptions,
|
|
2270
|
+
children: /* @__PURE__ */ jsx26(PaymentStep, { slots, checkoutHref })
|
|
2271
|
+
},
|
|
2272
|
+
currentLocation?.stripe_account_id
|
|
2273
|
+
) });
|
|
2274
|
+
}
|
|
2275
|
+
return /* @__PURE__ */ jsx26(CheckoutShell, { slots, children: /* @__PURE__ */ jsx26(DetailsStep, { slots }) });
|
|
1940
2276
|
}
|
|
1941
2277
|
export {
|
|
1942
2278
|
ACCORDION_MENU_DEFAULT_ITEM_CLASSES,
|
|
@@ -1944,19 +2280,46 @@ export {
|
|
|
1944
2280
|
BREADCRUMBS_DEFAULT_ITEM_CLASSES,
|
|
1945
2281
|
Breadcrumbs,
|
|
1946
2282
|
CHECKOUT_FORM_DEFAULT_ITEM_CLASSES,
|
|
2283
|
+
CHECKOUT_FORM_SLOTS,
|
|
2284
|
+
CLIENT_ITEM_FORM_DEFAULT_ITEM_CLASSES,
|
|
2285
|
+
CLIENT_ITEM_FORM_SLOTS,
|
|
1947
2286
|
CheckoutForm,
|
|
2287
|
+
CheckoutShell,
|
|
2288
|
+
CheckoutSteps,
|
|
2289
|
+
ClientItemForm,
|
|
2290
|
+
CommentsSection,
|
|
2291
|
+
ComponentsSection,
|
|
2292
|
+
ConsentFields,
|
|
2293
|
+
ContactFields,
|
|
1948
2294
|
CookieConsent,
|
|
2295
|
+
DetailsStep,
|
|
1949
2296
|
FIND_LOCATION_DEFAULT_ITEM_CLASSES,
|
|
1950
2297
|
FindLocation,
|
|
1951
2298
|
GRID_MENU_DEFAULT_ITEM_CLASSES,
|
|
1952
2299
|
GridMenu,
|
|
1953
|
-
ITEM_CUSTOMIZATION_FORM_DEFAULT_ITEM_CLASSES,
|
|
1954
|
-
|
|
2300
|
+
CLIENT_ITEM_FORM_DEFAULT_ITEM_CLASSES as ITEM_CUSTOMIZATION_FORM_DEFAULT_ITEM_CLASSES,
|
|
2301
|
+
ClientItemForm as ItemCustomizationClient,
|
|
2302
|
+
ClientItemForm as ItemCustomizationForm,
|
|
2303
|
+
OptionButton,
|
|
2304
|
+
OrderLine,
|
|
2305
|
+
OrderLines,
|
|
2306
|
+
OrderTotals,
|
|
2307
|
+
PaymentStep,
|
|
2308
|
+
PortionPicker,
|
|
2309
|
+
PortionSection,
|
|
2310
|
+
PromoCode,
|
|
2311
|
+
QuantitySection,
|
|
2312
|
+
RuleSection,
|
|
2313
|
+
StatusPanel,
|
|
2314
|
+
SubmitButton,
|
|
2315
|
+
VariantSection,
|
|
1955
2316
|
mergeAccordionMenuItemClasses,
|
|
1956
2317
|
mergeBreadcrumbsItemClasses,
|
|
1957
2318
|
mergeCheckoutFormItemClasses,
|
|
2319
|
+
mergeClientItemFormItemClasses,
|
|
1958
2320
|
mergeFindLocationItemClasses,
|
|
1959
2321
|
mergeGridMenuItemClasses,
|
|
1960
|
-
mergeItemCustomizationFormItemClasses
|
|
2322
|
+
mergeClientItemFormItemClasses as mergeItemCustomizationFormItemClasses,
|
|
2323
|
+
money3 as money
|
|
1961
2324
|
};
|
|
1962
2325
|
//# sourceMappingURL=components.mjs.map
|