@mohasinac/appkit 4.15.0 → 4.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/_internal/shared/actions/action-registry.d.ts +9 -2
  2. package/dist/_internal/shared/actions/action-registry.js +455 -6
  3. package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
  4. package/dist/_internal/shared/features/cart/schema.d.ts +11 -11
  5. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +22 -22
  6. package/dist/_internal/shared/features/orders/schema.d.ts +4 -4
  7. package/dist/_internal/shared/features/products/schema.d.ts +25 -25
  8. package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
  9. package/dist/_internal/shared/features/reviews/schema.d.ts +2 -2
  10. package/dist/client.d.ts +3 -3
  11. package/dist/client.js +3 -3
  12. package/dist/contracts/extend.d.ts +29 -0
  13. package/dist/contracts/extend.js +20 -0
  14. package/dist/contracts/index.d.ts +2 -1
  15. package/dist/contracts/index.js +2 -0
  16. package/dist/features/admin/components/AdminViewCards.js +24 -17
  17. package/dist/features/admin/components/DataListingView.js +15 -1
  18. package/dist/features/admin/components/DataTable.js +7 -17
  19. package/dist/features/auctions/schemas/index.d.ts +14 -14
  20. package/dist/features/auth/schemas/index.d.ts +2 -2
  21. package/dist/features/blog/actions/blog-actions.d.ts +7 -7
  22. package/dist/features/blog/schemas/blog-form.d.ts +6 -6
  23. package/dist/features/blog/schemas/index.d.ts +10 -10
  24. package/dist/features/cart/schemas/index.d.ts +3 -3
  25. package/dist/features/catalogue/schemas/validation.d.ts +12 -12
  26. package/dist/features/categories/schemas/index.d.ts +16 -16
  27. package/dist/features/collections/schemas/index.d.ts +8 -8
  28. package/dist/features/events/schemas/index.d.ts +2 -2
  29. package/dist/features/faq/actions/faq-actions.d.ts +6 -6
  30. package/dist/features/faq/schemas/index.d.ts +6 -6
  31. package/dist/features/grouped/schemas/grouped-listing-form.d.ts +2 -2
  32. package/dist/features/grouped/schemas/index.d.ts +4 -4
  33. package/dist/features/homepage/schemas/index.d.ts +40 -40
  34. package/dist/features/messages/schemas/index.d.ts +2 -2
  35. package/dist/features/orders/schemas/index.d.ts +24 -24
  36. package/dist/features/pre-orders/schemas/index.d.ts +4 -4
  37. package/dist/features/products/schemas/index.d.ts +36 -36
  38. package/dist/features/products/schemas/product-features.validators.d.ts +2 -2
  39. package/dist/features/promotions/schemas/index.d.ts +14 -14
  40. package/dist/features/reviews/schemas/index.d.ts +14 -14
  41. package/dist/features/scams/schemas/index.d.ts +2 -2
  42. package/dist/features/search/schemas/index.d.ts +2 -2
  43. package/dist/features/seller/components/SellerAnalyticsAlertsView.js +27 -9
  44. package/dist/features/seller/schemas/index.d.ts +2 -2
  45. package/dist/features/shipments/schemas/validation.d.ts +22 -22
  46. package/dist/features/store-extensions/schemas/listing-template-form.d.ts +22 -4
  47. package/dist/features/store-extensions/schemas/listing-template-form.js +42 -1
  48. package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +19 -13
  49. package/dist/features/store-extensions/schemas/shipping-config-form.js +25 -2
  50. package/dist/features/store-extensions/schemas/store-category-form.d.ts +42 -2
  51. package/dist/features/store-extensions/schemas/store-category-form.js +28 -0
  52. package/dist/features/stores/schemas/index.d.ts +4 -4
  53. package/dist/features/support/schemas/index.d.ts +4 -4
  54. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +24 -0
  55. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.js +1 -1
  58. package/dist/schemas/registry.d.ts +116 -113
  59. package/dist/styles.css +1 -1
  60. package/dist/tailwind-utilities.css +1 -1
  61. package/dist/ui/DataTable.js +4 -2
  62. package/dist/ui/columns/build-columns.d.ts +6 -1
  63. package/dist/ui/columns/build-columns.js +53 -0
  64. package/dist/ui/columns/cell-renderers.d.ts +68 -0
  65. package/dist/ui/columns/cell-renderers.js +111 -0
  66. package/dist/ui/columns/column-renderers.d.ts +6 -1
  67. package/dist/ui/columns/column-renderers.js +6 -1
  68. package/dist/ui/columns/index.d.ts +2 -1
  69. package/dist/ui/columns/index.js +5 -1
  70. package/dist/ui/components/Button.js +27 -2
  71. package/dist/ui/icons/icon-registry.d.ts +65 -0
  72. package/dist/ui/icons/icon-registry.js +115 -0
  73. package/package.json +1 -1
@@ -110,11 +110,11 @@ export declare const reviewFirestoreSchema: z.ZodObject<{
110
110
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
111
111
  }, z.ZodTypeAny, "passthrough">;
112
112
  userId: string;
113
+ rating: number;
113
114
  verified: boolean;
114
115
  productId: string;
115
116
  productTitle: string;
116
117
  userName: string;
117
- rating: number;
118
118
  comment: string;
119
119
  helpfulCount: number;
120
120
  reportCount: number;
@@ -126,9 +126,10 @@ export declare const reviewFirestoreSchema: z.ZodObject<{
126
126
  trimStart?: number | undefined;
127
127
  } | undefined;
128
128
  storeId?: string | undefined;
