@fayz-ai/storefront 0.8.3 → 0.8.4
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/components/StorefrontHeader.d.ts.map +1 -1
- package/dist/createStorefrontApp.d.ts.map +1 -1
- package/dist/index.cjs +113 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +114 -11
- package/dist/index.js.map +1 -1
- package/dist/pages/CheckoutPage.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/components/StorefrontHeader.tsx +113 -10
- package/src/createStorefrontApp.tsx +4 -0
- package/src/pages/CheckoutPage.tsx +5 -1
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import React7, { createContext, useState, useRef, useEffect, useMemo, useContext
|
|
|
8
8
|
import { hashRouterAdapter, normalizePostalCode, lookupPostalCode, registerScaffold, registerBlock, formatPostalCode, renderBlocks, defineApp } from '@fayz-ai/core';
|
|
9
9
|
export { getSupabaseClientOptional, renderApp } from '@fayz-ai/core';
|
|
10
10
|
import * as LucideIcons from 'lucide-react';
|
|
11
|
-
import { ChevronLeft, ChevronRight, ShoppingBag, X, Trash2, Phone, Mail, Search, User, UserCircle, Package, CreditCard, LogOut, Truck, RefreshCcw, ShieldCheck, Lock, Minus, Plus, MapPin, Info, AlertCircle, Check, Send, MessageCircle, PackageCheck, QrCode, XCircle, RotateCcw, Clock } from 'lucide-react';
|
|
11
|
+
import { ChevronLeft, ChevronRight, ShoppingBag, X, Trash2, Phone, Mail, Search, User, UserCircle, Package, CreditCard, LogOut, Menu, Truck, RefreshCcw, ShieldCheck, Lock, Minus, Plus, MapPin, Info, AlertCircle, Check, Send, MessageCircle, PackageCheck, QrCode, XCircle, RotateCcw, Clock } from 'lucide-react';
|
|
12
12
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
13
13
|
import { validateDiscount } from '@fayz-ai/shop';
|
|
14
14
|
|
|
@@ -909,7 +909,7 @@ function SearchInput({ className, iconOnly = false }) {
|
|
|
909
909
|
)
|
|
910
910
|
] });
|
|
911
911
|
}
|
|
912
|
-
function HeaderActions() {
|
|
912
|
+
function HeaderActions({ onMenuClick }) {
|
|
913
913
|
const config = useStorefrontConfig();
|
|
914
914
|
const count = useCartStore(selectCount);
|
|
915
915
|
const openDrawer = useCartStore((s) => s.openDrawer);
|
|
@@ -1007,6 +1007,16 @@ function HeaderActions() {
|
|
|
1007
1007
|
)
|
|
1008
1008
|
]
|
|
1009
1009
|
}
|
|
1010
|
+
),
|
|
1011
|
+
onMenuClick && /* @__PURE__ */ jsx(
|
|
1012
|
+
"button",
|
|
1013
|
+
{
|
|
1014
|
+
type: "button",
|
|
1015
|
+
"aria-label": "Abrir menu",
|
|
1016
|
+
onClick: onMenuClick,
|
|
1017
|
+
className: "relative rounded-full p-2.5 transition-opacity hover:opacity-70 md:hidden",
|
|
1018
|
+
children: /* @__PURE__ */ jsx(Menu, { className: "h-5 w-5" })
|
|
1019
|
+
}
|
|
1010
1020
|
)
|
|
1011
1021
|
] });
|
|
1012
1022
|
}
|
|
@@ -1047,12 +1057,94 @@ function NavLinks({ className }) {
|
|
|
1047
1057
|
))
|
|
1048
1058
|
] });
|
|
1049
1059
|
}
|
|
1060
|
+
function MobileMenuDrawer({ open, onClose }) {
|
|
1061
|
+
const config = useStorefrontConfig();
|
|
1062
|
+
const { categories } = useCategories();
|
|
1063
|
+
const setCategoryId = useCatalogStore((s) => s.setCategoryId);
|
|
1064
|
+
const showCategories = config.theme?.header?.showCategories !== false;
|
|
1065
|
+
const goCategory = (categoryId) => {
|
|
1066
|
+
useCatalogStore.getState().reset();
|
|
1067
|
+
setCategoryId(categoryId);
|
|
1068
|
+
navigateTo(config.catalogPath);
|
|
1069
|
+
onClose();
|
|
1070
|
+
};
|
|
1071
|
+
React7.useEffect(() => {
|
|
1072
|
+
if (!open) return;
|
|
1073
|
+
const onKey = (e) => {
|
|
1074
|
+
if (e.key === "Escape") onClose();
|
|
1075
|
+
};
|
|
1076
|
+
document.addEventListener("keydown", onKey);
|
|
1077
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
1078
|
+
}, [open, onClose]);
|
|
1079
|
+
if (!open) return null;
|
|
1080
|
+
return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 md:hidden", children: [
|
|
1081
|
+
/* @__PURE__ */ jsx(
|
|
1082
|
+
"div",
|
|
1083
|
+
{
|
|
1084
|
+
className: "absolute inset-0 animate-fade-in bg-black/40",
|
|
1085
|
+
"aria-hidden": true,
|
|
1086
|
+
onClick: onClose
|
|
1087
|
+
}
|
|
1088
|
+
),
|
|
1089
|
+
/* @__PURE__ */ jsxs(
|
|
1090
|
+
"div",
|
|
1091
|
+
{
|
|
1092
|
+
"data-testid": "mobile-menu-drawer",
|
|
1093
|
+
role: "dialog",
|
|
1094
|
+
"aria-label": "Menu Principal",
|
|
1095
|
+
className: "absolute right-0 top-0 flex h-full w-full max-w-[280px] animate-slide-in-from-right flex-col bg-background shadow-2xl",
|
|
1096
|
+
children: [
|
|
1097
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b px-5 py-4", children: [
|
|
1098
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "Menu" }),
|
|
1099
|
+
/* @__PURE__ */ jsx(
|
|
1100
|
+
"button",
|
|
1101
|
+
{
|
|
1102
|
+
type: "button",
|
|
1103
|
+
"aria-label": "Fechar menu",
|
|
1104
|
+
onClick: onClose,
|
|
1105
|
+
className: "rounded-full p-1.5 hover:bg-muted",
|
|
1106
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-5 w-5" })
|
|
1107
|
+
}
|
|
1108
|
+
)
|
|
1109
|
+
] }),
|
|
1110
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto p-5", children: /* @__PURE__ */ jsxs("nav", { className: "flex flex-col gap-4", children: [
|
|
1111
|
+
config.nav.map((link) => /* @__PURE__ */ jsx(
|
|
1112
|
+
Link,
|
|
1113
|
+
{
|
|
1114
|
+
to: link.to,
|
|
1115
|
+
onClick: onClose,
|
|
1116
|
+
className: "text-base font-semibold transition-opacity hover:opacity-70",
|
|
1117
|
+
children: link.label
|
|
1118
|
+
},
|
|
1119
|
+
link.to
|
|
1120
|
+
)),
|
|
1121
|
+
showCategories && categories.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1122
|
+
/* @__PURE__ */ jsx("div", { className: "my-2 border-t" }),
|
|
1123
|
+
/* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-bold uppercase tracking-wider text-muted-foreground", children: "Categorias" }),
|
|
1124
|
+
categories.map((c) => /* @__PURE__ */ jsx(
|
|
1125
|
+
"button",
|
|
1126
|
+
{
|
|
1127
|
+
type: "button",
|
|
1128
|
+
onClick: () => goCategory(c.id),
|
|
1129
|
+
className: "text-left text-sm font-medium transition-opacity hover:opacity-80",
|
|
1130
|
+
children: c.name
|
|
1131
|
+
},
|
|
1132
|
+
c.id
|
|
1133
|
+
))
|
|
1134
|
+
] })
|
|
1135
|
+
] }) })
|
|
1136
|
+
]
|
|
1137
|
+
}
|
|
1138
|
+
)
|
|
1139
|
+
] });
|
|
1140
|
+
}
|
|
1050
1141
|
function StorefrontHeader() {
|
|
1051
1142
|
const config = useStorefrontConfig();
|
|
1052
1143
|
const variant = config.theme?.header?.variant ?? "classic";
|
|
1053
1144
|
const scrolled = useScrolled();
|
|
1054
1145
|
const showSearch = config.theme?.header?.showSearch !== false;
|
|
1055
1146
|
const iconSearch = config.theme?.header?.searchStyle === "icon";
|
|
1147
|
+
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
|
1056
1148
|
const logo = /* @__PURE__ */ jsx(Link, { to: "/", className: "sf-heading shrink-0 text-xl font-bold tracking-tight", children: config.logo ?? config.name });
|
|
1057
1149
|
return /* @__PURE__ */ jsxs(
|
|
1058
1150
|
"header",
|
|
@@ -1093,14 +1185,20 @@ function StorefrontHeader() {
|
|
|
1093
1185
|
] })
|
|
1094
1186
|
] })
|
|
1095
1187
|
) : (
|
|
1096
|
-
// classic: logo left, nav, then a right-aligned search + actions cluster
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1188
|
+
// classic: logo left, nav, then a right-aligned search + actions cluster.
|
|
1189
|
+
// NavLinks is hidden below md in the primary row (no room for it there) —
|
|
1190
|
+
// below md a hamburger opens MobileMenuDrawer instead, otherwise mobile
|
|
1191
|
+
// has no way to reach nav/category links at all.
|
|
1192
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1193
|
+
/* @__PURE__ */ jsxs("div", { className: "mx-auto flex h-16 max-w-7xl items-center gap-6 px-4 sm:px-6", children: [
|
|
1194
|
+
logo,
|
|
1195
|
+
/* @__PURE__ */ jsx(NavLinks, { className: "hidden md:flex" }),
|
|
1196
|
+
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-2 sm:gap-3", children: [
|
|
1197
|
+
showSearch && /* @__PURE__ */ jsx(SearchInput, { iconOnly: iconSearch, className: iconSearch ? "" : "hidden w-full max-w-sm sm:block" }),
|
|
1198
|
+
/* @__PURE__ */ jsx(HeaderActions, { onMenuClick: () => setMobileMenuOpen(true) })
|
|
1199
|
+
] })
|
|
1200
|
+
] }),
|
|
1201
|
+
/* @__PURE__ */ jsx(MobileMenuDrawer, { open: mobileMenuOpen, onClose: () => setMobileMenuOpen(false) })
|
|
1104
1202
|
] })
|
|
1105
1203
|
)
|
|
1106
1204
|
]
|
|
@@ -3704,7 +3802,7 @@ function CheckoutPage() {
|
|
|
3704
3802
|
];
|
|
3705
3803
|
const minDuration = sleep(stepMs * 2);
|
|
3706
3804
|
try {
|
|
3707
|
-
const { order } = await placeStorefrontOrder({
|
|
3805
|
+
const { order, customerId } = await placeStorefrontOrder({
|
|
3708
3806
|
config,
|
|
3709
3807
|
cart,
|
|
3710
3808
|
session,
|
|
@@ -3727,6 +3825,7 @@ function CheckoutPage() {
|
|
|
3727
3825
|
// declare it settled. The order is now born `pending` and only the
|
|
3728
3826
|
// merchant (or a PSP webhook) can confirm the money arrived.
|
|
3729
3827
|
});
|
|
3828
|
+
if (customerId) session.setSession({ customerId, email: form.email, name: form.name });
|
|
3730
3829
|
await minDuration;
|
|
3731
3830
|
cart.clear();
|
|
3732
3831
|
navigateTo(`/order/${order.id}`);
|
|
@@ -4830,6 +4929,10 @@ function storefrontDiscountToSeed(discount) {
|
|
|
4830
4929
|
value: discount.percent,
|
|
4831
4930
|
usageLimit: null,
|
|
4832
4931
|
oncePerCustomer: false,
|
|
4932
|
+
minSubtotal: null,
|
|
4933
|
+
appliesTo: "all",
|
|
4934
|
+
productIds: [],
|
|
4935
|
+
categoryIds: [],
|
|
4833
4936
|
startsAt: ts,
|
|
4834
4937
|
endsAt: null,
|
|
4835
4938
|
status: "active",
|