@mohasinac/appkit 3.2.5 → 3.2.7
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/_internal/client/features/layout/SidebarCollapseToggle.js +1 -1
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +3 -3
- package/dist/_internal/server/features/products/data.d.ts +2 -1
- package/dist/_internal/server/jobs/core/countersReconcile.js +2 -1
- package/dist/_internal/shared/actions/action-registry.js +62 -0
- package/dist/_internal/shared/features/products/types.d.ts +3 -2
- package/dist/client.d.ts +2 -0
- package/dist/client.js +1 -0
- package/dist/constants/api-endpoints.d.ts +12 -0
- package/dist/constants/api-endpoints.js +4 -0
- package/dist/constants/field-names.d.ts +2 -0
- package/dist/constants/field-names.js +2 -0
- package/dist/features/about/components/PublicProfileView.js +8 -5
- package/dist/features/account/components/UserOffersPanel.js +0 -1
- package/dist/features/addresses/repository/addresses.repository.d.ts +14 -1
- package/dist/features/addresses/repository/addresses.repository.js +122 -1
- package/dist/features/addresses/schemas/firestore.d.ts +22 -3
- package/dist/features/addresses/schemas/firestore.js +25 -0
- package/dist/features/addresses/schemas/index.d.ts +2 -2
- package/dist/features/admin/components/AdminAddressClustersView.d.ts +5 -0
- package/dist/features/admin/components/AdminAddressClustersView.js +38 -0
- package/dist/features/admin/components/AdminAddressesView.d.ts +5 -0
- package/dist/features/admin/components/AdminAddressesView.js +137 -0
- package/dist/features/admin/components/AdminCarouselEditorView.js +1 -4
- package/dist/features/admin/components/AdminFulfillmentView.js +2 -3
- package/dist/features/admin/components/AdminOrderEditorView.js +1 -3
- package/dist/features/admin/components/AdminPaymentClustersView.d.ts +5 -0
- package/dist/features/admin/components/AdminPaymentClustersView.js +37 -0
- package/dist/features/admin/components/AdminPaymentMethodsView.d.ts +5 -0
- package/dist/features/admin/components/AdminPaymentMethodsView.js +130 -0
- package/dist/features/admin/components/AdminSiteSettingsView.js +2 -2
- package/dist/features/admin/components/index.d.ts +8 -0
- package/dist/features/admin/components/index.js +4 -0
- package/dist/features/admin/schemas/firestore.d.ts +3 -5
- package/dist/features/admin/types/product.types.d.ts +2 -1
- package/dist/features/auth/actions/profile-actions.d.ts +3 -1
- package/dist/features/auth/actions/profile-actions.js +29 -2
- package/dist/features/auth/schemas/firestore.d.ts +8 -10
- package/dist/features/cart/schemas/index.d.ts +6 -6
- package/dist/features/categories/components/CategoryBundlesListing.js +1 -3
- package/dist/features/checkout/schemas/firestore.d.ts +4 -4
- package/dist/features/copilot/components/AdminCopilotView.js +4 -4
- package/dist/features/events/schemas/firestore.d.ts +2 -2
- package/dist/features/grouped/schemas/firestore.d.ts +2 -4
- package/dist/features/history/hooks/useHistory.js +3 -2
- package/dist/features/homepage/actions/homepage-section-actions.d.ts +6 -6
- package/dist/features/homepage/actions/homepage-section-actions.js +2 -2
- package/dist/features/homepage/components/PromoGrid.js +1 -1
- package/dist/features/homepage/schemas/firestore.d.ts +15 -14
- package/dist/features/layout/AppLayoutShell.js +3 -18
- package/dist/features/layout/background-seed-defaults.d.ts +19 -0
- package/dist/features/layout/background-seed-defaults.js +14 -0
- package/dist/features/lottery/schemas/firestore.d.ts +2 -2
- package/dist/features/messages/hooks/useConversation.js +5 -13
- package/dist/features/messages/hooks/useConversations.js +0 -1
- package/dist/features/messages/schemas/firestore.d.ts +2 -2
- package/dist/features/orders/components/RefundHistoryTable.js +1 -3
- package/dist/features/orders/schemas/firestore.d.ts +2 -1
- package/dist/features/orders/schemas/index.d.ts +11 -7
- package/dist/features/orders/schemas/index.js +1 -1
- package/dist/features/payments/repository/saved-payment-methods.repository.d.ts +48 -0
- package/dist/features/payments/repository/saved-payment-methods.repository.js +236 -0
- package/dist/features/payments/schemas/index.d.ts +1 -0
- package/dist/features/payments/schemas/index.js +1 -0
- package/dist/features/payments/schemas/saved-methods-firestore.d.ts +63 -0
- package/dist/features/payments/schemas/saved-methods-firestore.js +60 -0
- package/dist/features/payments/server.d.ts +2 -0
- package/dist/features/payments/server.js +2 -0
- package/dist/features/products/actions/product-actions.d.ts +2 -1
- package/dist/features/products/api/[id]/route.js +1 -1
- package/dist/features/products/api/route.js +1 -1
- package/dist/features/products/components/CompareOverlay.d.ts +18 -1
- package/dist/features/products/components/CompareOverlay.js +0 -16
- package/dist/features/products/components/ProductDetailActions.js +2 -1
- package/dist/features/products/components/ShowGroupSection.js +1 -3
- package/dist/features/products/repository/product-features.repository.js +1 -1
- package/dist/features/products/schemas/firestore.d.ts +3 -6
- package/dist/features/promotions/actions/coupon-actions.d.ts +2 -1
- package/dist/features/promotions/hooks/useCouponValidate.d.ts +2 -1
- package/dist/features/promotions/repository/coupons.repository.d.ts +2 -1
- package/dist/features/promotions/schemas/firestore.d.ts +4 -4
- package/dist/features/promotions/schemas/index.d.ts +6 -6
- package/dist/features/reviews/repository/reviews.repository.d.ts +12 -0
- package/dist/features/reviews/repository/reviews.repository.js +24 -0
- package/dist/features/reviews/schemas/firestore.d.ts +5 -1
- package/dist/features/reviews/schemas/firestore.js +2 -0
- package/dist/features/reviews/schemas/index.d.ts +6 -6
- package/dist/features/scams/components/ScamRegistryView.js +2 -2
- package/dist/features/scams/schemas/firestore.d.ts +6 -6
- package/dist/features/search/types/index.d.ts +3 -2
- package/dist/features/search/types/index.js +0 -1
- package/dist/features/seller/components/FulfillmentView.js +2 -3
- package/dist/features/seller/components/PrintCenterView.js +1 -3
- package/dist/features/seller/components/SellerAddressesView.js +7 -4
- package/dist/features/seller/components/SellerOffersPanel.js +0 -1
- package/dist/features/seller/components/SellerReviewsView.js +0 -1
- package/dist/features/seller/schemas/firestore.d.ts +2 -4
- package/dist/features/server-errors/schemas/firestore.d.ts +2 -2
- package/dist/features/store-extensions/schemas/firestore.d.ts +2 -2
- package/dist/features/stores/components/StoreScopedSearch.js +2 -4
- package/dist/features/stores/repository/store.repository.js +3 -1
- package/dist/features/stores/types/index.d.ts +2 -1
- package/dist/features/stores/types/index.js +0 -1
- package/dist/features/support/schemas/firestore.d.ts +2 -2
- package/dist/features/support/schemas/index.d.ts +8 -8
- package/dist/features/wishlist/schemas/index.d.ts +2 -2
- package/dist/features/wishlist/types/index.d.ts +2 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.js +10 -0
- package/dist/next/routing/route-map.d.ts +8 -0
- package/dist/next/routing/route-map.js +4 -0
- package/dist/providers/auth-firebase/provider.js +3 -1
- package/dist/providers/auth-firebase/session.js +3 -1
- package/dist/repositories/index.d.ts +1 -0
- package/dist/repositories/index.js +1 -0
- package/dist/schemas/registry.d.ts +66 -66
- package/dist/schemas/webhooks/razorpay.d.ts +50 -50
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/pii-schemas.d.ts +2 -0
- package/dist/security/pii-schemas.js +2 -0
- package/dist/seo/json-ld.d.ts +2 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/Form.d.ts +3 -1
- package/dist/ui/components/Form.js +2 -1
- package/dist/ui/components/Radio.d.ts +7 -0
- package/dist/ui/components/Radio.js +7 -0
- package/dist/ui/components/surface-tokens.d.ts +4 -0
- package/dist/ui/components/surface-tokens.js +24 -0
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +1 -1
- package/dist/ui/rich-text/RichText.js +0 -1
- package/package.json +5 -2
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback, useEffect, useState } from "react";
|
|
4
4
|
import { MapPin, Pencil, Plus, Trash2, Star } from "lucide-react";
|
|
5
|
-
import { Button, ConfirmDeleteModal, Div, Grid, Heading, Label, Row, SideDrawer, Span, Stack, Table, Thead, Tbody, Tr, Th, Td, Text } from "../../../ui";
|
|
5
|
+
import { Badge, Button, ConfirmDeleteModal, Div, Grid, Heading, Label, Row, SideDrawer, Span, Stack, Table, Thead, Tbody, Tr, Th, Td, Text } from "../../../ui";
|
|
6
6
|
import { FieldInput } from "../../../ui/forms/FieldInput";
|
|
7
7
|
import { FieldCheckbox } from "../../../ui/forms/FieldCheckbox";
|
|
8
8
|
import { ROW_ACTION_META, ROW_ACTION_ID } from "../../../features/products/constants/action-defs";
|
|
@@ -50,7 +50,8 @@ function fromDoc(doc) {
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
function AddressCard({ address, onEdit, onDelete, }) {
|
|
53
|
-
|
|
53
|
+
const isBanned = address.banStatus === "banned";
|
|
54
|
+
return (_jsxs(Stack, { surface: "card", padding: "sm", gap: "sm", children: [_jsxs(Row, { align: "start", justify: "between", gap: "xs", children: [_jsxs(Row, { gap: "xs", wrap: true, className: "min-w-0", children: [_jsx(MapPin, { className: "h-4 w-4 shrink-0 text-[var(--appkit-color-primary)]" }), _jsx(Span, { size: "sm", weight: "semibold", className: "truncate", color: "primary", children: address.label }), address.isDefault && (_jsxs(Span, { size: "xs", weight: "medium", className: CLS_DEFAULT_PILL, children: [_jsx(Star, { className: "h-3 w-3" }), "Default"] })), isBanned && _jsx(Badge, { variant: "danger", size: "sm", children: "Banned" })] }), _jsx(Row, { gap: "px", className: "shrink-0", children: isBanned ? (_jsx(Span, { size: "xs", color: "muted", title: "Contact support to resolve address ban", children: "Contact support" })) : (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: onEdit, title: "Edit address", className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 hover:text-zinc-700 dark:hover:text-zinc-300 transition-colors", children: _jsx(Pencil, { className: "h-4 w-4" }) }), _jsx("button", { type: "button", onClick: onDelete, title: "Delete address", className: CLS_DELETE_BTN, children: _jsx(Trash2, { className: "h-4 w-4" }) })] })) })] }), _jsxs(Text, { size: "sm", color: "muted", children: [address.fullName, " \u00B7 ", address.phone] }), _jsxs(Text, { className: "leading-relaxed", color: "muted", size: "xs", children: [address.addressLine1, address.addressLine2 ? `, ${address.addressLine2}` : "", address.landmark ? ` (near ${address.landmark})` : "", _jsx("br", {}), address.city, ", ", address.state, " ", address.postalCode, ", ", address.country] })] }));
|
|
54
55
|
}
|
|
55
56
|
// ---------------------------------------------------------------------------
|
|
56
57
|
// Main Component
|
|
@@ -78,7 +79,6 @@ export function SellerAddressesView({ apiBase = SELLER_ENDPOINTS.STORE_ADDRESSES
|
|
|
78
79
|
setAddresses(data);
|
|
79
80
|
}
|
|
80
81
|
catch {
|
|
81
|
-
// toast-intentionally-silent: data load, error surfaced via errorMessage state
|
|
82
82
|
setErrorMessage("Could not load addresses. Please try again.");
|
|
83
83
|
}
|
|
84
84
|
finally {
|
|
@@ -144,5 +144,8 @@ export function SellerAddressesView({ apiBase = SELLER_ENDPOINTS.STORE_ADDRESSES
|
|
|
144
144
|
const handleDelete = (addr) => setDeleteTargetAddr(addr);
|
|
145
145
|
const set = (key, value) => setDraft((p) => ({ ...p, [key]: value }));
|
|
146
146
|
const setField = (key) => (value) => set(key, value);
|
|
147
|
-
return (_jsxs(Div, { className: "min-h-screen", children: [_jsxs(Row, { border: "default", justify: "between", className: "sticky top-[var(--header-height,0px)] z-10 backdrop-blur-sm border-b", surface: "default", padding: "inline", children: [_jsxs(Stack, { gap: "none", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", color: "primary", children: "Pickup Addresses" }), _jsx(Text, { size: "xs", color: "muted", className: "mt-0.5", children: "Manage your store's pickup and return locations" })] }), _jsxs(Button, { gap: "sm", size: "sm", onClick: openAdd, children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx(Span, { children: "Add Address" })] })] }), _jsxs(Div, { paddingX: "x-md-lg", className: "max-w-2xl", padding: "y-lg", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", children: errorMessage })), isLoading ? (_jsx(Row, { justify: "center", padding: "y-4xl", children: _jsx(Div, { className: "h-6 w-6 animate-spin border-2 border-[var(--appkit-color-primary)] border-t-transparent", rounded: "full" }) })) : addresses.length === 0 ? (_jsxs(Stack, { border: "default", className: "border-2 border-dashed", padding: "y-4xl", align: "center", gap: "3", rounded: "xl", children: [_jsx(MapPin, { className: "h-8 w-8 text-zinc-300 dark:text-slate-600" }), _jsx(Text, { size: "sm", color: "muted", children: "No pickup addresses yet" }), _jsx(Button, { size: "sm", variant: "outline", onClick: openAdd, children: "Add your first address" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Row, { justify: "end", className: "mb-2", children: [_jsx(Button, { size: "sm", variant: listView === "table" ? "primary" : "ghost", onClick: () => setListView("table"), children: "Table" }), _jsx(Button, { size: "sm", variant: listView === "cards" ? "primary" : "ghost", onClick: () => setListView("cards"), children: "Cards" })] }), listView === "cards" ? (_jsx(Grid, { gap: "sm", children: addresses.map((addr) => (_jsx(Div, { className: deletingId === addr.id ? "opacity-50 pointer-events-none" : "", children: _jsx(AddressCard, { address: addr, onEdit: () => openEdit(addr), onDelete: () => handleDelete(addr) }) }, addr.id))) })) : (_jsx(Div, { className: `${__O.xAuto}`, rounded: "lg", border: "default", children: _jsxs(Table, { size: "sm", children: [_jsx(Thead, { surface: "muted", children: _jsxs(Tr, { children: [_jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "Label" }), _jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "Name" }), _jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "City" }), _jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "Phone" }), _jsx(Th, { className: "text-right", padding: "sm", weight: "semibold", children: "Actions" })] }) }), _jsx(Tbody, { children: addresses.map((addr) =>
|
|
147
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsxs(Row, { border: "default", justify: "between", className: "sticky top-[var(--header-height,0px)] z-10 backdrop-blur-sm border-b", surface: "default", padding: "inline", children: [_jsxs(Stack, { gap: "none", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", color: "primary", children: "Pickup Addresses" }), _jsx(Text, { size: "xs", color: "muted", className: "mt-0.5", children: "Manage your store's pickup and return locations" })] }), _jsxs(Button, { gap: "sm", size: "sm", onClick: openAdd, children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx(Span, { children: "Add Address" })] })] }), _jsxs(Div, { paddingX: "x-md-lg", className: "max-w-2xl", padding: "y-lg", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", children: errorMessage })), isLoading ? (_jsx(Row, { justify: "center", padding: "y-4xl", children: _jsx(Div, { className: "h-6 w-6 animate-spin border-2 border-[var(--appkit-color-primary)] border-t-transparent", rounded: "full" }) })) : addresses.length === 0 ? (_jsxs(Stack, { border: "default", className: "border-2 border-dashed", padding: "y-4xl", align: "center", gap: "3", rounded: "xl", children: [_jsx(MapPin, { className: "h-8 w-8 text-zinc-300 dark:text-slate-600" }), _jsx(Text, { size: "sm", color: "muted", children: "No pickup addresses yet" }), _jsx(Button, { size: "sm", variant: "outline", onClick: openAdd, children: "Add your first address" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Row, { justify: "end", className: "mb-2", children: [_jsx(Button, { size: "sm", variant: listView === "table" ? "primary" : "ghost", onClick: () => setListView("table"), children: "Table" }), _jsx(Button, { size: "sm", variant: listView === "cards" ? "primary" : "ghost", onClick: () => setListView("cards"), children: "Cards" })] }), listView === "cards" ? (_jsx(Grid, { gap: "sm", children: addresses.map((addr) => (_jsx(Div, { className: deletingId === addr.id ? "opacity-50 pointer-events-none" : "", children: _jsx(AddressCard, { address: addr, onEdit: () => openEdit(addr), onDelete: () => handleDelete(addr) }) }, addr.id))) })) : (_jsx(Div, { className: `${__O.xAuto}`, rounded: "lg", border: "default", children: _jsxs(Table, { size: "sm", children: [_jsx(Thead, { surface: "muted", children: _jsxs(Tr, { children: [_jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "Label" }), _jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "Name" }), _jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "City" }), _jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "Phone" }), _jsx(Th, { className: "text-right", padding: "sm", weight: "semibold", children: "Actions" })] }) }), _jsx(Tbody, { children: addresses.map((addr) => {
|
|
148
|
+
const isBanned = addr.banStatus === "banned";
|
|
149
|
+
return (_jsxs(Tr, { className: `border-t border-[var(--appkit-color-border)] ${deletingId === addr.id ? "opacity-50" : ""}`, children: [_jsx(Td, { padding: "sm", children: _jsxs(Row, { gap: "xs", align: "center", children: [_jsx(Span, { children: addr.label }), isBanned && _jsx(Badge, { variant: "danger", size: "sm", children: "Banned" })] }) }), _jsx(Td, { padding: "sm", children: addr.fullName }), _jsxs(Td, { padding: "sm", children: [addr.city, ", ", addr.state] }), _jsx(Td, { className: "tabular-nums", padding: "sm", children: addr.phone }), _jsx(Td, { className: "text-right", padding: "sm", children: isBanned ? (_jsx(Span, { size: "xs", color: "muted", title: "Contact support to resolve address ban", children: "Contact support" })) : (_jsxs(Row, { justify: "end", gap: "xs", children: [_jsx(Button, { size: "sm", variant: "ghost", onClick: () => openEdit(addr), children: ROW_ACTION_META[ROW_ACTION_ID.EDIT].label }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => handleDelete(addr), children: ROW_ACTION_META[ROW_ACTION_ID.DELETE].label })] })) })] }, addr.id));
|
|
150
|
+
}) })] }) }))] }))] }), _jsx(SideDrawer, { isOpen: drawerOpen, onClose: closeDrawer, title: editingId ? "Edit Address" : "Add Address", footer: _jsxs(Row, { gap: "xs", children: [_jsx(Button, { variant: "outline", onClick: closeDrawer, className: "flex-1", children: "Cancel" }), _jsx(Button, { onClick: handleSave, disabled: saving, className: "flex-1", children: saving ? "Saving…" : editingId ? "Save Changes" : "Add Address" })] }), children: _jsxs(Stack, { gap: "md", padding: "y-2xs", children: [saveError && (_jsx(Div, { textSize: "sm", className: "border border-error/20", color: "error", surface: "danger-surface", padding: "inlineSm", rounded: "lg", children: saveError })), _jsx(FieldInput, { name: "label", label: "Label *", hint: "e.g. Warehouse, Shop, Home", type: "text", value: draft.label, onChange: setField("label"), placeholder: "Warehouse", maxLength: 60 }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(FieldInput, { name: "fullName", label: "Full Name *", type: "text", value: draft.fullName, onChange: setField("fullName"), placeholder: "Ravi Kumar", maxLength: 100 }), _jsx(FieldInput, { name: "phone", label: "Phone *", type: "tel", value: draft.phone, onChange: setField("phone"), placeholder: "+91 98765 43210", maxLength: 20 })] }), _jsx(FieldInput, { name: "addressLine1", label: "Address Line 1 *", type: "text", value: draft.addressLine1, onChange: setField("addressLine1"), placeholder: "Shop 12, Main Market", maxLength: 200 }), _jsx(FieldInput, { name: "addressLine2", label: "Address Line 2", type: "text", value: draft.addressLine2, onChange: setField("addressLine2"), placeholder: "Building / Floor (optional)", maxLength: 200 }), _jsx(FieldInput, { name: "landmark", label: "Landmark", type: "text", value: draft.landmark, onChange: setField("landmark"), placeholder: "Near metro station (optional)", maxLength: 100 }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(FieldInput, { name: "city", label: "City *", type: "text", value: draft.city, onChange: setField("city"), placeholder: "Mumbai", maxLength: 100 }), _jsx(FieldInput, { name: "state", label: "State *", type: "text", value: draft.state, onChange: setField("state"), placeholder: "Maharashtra", maxLength: 100 })] }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(FieldInput, { name: "postalCode", label: "Postal Code *", type: "text", value: draft.postalCode, onChange: setField("postalCode"), placeholder: "400001", maxLength: 10 }), _jsx(FieldInput, { name: "country", label: "Country *", type: "text", value: draft.country, onChange: setField("country"), placeholder: "India", maxLength: 60 })] }), _jsx(FieldCheckbox, { name: "isDefault", label: "Set as default pickup address", checked: draft.isDefault, onChange: (c) => set("isDefault", c) })] }) }), deleteTargetAddr && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Address", message: `Delete address "${deleteTargetAddr.label}"? This cannot be undone.`, onConfirm: () => { deleteById(deleteTargetAddr.id); setDeleteTargetAddr(null); }, onClose: () => setDeleteTargetAddr(null), isDeleting: deletingId === deleteTargetAddr.id }))] }));
|
|
148
151
|
}
|
|
@@ -135,7 +135,6 @@ export function SellerOffersPanel({ fetchEndpoint = "/api/store/offers", onRespo
|
|
|
135
135
|
setOffers(json.items ?? json.offers ?? []);
|
|
136
136
|
}
|
|
137
137
|
catch (err) {
|
|
138
|
-
// toast-intentionally-silent: data load, error surfaced via fetchError state
|
|
139
138
|
void normalizeError(err);
|
|
140
139
|
setFetchError(err instanceof Error ? err.message : "Failed to load offers.");
|
|
141
140
|
}
|
|
@@ -110,7 +110,6 @@ export function SellerReviewsView({ reviewsApiBase = "/api/store/reviews", reply
|
|
|
110
110
|
setMeta(json?.data?.meta ?? null);
|
|
111
111
|
}
|
|
112
112
|
catch (err) {
|
|
113
|
-
// toast-intentionally-silent: data load, error surfaced via error state
|
|
114
113
|
void normalizeError(err);
|
|
115
114
|
setError(err.message);
|
|
116
115
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Offers (Make-an-Offer) Firestore Document Types & Constants
|
|
3
3
|
*/
|
|
4
4
|
import { type GenerateOfferIdInput } from "../../../utils/id-generators";
|
|
5
|
+
import type { BaseDocument } from "../../../_internal/shared/types/base-document";
|
|
5
6
|
export type OfferStatus = "pending" | "accepted" | "declined" | "countered" | "expired" | "withdrawn" | "paid";
|
|
6
7
|
/** Runtime-accessible offer status values — use instead of bare string literals. */
|
|
7
8
|
export declare const OfferStatusValues: {
|
|
@@ -13,8 +14,7 @@ export declare const OfferStatusValues: {
|
|
|
13
14
|
readonly WITHDRAWN: "withdrawn";
|
|
14
15
|
readonly PAID: "paid";
|
|
15
16
|
};
|
|
16
|
-
export interface OfferDocument {
|
|
17
|
-
id: string;
|
|
17
|
+
export interface OfferDocument extends BaseDocument {
|
|
18
18
|
productId: string;
|
|
19
19
|
productTitle: string;
|
|
20
20
|
productSlug?: string;
|
|
@@ -36,8 +36,6 @@ export interface OfferDocument {
|
|
|
36
36
|
acceptedAt?: Date;
|
|
37
37
|
checkoutDeadline?: Date;
|
|
38
38
|
respondedAt?: Date;
|
|
39
|
-
createdAt: Date;
|
|
40
|
-
updatedAt: Date;
|
|
41
39
|
}
|
|
42
40
|
export declare const OFFER_COLLECTION: "offers";
|
|
43
41
|
export declare const OFFER_INDEXED_FIELDS: readonly ["buyerUid", "storeId", "productId", "status", "createdAt", "expiresAt"];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const SERVER_ERRORS_COLLECTION = "serverErrors";
|
|
2
2
|
/** Discriminator for which surface a recorded failure came from. */
|
|
3
3
|
export type ServerErrorSource = "vercel" | "client" | "function";
|
|
4
|
-
export
|
|
4
|
+
export type ServerErrorDocument = {
|
|
5
5
|
id: string;
|
|
6
6
|
/** Server timestamp; also acts as the TTL field (30d retention). */
|
|
7
7
|
occurredAt: number;
|
|
@@ -22,7 +22,7 @@ export interface ServerErrorDocument {
|
|
|
22
22
|
userAgent?: string;
|
|
23
23
|
/** sha256(requestBody) — for diagnosis without leaking PII. */
|
|
24
24
|
bodyDigest?: string;
|
|
25
|
-
}
|
|
25
|
+
};
|
|
26
26
|
export declare const SERVER_ERROR_FIELDS: {
|
|
27
27
|
readonly ID: "id";
|
|
28
28
|
readonly OCCURRED_AT: "occurredAt";
|
|
@@ -155,14 +155,14 @@ export declare const REPORTS_COLLECTION: "reports";
|
|
|
155
155
|
export declare const REPORT_INDEXED_FIELDS: readonly ["entityType", "entityId", "reporterId", "reason", "status", "createdAt"];
|
|
156
156
|
export declare const DEFAULT_REPORT_DATA: Partial<ReportDocument>;
|
|
157
157
|
export type ItemRequestStatus = "pending-approval" | "open" | "fulfilled" | "closed" | "rejected";
|
|
158
|
-
export
|
|
158
|
+
export type ItemRequestReply = {
|
|
159
159
|
id: string;
|
|
160
160
|
authorId: string;
|
|
161
161
|
authorName?: string;
|
|
162
162
|
body: string;
|
|
163
163
|
isOpInitiatedThread: boolean;
|
|
164
164
|
createdAt: Date;
|
|
165
|
-
}
|
|
165
|
+
};
|
|
166
166
|
export interface ItemRequestDocument extends BaseDocument {
|
|
167
167
|
opUserId: string;
|
|
168
168
|
opDisplayName: string;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { useRouter } from "next/navigation";
|
|
5
|
-
import { Button, Input, Row } from "../../../ui";
|
|
5
|
+
import { Button, Form, Input, Row } from "../../../ui";
|
|
6
6
|
import { ROUTES } from "../../../next/routing/route-map";
|
|
7
7
|
/**
|
|
8
8
|
* W1-19 — inline search input scoped to a single store. Submits to
|
|
@@ -23,7 +23,5 @@ export function StoreScopedSearch({ storeId, storeName, placeholder, className =
|
|
|
23
23
|
params.set("q", q);
|
|
24
24
|
router.push(`${base}?${params.toString()}`);
|
|
25
25
|
};
|
|
26
|
-
return (
|
|
27
|
-
// audit-raw-form-input-ok: store-scoped search bar — single query field, no validation needed
|
|
28
|
-
_jsx("form", { onSubmit: submit, className: `w-full ${className}`, children: _jsxs(Row, { gap: "sm", align: "center", className: "w-full", children: [_jsx(Input, { type: "search", value: value, onChange: (e) => setValue(e.target.value), placeholder: placeholder ?? `Search ${storeName}…`, "aria-label": `Search ${storeName}`, className: "flex-1" }), _jsx(Button, { type: "submit", variant: "primary", size: "sm", children: "Search" })] }) }));
|
|
26
|
+
return (_jsx(Form, { onSubmit: submit, className: `w-full ${className}`, children: _jsxs(Row, { gap: "sm", align: "center", className: "w-full", children: [_jsx(Input, { type: "search", value: value, onChange: (e) => setValue(e.target.value), placeholder: placeholder ?? `Search ${storeName}…`, "aria-label": `Search ${storeName}`, className: "flex-1" }), _jsx(Button, { type: "submit", variant: "primary", size: "sm", children: "Search" })] }) }));
|
|
29
27
|
}
|
|
@@ -8,6 +8,7 @@ import { BaseRepository, prepareForFirestore, applySieveToFirestore, } from "../
|
|
|
8
8
|
import { increment } from "../../../contracts/field-ops";
|
|
9
9
|
import { STORE_COLLECTION, STORE_FIELDS, DEFAULT_STORE_DATA, StoreStatusValues, } from "../schemas";
|
|
10
10
|
import { DatabaseError } from "../../../errors";
|
|
11
|
+
import { normalizeError } from "../../../errors/normalize";
|
|
11
12
|
import { encryptSecret, decryptSecret, } from "../../../security/settings-encryption";
|
|
12
13
|
export class StoreRepository extends BaseRepository {
|
|
13
14
|
constructor() {
|
|
@@ -64,7 +65,8 @@ export class StoreRepository extends BaseRepository {
|
|
|
64
65
|
.doc(input.storeSlug)
|
|
65
66
|
.create(prepareForFirestore(this.encryptSecrets(storeData)));
|
|
66
67
|
}
|
|
67
|
-
catch (err) {
|
|
68
|
+
catch (err) {
|
|
69
|
+
void normalizeError(err);
|
|
68
70
|
// gRPC ALREADY_EXISTS = code 6
|
|
69
71
|
if (err.code === 6) {
|
|
70
72
|
throw new DatabaseError(`Store slug "${input.storeSlug}" is already taken`);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ListingType } from "../../products/types";
|
|
1
2
|
export interface StoreListItem {
|
|
2
3
|
id: string;
|
|
3
4
|
storeSlug: string;
|
|
@@ -41,7 +42,7 @@ export interface StoreProductItem {
|
|
|
41
42
|
status: string;
|
|
42
43
|
featured: boolean;
|
|
43
44
|
/** Canonical listing-kind discriminator (SB1-G Phase 4). */
|
|
44
|
-
listingType:
|
|
45
|
+
listingType: ListingType;
|
|
45
46
|
currentBid?: number;
|
|
46
47
|
isPromoted?: boolean;
|
|
47
48
|
slug: string;
|
|
@@ -48,7 +48,7 @@ export type TicketPriority = (typeof TicketPriorityValues)[keyof typeof TicketPr
|
|
|
48
48
|
export declare const ACTIVE_TICKET_STATUSES: TicketStatus[];
|
|
49
49
|
/** Order statuses that are eligible for a support ticket. */
|
|
50
50
|
export declare const ELIGIBLE_ORDER_STATUSES_FOR_TICKET: readonly ["PENDING", "PROCESSING", "SHIPPED", "RETURN_REQUESTED"];
|
|
51
|
-
export
|
|
51
|
+
export type TicketMessage = {
|
|
52
52
|
id: string;
|
|
53
53
|
authorId: string;
|
|
54
54
|
authorRole: "user" | "support" | "admin";
|
|
@@ -57,7 +57,7 @@ export interface TicketMessage {
|
|
|
57
57
|
/** Media URLs (screenshots, attachments — /media/ proxy URLs, never raw Storage). */
|
|
58
58
|
attachments?: string[];
|
|
59
59
|
createdAt: Date;
|
|
60
|
-
}
|
|
60
|
+
};
|
|
61
61
|
/**
|
|
62
62
|
* Subject entities a ticket concerns. Assigned by admin/support agents so a
|
|
63
63
|
* single ticket can reference the buyer, store, order, product, or bid in
|
|
@@ -44,15 +44,15 @@ export declare const ticketRelatedPartiesSchema: z.ZodObject<{
|
|
|
44
44
|
bidId: z.ZodOptional<z.ZodString>;
|
|
45
45
|
}, "strip", z.ZodTypeAny, {
|
|
46
46
|
storeId?: string | undefined;
|
|
47
|
+
userId?: string | undefined;
|
|
47
48
|
orderId?: string | undefined;
|
|
48
49
|
productId?: string | undefined;
|
|
49
|
-
userId?: string | undefined;
|
|
50
50
|
bidId?: string | undefined;
|
|
51
51
|
}, {
|
|
52
52
|
storeId?: string | undefined;
|
|
53
|
+
userId?: string | undefined;
|
|
53
54
|
orderId?: string | undefined;
|
|
54
55
|
productId?: string | undefined;
|
|
55
|
-
userId?: string | undefined;
|
|
56
56
|
bidId?: string | undefined;
|
|
57
57
|
}>;
|
|
58
58
|
export declare const supportTicketFirestoreSchema: z.ZodObject<{
|
|
@@ -86,15 +86,15 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
|
|
|
86
86
|
bidId: z.ZodOptional<z.ZodString>;
|
|
87
87
|
}, "strip", z.ZodTypeAny, {
|
|
88
88
|
storeId?: string | undefined;
|
|
89
|
+
userId?: string | undefined;
|
|
89
90
|
orderId?: string | undefined;
|
|
90
91
|
productId?: string | undefined;
|
|
91
|
-
userId?: string | undefined;
|
|
92
92
|
bidId?: string | undefined;
|
|
93
93
|
}, {
|
|
94
94
|
storeId?: string | undefined;
|
|
95
|
+
userId?: string | undefined;
|
|
95
96
|
orderId?: string | undefined;
|
|
96
97
|
productId?: string | undefined;
|
|
97
|
-
userId?: string | undefined;
|
|
98
98
|
bidId?: string | undefined;
|
|
99
99
|
}>>;
|
|
100
100
|
status: z.ZodEnum<["open", "in_progress", "waiting_on_user", "resolved", "closed"]>;
|
|
@@ -159,6 +159,7 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
|
|
|
159
159
|
updatedAt: string | Date | z.objectOutputType<{
|
|
160
160
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
161
161
|
}, z.ZodTypeAny, "passthrough">;
|
|
162
|
+
userId: string;
|
|
162
163
|
priority: "normal" | "high" | "low" | "urgent";
|
|
163
164
|
messages: {
|
|
164
165
|
createdAt: string | Date | z.objectOutputType<{
|
|
@@ -170,7 +171,6 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
|
|
|
170
171
|
authorRole: "user" | "admin" | "support";
|
|
171
172
|
attachments?: string[] | undefined;
|
|
172
173
|
}[];
|
|
173
|
-
userId: string;
|
|
174
174
|
userEmail: string;
|
|
175
175
|
userDisplayName: string;
|
|
176
176
|
subject: string;
|
|
@@ -184,9 +184,9 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
|
|
|
184
184
|
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
185
185
|
relatedParties?: {
|
|
186
186
|
storeId?: string | undefined;
|
|
187
|
+
userId?: string | undefined;
|
|
187
188
|
orderId?: string | undefined;
|
|
188
189
|
productId?: string | undefined;
|
|
189
|
-
userId?: string | undefined;
|
|
190
190
|
bidId?: string | undefined;
|
|
191
191
|
} | undefined;
|
|
192
192
|
assignedToName?: string | undefined;
|
|
@@ -202,6 +202,7 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
|
|
|
202
202
|
updatedAt: string | Date | z.objectInputType<{
|
|
203
203
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
204
204
|
}, z.ZodTypeAny, "passthrough">;
|
|
205
|
+
userId: string;
|
|
205
206
|
priority: "normal" | "high" | "low" | "urgent";
|
|
206
207
|
messages: {
|
|
207
208
|
createdAt: string | Date | z.objectInputType<{
|
|
@@ -213,7 +214,6 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
|
|
|
213
214
|
authorRole: "user" | "admin" | "support";
|
|
214
215
|
attachments?: string[] | undefined;
|
|
215
216
|
}[];
|
|
216
|
-
userId: string;
|
|
217
217
|
userEmail: string;
|
|
218
218
|
userDisplayName: string;
|
|
219
219
|
subject: string;
|
|
@@ -227,9 +227,9 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
|
|
|
227
227
|
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
228
228
|
relatedParties?: {
|
|
229
229
|
storeId?: string | undefined;
|
|
230
|
+
userId?: string | undefined;
|
|
230
231
|
orderId?: string | undefined;
|
|
231
232
|
productId?: string | undefined;
|
|
232
|
-
userId?: string | undefined;
|
|
233
233
|
bidId?: string | undefined;
|
|
234
234
|
} | undefined;
|
|
235
235
|
assignedToName?: string | undefined;
|
|
@@ -23,8 +23,8 @@ export declare const wishlistItemSchema: z.ZodObject<{
|
|
|
23
23
|
addedAt: z.ZodOptional<z.ZodString>;
|
|
24
24
|
}, "strip", z.ZodTypeAny, {
|
|
25
25
|
id: string;
|
|
26
|
-
productId: string;
|
|
27
26
|
userId: string;
|
|
27
|
+
productId: string;
|
|
28
28
|
productTitle?: string | undefined;
|
|
29
29
|
productImage?: string | undefined;
|
|
30
30
|
addedAt?: string | undefined;
|
|
@@ -34,8 +34,8 @@ export declare const wishlistItemSchema: z.ZodObject<{
|
|
|
34
34
|
productStatus?: string | undefined;
|
|
35
35
|
}, {
|
|
36
36
|
id: string;
|
|
37
|
-
productId: string;
|
|
38
37
|
userId: string;
|
|
38
|
+
productId: string;
|
|
39
39
|
productTitle?: string | undefined;
|
|
40
40
|
productImage?: string | undefined;
|
|
41
41
|
addedAt?: string | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ListingType } from "../../products/types";
|
|
1
2
|
export interface WishlistItem {
|
|
2
3
|
id: string;
|
|
3
4
|
userId: string;
|
|
@@ -24,7 +25,7 @@ export interface WishlistProductData {
|
|
|
24
25
|
status?: "draft" | "published" | "in_review" | "archived";
|
|
25
26
|
isFeatured?: boolean;
|
|
26
27
|
/** Canonical listing-kind discriminator (SB1-G Phase 4). */
|
|
27
|
-
listingType?:
|
|
28
|
+
listingType?: ListingType;
|
|
28
29
|
}
|
|
29
30
|
/** WishlistItem enriched with inline product details returned by the wishlist GET endpoint. */
|
|
30
31
|
export interface EnrichedWishlistItem extends WishlistItem {
|
package/dist/index.d.ts
CHANGED
|
@@ -563,6 +563,7 @@ export { offerRepository } from "./repositories/index";
|
|
|
563
563
|
export { orderRepository } from "./repositories/index";
|
|
564
564
|
export { passwordResetTokenRepository } from "./repositories/index";
|
|
565
565
|
export { payoutRepository } from "./repositories/index";
|
|
566
|
+
export { savedPaymentMethodsRepository, SavedPaymentMethodsRepository } from "./repositories/index";
|
|
566
567
|
export { productRepository } from "./repositories/index";
|
|
567
568
|
export { reviewRepository } from "./repositories/index";
|
|
568
569
|
export { sessionRepository } from "./repositories/index";
|
|
@@ -1183,6 +1184,14 @@ export { AdminReturnRequestsView } from "./features/admin/index";
|
|
|
1183
1184
|
export type { AdminReturnRequestsViewProps } from "./features/admin/index";
|
|
1184
1185
|
export { AdminStoreAddressesView } from "./features/admin/index";
|
|
1185
1186
|
export type { AdminStoreAddressesViewProps } from "./features/admin/index";
|
|
1187
|
+
export { AdminAddressesView } from "./features/admin/index";
|
|
1188
|
+
export type { AdminAddressesViewProps } from "./features/admin/index";
|
|
1189
|
+
export { AdminAddressClustersView } from "./features/admin/index";
|
|
1190
|
+
export type { AdminAddressClustersViewProps } from "./features/admin/index";
|
|
1191
|
+
export { AdminPaymentMethodsView } from "./features/admin/index";
|
|
1192
|
+
export type { AdminPaymentMethodsViewProps } from "./features/admin/index";
|
|
1193
|
+
export { AdminPaymentClustersView } from "./features/admin/index";
|
|
1194
|
+
export type { AdminPaymentClustersViewProps } from "./features/admin/index";
|
|
1186
1195
|
export { AdminTopBar } from "./features/admin/index";
|
|
1187
1196
|
export { AdminTopProductsTable } from "./features/admin/index";
|
|
1188
1197
|
export { AdminUsersView } from "./features/admin/index";
|
package/dist/index.js
CHANGED
|
@@ -1117,6 +1117,8 @@ export { passwordResetTokenRepository } from "./repositories/index";
|
|
|
1117
1117
|
// [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
|
|
1118
1118
|
// payoutRepository - Shared export for payout repository.
|
|
1119
1119
|
export { payoutRepository } from "./repositories/index";
|
|
1120
|
+
// savedPaymentMethodsRepository - user saved payment methods (UPI, card, bank) with PII encryption + ban system.
|
|
1121
|
+
export { savedPaymentMethodsRepository, SavedPaymentMethodsRepository } from "./repositories/index";
|
|
1120
1122
|
// [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
|
|
1121
1123
|
// productRepository - Shared export for product repository.
|
|
1122
1124
|
export { productRepository } from "./repositories/index";
|
|
@@ -2274,6 +2276,14 @@ export { AdminContactEditorView } from "./features/admin/index";
|
|
|
2274
2276
|
export { AdminReturnRequestsView } from "./features/admin/index";
|
|
2275
2277
|
// AdminStoreAddressesView - Admin read-only store pickup locations overview (LL17).
|
|
2276
2278
|
export { AdminStoreAddressesView } from "./features/admin/index";
|
|
2279
|
+
// AdminAddressesView - Address ban management (Banned / Unban Requested / Suspicious tabs).
|
|
2280
|
+
export { AdminAddressesView } from "./features/admin/index";
|
|
2281
|
+
// AdminAddressClustersView - Multi-account shared address cluster view.
|
|
2282
|
+
export { AdminAddressClustersView } from "./features/admin/index";
|
|
2283
|
+
// AdminPaymentMethodsView - Payment method ban management.
|
|
2284
|
+
export { AdminPaymentMethodsView } from "./features/admin/index";
|
|
2285
|
+
// AdminPaymentClustersView - Multi-account shared payment identifier cluster view.
|
|
2286
|
+
export { AdminPaymentClustersView } from "./features/admin/index";
|
|
2277
2287
|
// [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
|
|
2278
2288
|
// AdminTopBar - Shared export for admin top bar.
|
|
2279
2289
|
export { AdminTopBar } from "./features/admin/index";
|
|
@@ -338,6 +338,10 @@ export declare const DEFAULT_ROUTE_MAP: {
|
|
|
338
338
|
readonly GUIDE_TEAM: "/admin/guide/team";
|
|
339
339
|
readonly GUIDE_ANALYTICS: "/admin/guide/analytics";
|
|
340
340
|
readonly GUIDE_TRUST: "/admin/guide/trust";
|
|
341
|
+
readonly BANNED_ADDRESSES: "/admin/banned-addresses";
|
|
342
|
+
readonly ADDRESS_CLUSTERS: "/admin/address-clusters";
|
|
343
|
+
readonly PAYMENT_METHODS: "/admin/payment-methods";
|
|
344
|
+
readonly PAYMENT_METHODS_CLUSTERS: "/admin/payment-methods/clusters";
|
|
341
345
|
};
|
|
342
346
|
readonly DEMO: {
|
|
343
347
|
readonly SEED: "/demo/seed";
|
|
@@ -675,6 +679,10 @@ export declare const ROUTES: {
|
|
|
675
679
|
readonly GUIDE_TEAM: "/admin/guide/team";
|
|
676
680
|
readonly GUIDE_ANALYTICS: "/admin/guide/analytics";
|
|
677
681
|
readonly GUIDE_TRUST: "/admin/guide/trust";
|
|
682
|
+
readonly BANNED_ADDRESSES: "/admin/banned-addresses";
|
|
683
|
+
readonly ADDRESS_CLUSTERS: "/admin/address-clusters";
|
|
684
|
+
readonly PAYMENT_METHODS: "/admin/payment-methods";
|
|
685
|
+
readonly PAYMENT_METHODS_CLUSTERS: "/admin/payment-methods/clusters";
|
|
678
686
|
};
|
|
679
687
|
readonly DEMO: {
|
|
680
688
|
readonly SEED: "/demo/seed";
|
|
@@ -334,6 +334,10 @@ export const DEFAULT_ROUTE_MAP = {
|
|
|
334
334
|
GUIDE_TEAM: "/admin/guide/team",
|
|
335
335
|
GUIDE_ANALYTICS: "/admin/guide/analytics",
|
|
336
336
|
GUIDE_TRUST: "/admin/guide/trust",
|
|
337
|
+
BANNED_ADDRESSES: "/admin/banned-addresses",
|
|
338
|
+
ADDRESS_CLUSTERS: "/admin/address-clusters",
|
|
339
|
+
PAYMENT_METHODS: "/admin/payment-methods",
|
|
340
|
+
PAYMENT_METHODS_CLUSTERS: "/admin/payment-methods/clusters",
|
|
337
341
|
},
|
|
338
342
|
DEMO: {
|
|
339
343
|
SEED: "/demo/seed",
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Server-side only. Never import this in browser/client-component code.
|
|
6
6
|
*/
|
|
7
7
|
import { getAdminAuthLite } from "../db-firebase/admin-auth-lite";
|
|
8
|
+
import { normalizeError } from "../../errors/normalize";
|
|
8
9
|
/** Firebase error codes that represent a normal "not authenticated" state. */
|
|
9
10
|
const EXPECTED_AUTH_CODES = new Set([
|
|
10
11
|
"auth/argument-error",
|
|
@@ -56,7 +57,8 @@ export const firebaseAuthProvider = {
|
|
|
56
57
|
const decoded = await getAdminAuthLite().verifyIdToken(token);
|
|
57
58
|
return toAuthPayload(decoded);
|
|
58
59
|
}
|
|
59
|
-
catch (err) {
|
|
60
|
+
catch (err) {
|
|
61
|
+
void normalizeError(err);
|
|
60
62
|
if (!isExpectedAuthError(err)) {
|
|
61
63
|
console.error("[@mohasinac/auth-firebase] Token verification failed:", err);
|
|
62
64
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* Server-side only.
|
|
8
8
|
*/
|
|
9
9
|
import { getAdminAuthLite } from "../db-firebase/admin-auth-lite";
|
|
10
|
+
import { normalizeError } from "../../errors/normalize";
|
|
10
11
|
/** Default session duration: 5 days (in milliseconds). */
|
|
11
12
|
const DEFAULT_EXPIRES_IN_MS = 60 * 60 * 24 * 5 * 1000;
|
|
12
13
|
const EXPECTED_SESSION_CODES = new Set([
|
|
@@ -56,7 +57,8 @@ export const firebaseSessionProvider = {
|
|
|
56
57
|
].includes(k))),
|
|
57
58
|
};
|
|
58
59
|
}
|
|
59
|
-
catch (err) {
|
|
60
|
+
catch (err) {
|
|
61
|
+
void normalizeError(err);
|
|
60
62
|
if (!EXPECTED_SESSION_CODES.has(err.code ?? "")) {
|
|
61
63
|
console.error("[@mohasinac/auth-firebase] Session cookie verification failed:", err);
|
|
62
64
|
}
|
|
@@ -29,6 +29,7 @@ export type { ClaimedCouponCreateInput } from "../features/promotions/repository
|
|
|
29
29
|
export { FAQsRepository, FirebaseFAQsRepository, faqsRepository, } from "../features/faq/repository/faqs.repository";
|
|
30
30
|
export { BlogRepository, blogRepository, } from "../features/blog/repository/blog.repository";
|
|
31
31
|
export { payoutRepository } from "../features/payments/repository/payout.repository";
|
|
32
|
+
export { SavedPaymentMethodsRepository, savedPaymentMethodsRepository, } from "../features/payments/repository/saved-payment-methods.repository";
|
|
32
33
|
export { GroupedListingsRepository, groupedListingsRepository, } from "../features/grouped/repository/grouped-listings.repository";
|
|
33
34
|
export { payoutMethodsRepository, shippingConfigsRepository, analyticsCardsRepository, analyticsAlertsRepository, storeCategoriesRepository, listingTemplatesRepository, moderationQueueRepository, reportsRepository, itemRequestsRepository, storeWhatsAppConfigRepository, storeGoogleConfigRepository, PayoutMethodsRepository, ShippingConfigsRepository, AnalyticsCardsRepository, AnalyticsAlertsRepository, StoreCategoriesRepository, ListingTemplatesRepository, ModerationQueueRepository, ReportsRepository, ItemRequestsRepository, StoreWhatsAppConfigRepository, StoreGoogleConfigRepository, } from "../features/store-extensions/repository/store-extensions.repositories";
|
|
34
35
|
export { roleOverridesRepository, customRolesRepository, adminNotificationsRepository, RoleOverridesRepository, CustomRolesRepository, AdminNotificationsRepository, } from "../features/store-extensions/repository/rbac.repositories";
|
|
@@ -35,6 +35,7 @@ export { ClaimedCouponsRepository, claimedCouponsRepository, } from "../features
|
|
|
35
35
|
export { FAQsRepository, FirebaseFAQsRepository, faqsRepository, } from "../features/faq/repository/faqs.repository";
|
|
36
36
|
export { BlogRepository, blogRepository, } from "../features/blog/repository/blog.repository";
|
|
37
37
|
export { payoutRepository } from "../features/payments/repository/payout.repository";
|
|
38
|
+
export { SavedPaymentMethodsRepository, savedPaymentMethodsRepository, } from "../features/payments/repository/saved-payment-methods.repository";
|
|
38
39
|
// Grouped listings repository
|
|
39
40
|
export { GroupedListingsRepository, groupedListingsRepository, } from "../features/grouped/repository/grouped-listings.repository";
|
|
40
41
|
// S-STORE-CROSS — 11 new collection repositories
|