129
+ listingType?: string | undefined;
130
+ storeName?: string | undefined;
129
131
  images?: string[] | undefined;
130
132
  featured?: boolean | undefined;
131
- listingType?: string | undefined;
132
133
  userAvatar?: string | undefined;
133
134
  moderatorId?: string | undefined;
134
135
  moderatorNote?: string | undefined;
@@ -139,7 +140,6 @@ export declare const reviewFirestoreSchema: z.ZodObject<{
139
140
  rejectedAt?: string | Date | z.objectOutputType<{
140
141
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
141
142
  }, z.ZodTypeAny, "passthrough"> | undefined;
142
- storeName?: string | undefined;
143
143
  userSlug?: string | undefined;
144
144
  hasImages?: boolean | undefined;
145
145
  isAnonymous?: boolean | undefined;
@@ -158,11 +158,11 @@ export declare const reviewFirestoreSchema: z.ZodObject<{
158
158
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
159
159
  }, z.ZodTypeAny, "passthrough">;
160
160
  userId: string;
161
+ rating: number;
161
162
  verified: boolean;
162
163
  productId: string;
163
164
  productTitle: string;
164
165
  userName: string;
165
- rating: number;
166
166
  comment: string;
167
167
  helpfulCount: number;
168
168
  reportCount: number;
@@ -174,9 +174,10 @@ export declare const reviewFirestoreSchema: z.ZodObject<{
174
174
  trimStart?: number | undefined;
175
175
  } | undefined;
176
176
  storeId?: string | undefined;
177
+ listingType?: string | undefined;
178
+ storeName?: string | undefined;
177
179
  images?: string[] | undefined;
178
180
  featured?: boolean | undefined;
179
- listingType?: string | undefined;
180
181
  userAvatar?: string | undefined;
181
182
  moderatorId?: string | undefined;
182
183
  moderatorNote?: string | undefined;
@@ -187,7 +188,6 @@ export declare const reviewFirestoreSchema: z.ZodObject<{
187
188
  rejectedAt?: string | Date | z.objectInputType<{
188
189
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
189
190
  }, z.ZodTypeAny, "passthrough"> | undefined;
190
- storeName?: string | undefined;
191
191
  userSlug?: string | undefined;
192
192
  hasImages?: boolean | undefined;
193
193
  isAnonymous?: boolean | undefined;
@@ -293,9 +293,9 @@ export declare const reviewSchema: z.ZodObject<{
293
293
  status: "pending" | "approved" | "rejected";
294
294
  id: string;
295
295
  userId: string;
296
+ rating: 3 | 1 | 2 | 4 | 5;
296
297
  productId: string;
297
298
  userName: string;
298
- rating: 3 | 1 | 2 | 4 | 5;
299
299
  title?: string | undefined;
300
300
  video?: {
301
301
  url: string;
@@ -306,27 +306,27 @@ export declare const reviewSchema: z.ZodObject<{
306
306
  } | undefined;
307
307
  createdAt?: string | undefined;
308
308
  updatedAt?: string | undefined;
309
+ listingType?: string | undefined;
310
+ storeName?: string | undefined;
309
311
  verified?: boolean | undefined;
310
312
  images?: {
311
313
  url: string;
312
314
  thumbnailUrl?: string | undefined;
313
315
  }[] | undefined;
314
316
  featured?: boolean | undefined;
315
- listingType?: string | undefined;
316
317
  productTitle?: string | undefined;
317
318
  userAvatar?: string | undefined;
318
319
  comment?: string | undefined;
319
320
  helpfulCount?: number | undefined;
320
321
  reportCount?: number | undefined;
321
- storeName?: string | undefined;
322
322
  storeSlug?: string | undefined;
323
323
  }, {
324
324
  status: "pending" | "approved" | "rejected";
325
325
  id: string;
326
326
  userId: string;
327
+ rating: 3 | 1 | 2 | 4 | 5;
327
328
  productId: string;
328
329
  userName: string;
329
- rating: 3 | 1 | 2 | 4 | 5;
330
330
  title?: string | undefined;
331
331
  video?: {
332
332
  url: string;
@@ -337,19 +337,19 @@ export declare const reviewSchema: z.ZodObject<{
337
337
  } | undefined;
338
338
  createdAt?: string | undefined;
339
339
  updatedAt?: string | undefined;
340
+ listingType?: string | undefined;
341
+ storeName?: string | undefined;
340
342
  verified?: boolean | undefined;
341
343
  images?: {
342
344
  url: string;
343
345
  thumbnailUrl?: string | undefined;
344
346
  }[] | undefined;
345
347
  featured?: boolean | undefined;
346
- listingType?: string | undefined;
347
348
  productTitle?: string | undefined;
348
349
  userAvatar?: string | undefined;
349
350
  comment?: string | undefined;
350
351
  helpfulCount?: number | undefined;
351
352
  reportCount?: number | undefined;
352
- storeName?: string | undefined;
353
353
  storeSlug?: string | undefined;
354
354
  }>;
355
355
  /** Base schema for list-query parameters. */
@@ -370,9 +370,9 @@ export declare const reviewListParamsSchema: z.ZodObject<{
370
370
  perPage?: number | undefined;
371
371
  storeId?: string | undefined;
372
372
  userId?: string | undefined;
373
+ rating?: number | undefined;
373
374
  featured?: boolean | undefined;
374
375
  productId?: string | undefined;
375
- rating?: number | undefined;
376
376
  }, {
377
377
  sort?: string | undefined;
378
378
  status?: "pending" | "approved" | "rejected" | undefined;
@@ -380,7 +380,7 @@ export declare const reviewListParamsSchema: z.ZodObject<{
380
380
  perPage?: number | undefined;
381
381
  storeId?: string | undefined;
382
382
  userId?: string | undefined;
383
+ rating?: number | undefined;
383
384
  featured?: boolean | undefined;
384
385
  productId?: string | undefined;
385
- rating?: number | undefined;
386
386
  }>;
@@ -87,9 +87,9 @@ export declare const scammerFirestoreSchema: z.ZodObject<{
87
87
  updatedAt: string | Date | z.objectOutputType<{
88
88
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
89
89
  }, z.ZodTypeAny, "passthrough">;
90
+ views: number;
90
91
  description: string;
91
92
  tags: string[];
92
- views: number;
93
93
  scamType: string;
94
94
  reportedBy: string;
95
95
  reportedByAnon: boolean;
@@ -127,9 +127,9 @@ export declare const scammerFirestoreSchema: z.ZodObject<{
127
127
  updatedAt: string | Date | z.objectInputType<{
128
128
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
129
129
  }, z.ZodTypeAny, "passthrough">;
130
+ views: number;
130
131
  description: string;
131
132
  tags: string[];
132
- views: number;
133
133
  scamType: string;
134
134
  reportedBy: string;
135
135
  reportedByAnon: boolean;
@@ -27,9 +27,9 @@ export declare const searchProductItemSchema: z.ZodObject<{
27
27
  currency?: string | undefined;
28
28
  status?: string | undefined;
29
29
  price?: number | undefined;
30
+ listingType?: "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | undefined;
30
31
  mainImage?: string | undefined;
31
32
  featured?: boolean | undefined;
32
- listingType?: "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | undefined;
33
33
  isPromoted?: boolean | undefined;
34
34
  }, {
35
35
  id: string;
@@ -38,9 +38,9 @@ export declare const searchProductItemSchema: z.ZodObject<{
38
38
  currency?: string | undefined;
39
39
  status?: string | undefined;
40
40
  price?: number | undefined;
41
+ listingType?: "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | undefined;
41
42
  mainImage?: string | undefined;
42
43
  featured?: boolean | undefined;
43
- listingType?: "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | undefined;
44
44
  isPromoted?: boolean | undefined;
45
45
  }>;
46
46
  /**
@@ -6,6 +6,9 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
6
6
  import { Alert, Badge, Button, Div, Form, FormActions, Heading, Input, Row, Section, Select, Stack, Text, Toggle, useToast } from "../../../ui";
7
7
  import { apiClient } from "../../../http";
8
8
  import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
9
+ import { analyticsAlertCreateSchema } from "../../store-extensions/schemas/analytics-forms";
10
+ import { FormErrorSummary } from "../../../ui/forms/FormErrorSummary";
11
+ import { ValidationError } from "../../../errors/validation-error";
9
12
  const __P = {
10
13
  p5: "p-[var(--appkit-space-5)]",
11
14
  };
@@ -79,17 +82,29 @@ export function SellerAnalyticsAlertsView({ labels = {}, }) {
79
82
  const alerts = data ?? [];
80
83
  const createMutation = useApiMutation({
81
84
  mutationFn: async () => {
82
- const payload = {
85
+ /*
86
+ * Parsed against the SAME schema the route uses, before the request.
87
+ *
88
+ * This form used to hand-build its payload and included `scope: "seller"`
89
+ * — a field the route pins from the session and the schema does not
90
+ * declare. Once that schema became `.strict()`, every "Create Alert"
91
+ * became a 400, and nothing local could have caught it: the client had
92
+ * no schema to check against. Parsing here is the structural fix, not
93
+ * the deletion of one key.
94
+ */
95
+ const parsed = analyticsAlertCreateSchema.safeParse({
83
96
  label: draft.label,
84
97
  metric: draft.metric,
85
98
  operator: draft.operator,
86
- threshold: Number(draft.threshold),
87
- windowHours: Number(draft.windowHours),
99
+ threshold: draft.threshold,
100
+ windowHours: draft.windowHours,
88
101
  notifyChannels: draft.notifyChannels,
89
- scope: "seller",
90
102
  isActive: true,
91
- };
92
- return apiClient.post(SELLER_ENDPOINTS.ANALYTICS_ALERTS, payload);
103
+ });
104
+ if (!parsed.success) {
105
+ throw new ValidationError(parsed.error.issues[0]?.message ?? "Invalid alert", parsed.error.issues);
106
+ }
107
+ return apiClient.post(SELLER_ENDPOINTS.ANALYTICS_ALERTS, parsed.data);
93
108
  },
94
109
  onSuccess: () => {
95
110
  showToast("Alert created", "success");
@@ -97,7 +112,7 @@ export function SellerAnalyticsAlertsView({ labels = {}, }) {
97
112
  setShowForm(false);
98
113
  setDraft(EMPTY_DRAFT);
99
114
  },
100
- onError: () => showToast("Failed to create alert", "error"),
115
+ onError: (err) => showToast(err?.message ?? "Failed to create alert", "error"),
101
116
  });
102
117
  const toggleMutation = useApiMutation({
103
118
  mutationFn: async ({ id, isActive }) => apiClient.patch(SELLER_ENDPOINTS.ANALYTICS_ALERT_BY_ID(id), { isActive }),
@@ -122,7 +137,10 @@ export function SellerAnalyticsAlertsView({ labels = {}, }) {
122
137
  : [...d.notifyChannels, ch],
123
138
  }));
124
139
  }, []);
125
- return (_jsxs(Stack, { gap: "lg", children: [_jsxs(Row, { justify: "between", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", color: "primary", children: labels.title ?? "Analytics Alerts" }), _jsx(Button, { size: "sm", onClick: () => setShowForm((v) => !v), children: showForm ? "Cancel" : "+ New Alert" })] }), _jsx(Text, { size: "sm", color: "muted", children: "Get notified when a key metric crosses a threshold. Alerts check the metric over the selected window and fire through your chosen channels." }), showForm && (_jsxs(Section, { className: `${__P.p5} space-y-[1rem]`, rounded: "xl", border: "default", children: [_jsx(Heading, { level: 3, size: "sm", weight: "semibold", color: "primary", children: "Create Alert" }), _jsxs(Form, { onSubmit: (e) => { e.preventDefault(); createMutation.mutate(); }, children: [_jsxs(Div, { layout: "grid", gap: "4", className: "sm:grid-cols-2", children: [_jsx(Input, { label: "Alert label", value: draft.label, onChange: (e) => setDraft((d) => ({ ...d, label: e.target.value })), placeholder: "e.g. Low daily orders", required: true }), _jsx(Select, { label: "Metric", value: draft.metric, onValueChange: (v) => setDraft((d) => ({ ...d, metric: v })), options: METRIC_OPTIONS }), _jsx(Select, { label: "Operator", value: draft.operator, onValueChange: (v) => setDraft((d) => ({ ...d, operator: v })), options: OPERATOR_OPTIONS }), _jsx(Input, { label: "Threshold", type: "number", value: draft.threshold, onChange: (e) => setDraft((d) => ({ ...d, threshold: e.target.value })), placeholder: "e.g. 10", required: true }), _jsx(Select, { label: "Check window", value: draft.windowHours, onValueChange: (v) => setDraft((d) => ({ ...d, windowHours: v })), options: WINDOW_OPTIONS })] }), _jsxs(Div, { className: "mt-3", children: [_jsx(Text, { className: "mb-2", color: "muted", size: "xs", weight: "medium", children: "Notify via" }), _jsx(Row, { gap: "sm", wrap: true, children: CHANNEL_OPTIONS.map((ch) => (_jsx(Button, { variant: "outline", type: "button", onClick: () => toggleChannel(ch.value), rounded: "full", paddingX: "sm", paddingY: "xs", textSize: "xs", className: draft.notifyChannels.includes(ch.value)
140
+ return (_jsxs(Stack, { gap: "lg", children: [_jsxs(Row, { justify: "between", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", color: "primary", children: labels.title ?? "Analytics Alerts" }), _jsx(Button, { size: "sm", onClick: () => setShowForm((v) => !v), children: showForm ? "Cancel" : "+ New Alert" })] }), _jsx(Text, { size: "sm", color: "muted", children: "Get notified when a key metric crosses a threshold. Alerts check the metric over the selected window and fire through your chosen channels." }), showForm && (_jsxs(Section, { className: `${__P.p5} space-y-[1rem]`, rounded: "xl", border: "default", children: [_jsx(Heading, { level: 3, size: "sm", weight: "semibold", color: "primary", children: "Create Alert" }), _jsxs(Form, { schema: analyticsAlertCreateSchema, onSubmit: (e) => {
141
+ e.preventDefault();
142
+ createMutation.mutate();
143
+ }, children: [_jsxs(Div, { layout: "grid", gap: "4", className: "sm:grid-cols-2", children: [_jsx(Input, { label: "Alert label", value: draft.label, onChange: (e) => setDraft((d) => ({ ...d, label: e.target.value })), placeholder: "e.g. Low daily orders", required: true }), _jsx(Select, { label: "Metric", value: draft.metric, onValueChange: (v) => setDraft((d) => ({ ...d, metric: v })), options: METRIC_OPTIONS }), _jsx(Select, { label: "Operator", value: draft.operator, onValueChange: (v) => setDraft((d) => ({ ...d, operator: v })), options: OPERATOR_OPTIONS }), _jsx(Input, { label: "Threshold", type: "number", value: draft.threshold, onChange: (e) => setDraft((d) => ({ ...d, threshold: e.target.value })), placeholder: "e.g. 10", required: true }), _jsx(Select, { label: "Check window", value: draft.windowHours, onValueChange: (v) => setDraft((d) => ({ ...d, windowHours: v })), options: WINDOW_OPTIONS })] }), _jsxs(Div, { className: "mt-3", children: [_jsx(Text, { className: "mb-2", color: "muted", size: "xs", weight: "medium", children: "Notify via" }), _jsx(Row, { gap: "sm", wrap: true, children: CHANNEL_OPTIONS.map((ch) => (_jsx(Button, { variant: "outline", type: "button", onClick: () => toggleChannel(ch.value), rounded: "full", paddingX: "sm", paddingY: "xs", textSize: "xs", className: draft.notifyChannels.includes(ch.value)
126
144
  ? "bg-[var(--appkit-color-primary)] text-white border-transparent"
127
- : "bg-[var(--appkit-color-surface)] text-[var(--appkit-color-text-muted)] border-[var(--appkit-color-border)]", children: ch.label }, ch.value))) })] }), _jsx(FormActions, { align: "right", className: "mt-4", children: _jsx(Button, { type: "submit", isLoading: createMutation.isPending, children: createMutation.isPending ? "Creating…" : "Create Alert" }) })] })] })), isLoading && (_jsx(Stack, { gap: "sm", children: [1, 2, 3].map((i) => (_jsx(Div, { className: "h-16 animate-pulse", surface: "subtle", rounded: "lg" }, i))) })), !isLoading && alerts.length === 0 && !showForm && (_jsx(Alert, { variant: "info", children: "No alerts configured. Create an alert to get notified when a key metric crosses a threshold." })), !isLoading && alerts.length > 0 && (_jsx(Stack, { gap: "3", children: alerts.map((alert) => (_jsx(AlertCard, { alert: alert, onToggle: (id, isActive) => toggleMutation.mutate({ id, isActive }), onDelete: (id) => deleteMutation.mutate(id) }, alert.id))) }))] }));
145
+ : "bg-[var(--appkit-color-surface)] text-[var(--appkit-color-text-muted)] border-[var(--appkit-color-border)]", children: ch.label }, ch.value))) })] }), _jsx(FormErrorSummary, {}), _jsx(FormActions, { align: "right", className: "mt-4", children: _jsx(Button, { type: "submit", isLoading: createMutation.isPending, children: createMutation.isPending ? "Creating…" : "Create Alert" }) })] })] })), isLoading && (_jsx(Stack, { gap: "sm", children: [1, 2, 3].map((i) => (_jsx(Div, { className: "h-16 animate-pulse", surface: "subtle", rounded: "lg" }, i))) })), !isLoading && alerts.length === 0 && !showForm && (_jsx(Alert, { variant: "info", children: "No alerts configured. Create an alert to get notified when a key metric crosses a threshold." })), !isLoading && alerts.length > 0 && (_jsx(Stack, { gap: "3", children: alerts.map((alert) => (_jsx(AlertCard, { alert: alert, onToggle: (id, isActive) => toggleMutation.mutate({ id, isActive }), onDelete: (id) => deleteMutation.mutate(id) }, alert.id))) }))] }));
128
146
  }
@@ -89,8 +89,8 @@ export declare const sellerStoreSchema: z.ZodObject<{
89
89
  id: string;
90
90
  createdAt: string;
91
91
  updatedAt: string;
92
- ownerId: string;
93
92
  storeName: string;
93
+ ownerId: string;
94
94
  storeSlug: string;
95
95
  isPublic: boolean;
96
96
  location?: string | undefined;
@@ -121,8 +121,8 @@ export declare const sellerStoreSchema: z.ZodObject<{
121
121
  id: string;
122
122
  createdAt: string;
123
123
  updatedAt: string;
124
- ownerId: string;
125
124
  storeName: string;
125
+ ownerId: string;
126
126
  storeSlug: string;
127
127
  isPublic: boolean;
128
128
  location?: string | undefined;
@@ -230,36 +230,36 @@ export declare const createShipmentItemSchema: z.ZodEffects<z.ZodObject<{
230
230
  quantity: number;
231
231
  isForSelfUse: boolean;
232
232
  notes?: string | undefined;
233
- categorySlugs?: string[] | undefined;
234
- brandSlug?: string | undefined;
235
233
  price?: number | undefined;
234
+ brandSlug?: string | undefined;
235
+ categorySlugs?: string[] | undefined;
236
236
  condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
237
237
  }, {
238
238
  title: string;
239
239
  quantity: number;
240
240
  isForSelfUse: boolean;
241
241
  notes?: string | undefined;
242
- categorySlugs?: string[] | undefined;
243
- brandSlug?: string | undefined;
244
242
  price?: number | undefined;
243
+ brandSlug?: string | undefined;
244
+ categorySlugs?: string[] | undefined;
245
245
  condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
246
246
  }>, {
247
247
  title: string;
248
248
  quantity: number;
249
249
  isForSelfUse: boolean;
250
250
  notes?: string | undefined;
251
- categorySlugs?: string[] | undefined;
252
- brandSlug?: string | undefined;
253
251
  price?: number | undefined;
252
+ brandSlug?: string | undefined;
253
+ categorySlugs?: string[] | undefined;
254
254
  condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
255
255
  }, {
256
256
  title: string;
257
257
  quantity: number;
258
258
  isForSelfUse: boolean;
259
259
  notes?: string | undefined;
260
- categorySlugs?: string[] | undefined;
261
- brandSlug?: string | undefined;
262
260
  price?: number | undefined;
261
+ brandSlug?: string | undefined;
262
+ categorySlugs?: string[] | undefined;
263
263
  condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
264
264
  }>;
265
265
  export declare const updateShipmentItemSchema: z.ZodObject<{
@@ -278,11 +278,11 @@ export declare const updateShipmentItemSchema: z.ZodObject<{
278
278
  }, "strip", z.ZodTypeAny, {
279
279
  title?: string | undefined;
280
280
  notes?: string | undefined;
281
- categorySlugs?: string[] | undefined;
282
- brandSlug?: string | undefined;
283
281
  price?: number | undefined;
284
- condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
282
+ brandSlug?: string | undefined;
285
283
  quantity?: number | undefined;
284
+ categorySlugs?: string[] | undefined;
285
+ condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
286
286
  isForSelfUse?: boolean | undefined;
287
287
  linkedProductId?: string | null | undefined;
288
288
  linkedProductSlug?: string | null | undefined;
@@ -290,11 +290,11 @@ export declare const updateShipmentItemSchema: z.ZodObject<{
290
290
  }, {
291
291
  title?: string | undefined;
292
292
  notes?: string | undefined;
293
- categorySlugs?: string[] | undefined;
294
- brandSlug?: string | undefined;
295
293
  price?: number | undefined;
296
- condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
294
+ brandSlug?: string | undefined;
297
295
  quantity?: number | undefined;
296
+ categorySlugs?: string[] | undefined;
297
+ condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
298
298
  isForSelfUse?: boolean | undefined;
299
299
  linkedProductId?: string | null | undefined;
300
300
  linkedProductSlug?: string | null | undefined;
@@ -319,36 +319,36 @@ export declare const bulkShipmentItemsSchema: z.ZodEffects<z.ZodArray<z.ZodObjec
319
319
  quantity: number;
320
320
  isForSelfUse: boolean;
321
321
  notes?: string | undefined;
322
- categorySlugs?: string[] | undefined;
323
- brandSlug?: string | undefined;
324
322
  price?: number | undefined;
323
+ brandSlug?: string | undefined;
324
+ categorySlugs?: string[] | undefined;
325
325
  condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
326
326
  }, {
327
327
  title: string;
328
328
  quantity: number;
329
329
  isForSelfUse: boolean;
330
330
  notes?: string | undefined;
331
- categorySlugs?: string[] | undefined;
332
- brandSlug?: string | undefined;
333
331
  price?: number | undefined;
332
+ brandSlug?: string | undefined;
333
+ categorySlugs?: string[] | undefined;
334
334
  condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
335
335
  }>, "many">, {
336
336
  title: string;
337
337
  quantity: number;
338
338
  isForSelfUse: boolean;
339
339
  notes?: string | undefined;
340
- categorySlugs?: string[] | undefined;
341
- brandSlug?: string | undefined;
342
340
  price?: number | undefined;
341
+ brandSlug?: string | undefined;
342
+ categorySlugs?: string[] | undefined;
343
343
  condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
344
344
  }[], {
345
345
  title: string;
346
346
  quantity: number;
347
347
  isForSelfUse: boolean;
348
348
  notes?: string | undefined;
349
- categorySlugs?: string[] | undefined;
350
- brandSlug?: string | undefined;
351
349
  price?: number | undefined;
350
+ brandSlug?: string | undefined;
351
+ categorySlugs?: string[] | undefined;
352
352
  condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | "graded" | undefined;
353
353
  }[]>;
354
354
  export type CreateShipmentInput = z.infer<typeof createShipmentSchema>;
@@ -1,4 +1,8 @@
1
1
  import { z } from "zod";
2
+ export declare const LISTING_TEMPLATE_TYPE_OPTIONS: {
3
+ value: "art" | "stickers" | "classified" | "standard" | "auction" | "pre-order" | "prize-draw" | "digital-code" | "live" | "bundle";
4
+ label: string;
5
+ }[];
2
6
  /**
3
7
  * 🛑 `annotate()` must be the OUTERMOST call on each field — it keys a WeakMap
4
8
  * by schema instance and every zod wrapper returns a new one.
@@ -33,8 +37,8 @@ export type ListingTemplateFormValues = z.infer<typeof listingTemplateFormSchema
33
37
  */
34
38
  export declare const listingTemplateCreateSchema: z.ZodObject<{
35
39
  name: z.ZodString;
36
- description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
37
40
  listingType: z.ZodEnum<["standard", "auction", "pre-order", "prize-draw", "bundle", "classified", "digital-code", "live", "art", "stickers"]>;
41
+ description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
38
42
  isActive: z.ZodOptional<z.ZodBoolean>;
39
43
  isShared: z.ZodOptional<z.ZodBoolean>;
40
44
  defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<import("../../..").FirestoreValue, z.ZodTypeDef, import("../../..").FirestoreValue>>>;
@@ -54,6 +58,20 @@ export declare const listingTemplateCreateSchema: z.ZodObject<{
54
58
  defaults?: Record<string, import("../../..").FirestoreValue> | undefined;
55
59
  }>;
56
60
  /** Update contract — every field optional, and the same ownership fields absent. */
61
+ /**
62
+ * Update contract.
63
+ *
64
+ * `.strict()` as well as `.partial()`: the edit page used to PATCH the whole
65
+ * loaded document — `id`, `storeId`, `createdAt`, `updatedAt`, `usageCount`
66
+ * and all — and a non-strict schema silently stripped them, which reads as a
67
+ * clean save while quietly discarding half the payload. The page now sends
68
+ * only the editable fields, so a stray key here is a real mistake and should
69
+ * be a 400.
70
+ *
71
+ * `listingType` remains accepted-but-optional rather than removed: it is not
72
+ * editable in the UI (changing a template's type would invalidate every
73
+ * default stored against it), but the create path shares this shape.
74
+ */
57
75
  export declare const listingTemplateUpdateSchema: z.ZodObject<{
58
76
  name: z.ZodOptional<z.ZodString>;
59
77
  description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
@@ -61,17 +79,17 @@ export declare const listingTemplateUpdateSchema: z.ZodObject<{
61
79
  defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<import("../../..").FirestoreValue, z.ZodTypeDef, import("../../..").FirestoreValue>>>;
62
80
  isShared: z.ZodOptional<z.ZodBoolean>;
63
81
  isActive: z.ZodOptional<z.ZodBoolean>;
64
- }, "strip", z.ZodTypeAny, {
82
+ }, "strict", z.ZodTypeAny, {
65
83
  name?: string | undefined;
66
- description?: string | undefined;
67
84
  listingType?: "art" | "stickers" | "classified" | "standard" | "auction" | "pre-order" | "prize-draw" | "digital-code" | "live" | "bundle" | undefined;
85
+ description?: string | undefined;
68
86
  isActive?: boolean | undefined;
69
87
  isShared?: boolean | undefined;
70
88
  defaults?: Record<string, import("../../..").FirestoreValue> | undefined;
71
89
  }, {
72
90
  name?: string | undefined;
73
- description?: string | undefined;
74
91
  listingType?: "art" | "stickers" | "classified" | "standard" | "auction" | "pre-order" | "prize-draw" | "digital-code" | "live" | "bundle" | undefined;
92
+ description?: string | undefined;
75
93
  isActive?: boolean | undefined;
76
94
  isShared?: boolean | undefined;
77
95
  defaults?: Record<string, import("../../..").FirestoreValue> | undefined;
@@ -41,6 +41,33 @@ import { firestoreValueSchema } from "../../../schemas/firestore-value";
41
41
  * templates while `bundle` lingered.
42
42
  */
43
43
  const listingTemplateTypeSchema = z.enum(LISTING_TEMPLATE_TYPES);
44
+ /**
45
+ * Dropdown options, derived from the same runtime array the schema validates
46
+ * against.
47
+ *
48
+ * 🛑 The New Template page carried its own hand-written list of EIGHT of these
49
+ * ten. `art` and `stickers` were added to the union but not to that literal,
50
+ * so a seller could not create a template for either — the same defect the
51
+ * homepage-section create route had (21 values against a union of 25), one
52
+ * domain over. Labels are keyed `Record<ListingTemplateType, string>`, so a
53
+ * new type is a compile error here rather than a missing dropdown entry.
54
+ */
55
+ const LISTING_TEMPLATE_TYPE_LABEL = {
56
+ standard: "Standard",
57
+ auction: "Auction",
58
+ "pre-order": "Pre-order",
59
+ "prize-draw": "Prize draw",
60
+ bundle: "Bundle",
61
+ classified: "Classified",
62
+ "digital-code": "Digital code",
63
+ live: "Live item",
64
+ art: "Art print",
65
+ stickers: "Sticker sheet",
66
+ };
67
+ export const LISTING_TEMPLATE_TYPE_OPTIONS = LISTING_TEMPLATE_TYPES.map((value) => ({
68
+ value,
69
+ label: LISTING_TEMPLATE_TYPE_LABEL[value],
70
+ }));
44
71
  /**
45
72
  * 🛑 `annotate()` must be the OUTERMOST call on each field — it keys a WeakMap
46
73
  * by schema instance and every zod wrapper returns a new one.
@@ -84,4 +111,18 @@ export const listingTemplateCreateSchema = listingTemplateFormSchema.partial({
84
111
  defaults: true,
85
112
  });
86
113
  /** Update contract — every field optional, and the same ownership fields absent. */
87
- export const listingTemplateUpdateSchema = listingTemplateFormSchema.partial();
114
+ /**
115
+ * Update contract.
116
+ *
117
+ * `.strict()` as well as `.partial()`: the edit page used to PATCH the whole
118
+ * loaded document — `id`, `storeId`, `createdAt`, `updatedAt`, `usageCount`
119
+ * and all — and a non-strict schema silently stripped them, which reads as a
120
+ * clean save while quietly discarding half the payload. The page now sends
121
+ * only the editable fields, so a stray key here is a real mistake and should
122
+ * be a 400.
123
+ *
124
+ * `listingType` remains accepted-but-optional rather than removed: it is not
125
+ * editable in the UI (changing a template's type would invalidate every
126
+ * default stored against it), but the create path shares this shape.
127
+ */
128
+ export const listingTemplateUpdateSchema = listingTemplateFormSchema.partial().strict();
@@ -1,11 +1,17 @@
1
1
  import { z } from "zod";
2
+ import type { ShippingMethod } from "./firestore";
3
+ /** Dropdown options for any surface that picks a shipping method. */
4
+ export declare const SHIPPING_METHOD_OPTIONS: {
5
+ value: ShippingMethod;
6
+ label: string;
7
+ }[];
2
8
  /**
3
9
  * 🛑 `annotate()` must be the OUTERMOST call on each field — it keys a WeakMap
4
10
  * by schema instance and every zod wrapper returns a new one.
5
11
  */
6
12
  export declare const shippingConfigFormSchema: z.ZodEffects<z.ZodObject<{
7
13
  label: z.ZodString;
8
- method: z.ZodEnum<["free", "flat", "weight", "express", "pickup", "custom"]>;
14
+ method: z.ZodEnum<[ShippingMethod, ...ShippingMethod[]]>;
9
15
  flatRate: z.ZodOptional<z.ZodNumber>;
10
16
  pricePerKg: z.ZodOptional<z.ZodNumber>;
11
17
  freeAbove: z.ZodOptional<z.ZodNumber>;
@@ -17,7 +23,7 @@ export declare const shippingConfigFormSchema: z.ZodEffects<z.ZodObject<{
17
23
  label: string;
18
24
  isDefault: boolean;
19
25
  isActive: boolean;
20
- method: "flat" | "weight" | "custom" | "free" | "express" | "pickup";
26
+ method: ShippingMethod;
21
27
  estimatedDays?: number | undefined;
22
28
  freeAbove?: number | undefined;
23
29
  flatRate?: number | undefined;
@@ -27,7 +33,7 @@ export declare const shippingConfigFormSchema: z.ZodEffects<z.ZodObject<{
27
33
  label: string;
28
34
  isDefault: boolean;
29
35
  isActive: boolean;
30
- method: "flat" | "weight" | "custom" | "free" | "express" | "pickup";
36
+ method: ShippingMethod;
31
37
  estimatedDays?: number | undefined;
32
38
  freeAbove?: number | undefined;
33
39
  flatRate?: number | undefined;
@@ -37,7 +43,7 @@ export declare const shippingConfigFormSchema: z.ZodEffects<z.ZodObject<{
37
43
  label: string;
38
44
  isDefault: boolean;
39
45
  isActive: boolean;
40
- method: "flat" | "weight" | "custom" | "free" | "express" | "pickup";
46
+ method: ShippingMethod;
41
47
  estimatedDays?: number | undefined;
42
48
  freeAbove?: number | undefined;
43
49
  flatRate?: number | undefined;
@@ -47,7 +53,7 @@ export declare const shippingConfigFormSchema: z.ZodEffects<z.ZodObject<{
47
53
  label: string;
48
54
  isDefault: boolean;
49
55
  isActive: boolean;
50
- method: "flat" | "weight" | "custom" | "free" | "express" | "pickup";
56
+ method: ShippingMethod;
51
57
  estimatedDays?: number | undefined;
52
58
  freeAbove?: number | undefined;
53
59
  flatRate?: number | undefined;
@@ -58,7 +64,7 @@ export type ShippingConfigFormValues = z.infer<typeof shippingConfigFormSchema>;
58
64
  /** `storeId` is absent — the route sets it from the session, never the body. */
59
65
  export declare const shippingConfigCreateSchema: z.ZodEffects<z.ZodObject<{
60
66
  label: z.ZodString;
61
- method: z.ZodEnum<["free", "flat", "weight", "express", "pickup", "custom"]>;
67
+ method: z.ZodEnum<[ShippingMethod, ...ShippingMethod[]]>;
62
68
  flatRate: z.ZodOptional<z.ZodNumber>;
63
69
  pricePerKg: z.ZodOptional<z.ZodNumber>;
64
70
  freeAbove: z.ZodOptional<z.ZodNumber>;
@@ -70,7 +76,7 @@ export declare const shippingConfigCreateSchema: z.ZodEffects<z.ZodObject<{
70
76
  label: string;
71
77
  isDefault: boolean;
72
78
  isActive: boolean;
73
- method: "flat" | "weight" | "custom" | "free" | "express" | "pickup";
79
+ method: ShippingMethod;
74
80
  estimatedDays?: number | undefined;
75
81
  freeAbove?: number | undefined;
76
82
  flatRate?: number | undefined;
@@ -80,7 +86,7 @@ export declare const shippingConfigCreateSchema: z.ZodEffects<z.ZodObject<{
80
86
  label: string;
81
87
  isDefault: boolean;
82
88
  isActive: boolean;
83
- method: "flat" | "weight" | "custom" | "free" | "express" | "pickup";
89
+ method: ShippingMethod;
84
90
  estimatedDays?: number | undefined;
85
91
  freeAbove?: number | undefined;
86
92
  flatRate?: number | undefined;
@@ -90,7 +96,7 @@ export declare const shippingConfigCreateSchema: z.ZodEffects<z.ZodObject<{
90
96
  label: string;
91
97
  isDefault: boolean;
92
98
  isActive: boolean;
93
- method: "flat" | "weight" | "custom" | "free" | "express" | "pickup";
99
+ method: ShippingMethod;
94
100
  estimatedDays?: number | undefined;
95
101
  freeAbove?: number | undefined;
96
102
  flatRate?: number | undefined;
@@ -100,7 +106,7 @@ export declare const shippingConfigCreateSchema: z.ZodEffects<z.ZodObject<{
100
106
  label: string;
101
107
  isDefault: boolean;
102
108
  isActive: boolean;
103
- method: "flat" | "weight" | "custom" | "free" | "express" | "pickup";
109
+ method: ShippingMethod;
104
110
  estimatedDays?: number | undefined;
105
111
  freeAbove?: number | undefined;
106
112
  flatRate?: number | undefined;
@@ -114,7 +120,7 @@ export declare const shippingConfigCreateSchema: z.ZodEffects<z.ZodObject<{
114
120
  */
115
121
  export declare const shippingConfigUpdateSchema: z.ZodObject<{
116
122
  label: z.ZodOptional<z.ZodString>;
117
- method: z.ZodOptional<z.ZodEnum<["free", "flat", "weight", "express", "pickup", "custom"]>>;
123
+ method: z.ZodOptional<z.ZodEnum<[ShippingMethod, ...ShippingMethod[]]>>;
118
124
  flatRate: z.ZodOptional<z.ZodNumber>;
119
125
  pricePerKg: z.ZodOptional<z.ZodNumber>;
120
126
  freeAbove: z.ZodOptional<z.ZodNumber>;
@@ -127,7 +133,7 @@ export declare const shippingConfigUpdateSchema: z.ZodObject<{
127
133
  label?: string | undefined;
128
134
  isDefault?: boolean | undefined;
129
135
  isActive?: boolean | undefined;
130
- method?: "flat" | "weight" | "custom" | "free" | "express" | "pickup" | undefined;
136
+ method?: ShippingMethod | undefined;
131
137
  estimatedDays?: number | undefined;
132
138
  freeAbove?: number | undefined;
133
139
  flatRate?: number | undefined;
@@ -138,7 +144,7 @@ export declare const shippingConfigUpdateSchema: z.ZodObject<{
138
144
  label?: string | undefined;
139
145
  isDefault?: boolean | undefined;
140
146
  isActive?: boolean | undefined;
141
- method?: "flat" | "weight" | "custom" | "free" | "express" | "pickup" | undefined;
147
+ method?: ShippingMethod | undefined;
142
148
  estimatedDays?: number | undefined;
143
149
  freeAbove?: number | undefined;
144
150
  flatRate?: number | undefined;