@mohasinac/appkit 4.14.0 → 4.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/server/features/auctions/actions.js +2 -2
- package/dist/_internal/server/features/cart/service.d.ts +3 -3
- package/dist/_internal/server/features/checkout/actions.js +19 -0
- package/dist/_internal/server/features/checkout/source-context.d.ts +5 -0
- package/dist/_internal/server/features/checkout/source-context.js +157 -0
- package/dist/_internal/server/features/offers/adapters.d.ts +103 -0
- package/dist/_internal/server/features/offers/adapters.js +88 -0
- package/dist/_internal/server/features/offers/index.d.ts +2 -0
- package/dist/_internal/server/features/offers/index.js +1 -0
- package/dist/_internal/server/features/orders/adapters.js +24 -0
- package/dist/_internal/server/jobs/core/offerExpiry.js +10 -10
- package/dist/_internal/shared/actions/action-registry.d.ts +9 -2
- package/dist/_internal/shared/actions/action-registry.js +458 -7
- package/dist/_internal/shared/features/auctions/schema.d.ts +14 -2
- package/dist/_internal/shared/features/auctions/schema.js +13 -1
- package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
- package/dist/_internal/shared/features/cart/schema.d.ts +25 -20
- package/dist/_internal/shared/features/cart/schema.js +15 -0
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +22 -22
- package/dist/_internal/shared/features/orders/schema.d.ts +4 -4
- package/dist/_internal/shared/features/products/schema.d.ts +27 -27
- package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
- package/dist/_internal/shared/features/reviews/schema.d.ts +2 -2
- package/dist/_internal/shared/history/history.d.ts +22 -0
- package/dist/_internal/shared/history/history.js +41 -1
- package/dist/client.d.ts +13 -2
- package/dist/client.js +20 -2
- package/dist/constants/field-names.d.ts +8 -6
- package/dist/constants/field-names.js +48 -6
- package/dist/contracts/extend.d.ts +29 -0
- package/dist/contracts/extend.js +20 -0
- package/dist/contracts/index.d.ts +2 -1
- package/dist/contracts/index.js +2 -0
- package/dist/features/account/components/UserBidsView.js +12 -4
- package/dist/features/account/components/UserReturnsView.d.ts +3 -0
- package/dist/features/account/components/UserReturnsView.js +17 -1
- package/dist/features/admin/components/AdminAuditLogView.js +1 -0
- package/dist/features/admin/components/AdminBidsView.js +15 -2
- package/dist/features/admin/components/AdminBlogEditorView.js +65 -33
- package/dist/features/admin/components/AdminFeatureEditorView.js +35 -6
- package/dist/features/admin/components/AdminNavEditorView.js +15 -5
- package/dist/features/admin/components/AdminNewsletterView.js +18 -2
- package/dist/features/admin/components/AdminOffersView.js +62 -18
- package/dist/features/admin/components/AdminPaymentMethodsView.js +24 -4
- package/dist/features/admin/components/AdminScammerEditorView.d.ts +2 -1
- package/dist/features/admin/components/AdminScammerEditorView.js +3 -13
- package/dist/features/admin/components/AdminScammersView.js +3 -8
- package/dist/features/admin/components/AdminSectionsView.js +32 -23
- package/dist/features/admin/components/AdminSessionsView.js +17 -2
- package/dist/features/admin/components/AdminViewCards.js +24 -17
- package/dist/features/admin/components/DataListingView.js +15 -1
- package/dist/features/admin/components/DataTable.js +7 -17
- package/dist/features/admin/components/ViewAuditLogEntryModal.js +1 -0
- package/dist/features/admin/components/sections/adminSectionsTypes.d.ts +4 -2
- package/dist/features/admin/components/sections/adminSectionsTypes.js +45 -27
- package/dist/features/admin/constants/filter-tabs.d.ts +3 -0
- package/dist/features/admin/constants/filter-tabs.js +1 -0
- package/dist/features/admin/schemas/homepage-section-form.d.ts +22 -0
- package/dist/features/admin/schemas/homepage-section-form.js +68 -0
- package/dist/features/admin/schemas/nav-item-form.d.ts +74 -0
- package/dist/features/admin/schemas/nav-item-form.js +72 -0
- package/dist/features/auctions/components/AuctionBidsTable.d.ts +10 -1
- package/dist/features/auctions/components/AuctionBidsTable.js +22 -4
- package/dist/features/auctions/components/bid-detail-fields.d.ts +29 -0
- package/dist/features/auctions/components/bid-detail-fields.js +103 -0
- package/dist/features/auctions/schemas/index.d.ts +14 -14
- package/dist/features/audit-log/schemas/firestore.d.ts +14 -0
- package/dist/features/audit-log/schemas/firestore.js +7 -0
- package/dist/features/auth/schemas/index.d.ts +2 -2
- package/dist/features/blog/actions/blog-actions.d.ts +7 -7
- package/dist/features/blog/schemas/blog-form.d.ts +80 -0
- package/dist/features/blog/schemas/blog-form.js +100 -0
- package/dist/features/blog/schemas/index.d.ts +10 -10
- package/dist/features/cart/schemas/index.d.ts +3 -3
- package/dist/features/catalogue/schemas/validation.d.ts +12 -12
- package/dist/features/categories/schemas/index.d.ts +16 -16
- package/dist/features/collections/schemas/index.d.ts +8 -8
- package/dist/features/events/components/AdminEventEditorView.js +32 -54
- package/dist/features/events/components/AdminEventEntriesView.js +22 -3
- package/dist/features/events/schemas/event-form.d.ts +113 -0
- package/dist/features/events/schemas/event-form.js +82 -0
- package/dist/features/events/schemas/index.d.ts +2 -2
- package/dist/features/faq/actions/faq-actions.d.ts +6 -6
- package/dist/features/faq/schemas/index.d.ts +6 -6
- package/dist/features/grouped/schemas/grouped-listing-form.d.ts +101 -0
- package/dist/features/grouped/schemas/grouped-listing-form.js +89 -0
- package/dist/features/grouped/schemas/index.d.ts +4 -4
- package/dist/features/homepage/actions/homepage-section-actions.d.ts +11 -3
- package/dist/features/homepage/actions/homepage-section-actions.js +33 -1
- package/dist/features/homepage/schemas/index.d.ts +71 -40
- package/dist/features/homepage/schemas/index.js +24 -0
- package/dist/features/messages/schemas/index.d.ts +2 -2
- package/dist/features/orders/components/OrderStatusTimeline.d.ts +5 -1
- package/dist/features/orders/components/OrderStatusTimeline.js +39 -20
- package/dist/features/orders/repository/orders.repository.js +5 -0
- package/dist/features/orders/schemas/firestore.d.ts +36 -1
- package/dist/features/orders/schemas/index.d.ts +24 -24
- package/dist/features/orders/types/index.d.ts +35 -7
- package/dist/features/pre-orders/schemas/index.d.ts +4 -4
- package/dist/features/products/components/GroupSettingsPanel.js +5 -1
- package/dist/features/products/schemas/index.d.ts +38 -38
- package/dist/features/products/schemas/product-features.validators.d.ts +75 -2
- package/dist/features/products/schemas/product-features.validators.js +63 -0
- package/dist/features/promotions/schemas/index.d.ts +14 -14
- package/dist/features/reviews/schemas/index.d.ts +14 -14
- package/dist/features/scams/constants/scammer-status-display.d.ts +28 -0
- package/dist/features/scams/constants/scammer-status-display.js +79 -0
- package/dist/features/scams/schemas/index.d.ts +2 -2
- package/dist/features/search/schemas/index.d.ts +2 -2
- package/dist/features/seller/actions/offer-actions.js +32 -2
- package/dist/features/seller/components/OfferPhaseTimeline.d.ts +59 -0
- package/dist/features/seller/components/OfferPhaseTimeline.js +107 -0
- package/dist/features/seller/components/SellerBidsView.js +11 -4
- package/dist/features/seller/components/SellerCouponEditorView.js +17 -17
- package/dist/features/seller/components/SellerOffersView.js +2 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +38 -14
- package/dist/features/seller/repository/offer.repository.d.ts +69 -8
- package/dist/features/seller/repository/offer.repository.js +127 -23
- package/dist/features/seller/schemas/coupon-form.d.ts +72 -0
- package/dist/features/seller/schemas/coupon-form.js +116 -0
- package/dist/features/seller/schemas/firestore.d.ts +56 -2
- package/dist/features/seller/schemas/firestore.js +27 -0
- package/dist/features/seller/schemas/index.d.ts +2 -2
- package/dist/features/seller/schemas/offer-forms.d.ts +21 -0
- package/dist/features/seller/schemas/offer-forms.js +21 -0
- package/dist/features/shell/build-sections.d.ts +63 -0
- package/dist/features/shell/build-sections.js +207 -0
- package/dist/features/shell/field-ui-meta.d.ts +115 -0
- package/dist/features/shell/field-ui-meta.js +324 -0
- package/dist/features/shell/index.d.ts +4 -0
- package/dist/features/shell/index.js +2 -0
- package/dist/features/shipments/schemas/validation.d.ts +22 -22
- package/dist/features/status-history/components/StatusTimeline.d.ts +74 -0
- package/dist/features/status-history/components/StatusTimeline.js +46 -0
- package/dist/features/status-history/index.d.ts +11 -0
- package/dist/features/status-history/index.js +10 -0
- package/dist/features/store-extensions/components/ReviewDecisionModal.d.ts +27 -0
- package/dist/features/store-extensions/components/ReviewDecisionModal.js +82 -0
- package/dist/features/store-extensions/index.d.ts +12 -0
- package/dist/features/store-extensions/index.js +12 -0
- package/dist/features/store-extensions/schemas/admin-notification-form.d.ts +36 -0
- package/dist/features/store-extensions/schemas/admin-notification-form.js +114 -0
- package/dist/features/store-extensions/schemas/analytics-forms.d.ts +57 -0
- package/dist/features/store-extensions/schemas/analytics-forms.js +158 -0
- package/dist/features/store-extensions/schemas/custom-role-form.d.ts +85 -0
- package/dist/features/store-extensions/schemas/custom-role-form.js +118 -0
- package/dist/features/store-extensions/schemas/firestore.d.ts +21 -1
- package/dist/features/store-extensions/schemas/firestore.js +60 -0
- package/dist/features/store-extensions/schemas/google-config-form.d.ts +53 -0
- package/dist/features/store-extensions/schemas/google-config-form.js +105 -0
- package/dist/features/store-extensions/schemas/item-request-create-form.d.ts +28 -0
- package/dist/features/store-extensions/schemas/item-request-create-form.js +80 -0
- package/dist/features/store-extensions/schemas/listing-template-form.d.ts +78 -0
- package/dist/features/store-extensions/schemas/listing-template-form.js +87 -0
- package/dist/features/store-extensions/schemas/moderation-review-form.d.ts +49 -0
- package/dist/features/store-extensions/schemas/moderation-review-form.js +101 -0
- package/dist/features/store-extensions/schemas/payout-method-form.d.ts +153 -0
- package/dist/features/store-extensions/schemas/payout-method-form.js +155 -0
- package/dist/features/store-extensions/schemas/report-create-form.d.ts +25 -0
- package/dist/features/store-extensions/schemas/report-create-form.js +79 -0
- package/dist/features/store-extensions/schemas/report-review-form.d.ts +47 -0
- package/dist/features/store-extensions/schemas/report-review-form.js +111 -0
- package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +148 -0
- package/dist/features/store-extensions/schemas/shipping-config-form.js +104 -0
- package/dist/features/store-extensions/schemas/store-category-form.d.ts +54 -0
- package/dist/features/store-extensions/schemas/store-category-form.js +73 -0
- package/dist/features/stores/schemas/index.d.ts +4 -4
- package/dist/features/support/schemas/index.d.ts +4 -4
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +350 -0
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.js +12 -2
- package/dist/next/routing/route-map.d.ts +16 -2
- package/dist/next/routing/route-map.js +9 -2
- package/dist/schemas/firestore-value.d.ts +8 -0
- package/dist/schemas/firestore-value.js +44 -0
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/registry.d.ts +734 -101
- package/dist/schemas/registry.js +64 -1
- package/dist/seed/bids-seed-data.js +30 -0
- package/dist/seed/offers-seed-data.js +212 -7
- package/dist/seed/orders-seed-data.js +336 -1
- package/dist/seed/products-auctions-seed-data.js +41 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +5 -0
- package/dist/styles.css +1 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/DataTable.js +4 -2
- package/dist/ui/columns/build-columns.d.ts +6 -1
- package/dist/ui/columns/build-columns.js +53 -0
- package/dist/ui/columns/cell-renderers.d.ts +68 -0
- package/dist/ui/columns/cell-renderers.js +111 -0
- package/dist/ui/columns/column-renderers.d.ts +6 -1
- package/dist/ui/columns/column-renderers.js +6 -1
- package/dist/ui/columns/index.d.ts +2 -1
- package/dist/ui/columns/index.js +5 -1
- package/dist/ui/components/Button.js +27 -2
- package/dist/ui/components/RecordDetailModal.d.ts +10 -1
- package/dist/ui/components/RecordDetailModal.js +2 -2
- package/dist/ui/icons/icon-registry.d.ts +65 -0
- package/dist/ui/icons/icon-registry.js +115 -0
- package/package.json +2 -1
- package/scripts/node-esm-loader.mjs +65 -0
- package/scripts/seed-cli-loader.mjs +6 -49
- package/scripts/seed-cli.mjs +1 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* 🛑 `annotate()` must be the OUTERMOST call on each field — it keys a WeakMap
|
|
4
|
+
* by schema instance and every zod wrapper returns a new one.
|
|
5
|
+
*/
|
|
6
|
+
export declare const groupedListingFormSchema: z.ZodObject<{
|
|
7
|
+
title: z.ZodString;
|
|
8
|
+
description: z.ZodOptional<z.ZodString>;
|
|
9
|
+
groupTheme: z.ZodEnum<["related", "character", "lineage", "set", "generic"]>;
|
|
10
|
+
productIds: z.ZodArray<z.ZodString, "many">;
|
|
11
|
+
minActiveMembers: z.ZodNumber;
|
|
12
|
+
coverImage: z.ZodOptional<z.ZodString>;
|
|
13
|
+
isActive: z.ZodBoolean;
|
|
14
|
+
isFeatured: z.ZodBoolean;
|
|
15
|
+
}, "strip", z.ZodTypeAny, {
|
|
16
|
+
title: string;
|
|
17
|
+
isActive: boolean;
|
|
18
|
+
isFeatured: boolean;
|
|
19
|
+
productIds: string[];
|
|
20
|
+
groupTheme: "set" | "related" | "character" | "lineage" | "generic";
|
|
21
|
+
minActiveMembers: number;
|
|
22
|
+
description?: string | undefined;
|
|
23
|
+
coverImage?: string | undefined;
|
|
24
|
+
}, {
|
|
25
|
+
title: string;
|
|
26
|
+
isActive: boolean;
|
|
27
|
+
isFeatured: boolean;
|
|
28
|
+
productIds: string[];
|
|
29
|
+
groupTheme: "set" | "related" | "character" | "lineage" | "generic";
|
|
30
|
+
minActiveMembers: number;
|
|
31
|
+
description?: string | undefined;
|
|
32
|
+
coverImage?: string | undefined;
|
|
33
|
+
}>;
|
|
34
|
+
export type GroupedListingFormValues = z.infer<typeof groupedListingFormSchema>;
|
|
35
|
+
/**
|
|
36
|
+
* Create contract. `storeId` is absent — the store route sets it from the
|
|
37
|
+
* session, so a seller cannot file a group under another store.
|
|
38
|
+
*/
|
|
39
|
+
export declare const groupedListingCreateSchema: z.ZodObject<{
|
|
40
|
+
title: z.ZodString;
|
|
41
|
+
description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
42
|
+
isActive: z.ZodBoolean;
|
|
43
|
+
isFeatured: z.ZodOptional<z.ZodBoolean>;
|
|
44
|
+
coverImage: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
45
|
+
productIds: z.ZodArray<z.ZodString, "many">;
|
|
46
|
+
groupTheme: z.ZodEnum<["related", "character", "lineage", "set", "generic"]>;
|
|
47
|
+
minActiveMembers: z.ZodOptional<z.ZodNumber>;
|
|
48
|
+
}, "strip", z.ZodTypeAny, {
|
|
49
|
+
title: string;
|
|
50
|
+
isActive: boolean;
|
|
51
|
+
productIds: string[];
|
|
52
|
+
groupTheme: "set" | "related" | "character" | "lineage" | "generic";
|
|
53
|
+
description?: string | undefined;
|
|
54
|
+
isFeatured?: boolean | undefined;
|
|
55
|
+
coverImage?: string | undefined;
|
|
56
|
+
minActiveMembers?: number | undefined;
|
|
57
|
+
}, {
|
|
58
|
+
title: string;
|
|
59
|
+
isActive: boolean;
|
|
60
|
+
productIds: string[];
|
|
61
|
+
groupTheme: "set" | "related" | "character" | "lineage" | "generic";
|
|
62
|
+
description?: string | undefined;
|
|
63
|
+
isFeatured?: boolean | undefined;
|
|
64
|
+
coverImage?: string | undefined;
|
|
65
|
+
minActiveMembers?: number | undefined;
|
|
66
|
+
}>;
|
|
67
|
+
/** Update contract — partial, `.strict()` so an unknown key is a 400. */
|
|
68
|
+
export declare const groupedListingUpdateSchema: z.ZodObject<{
|
|
69
|
+
title: z.ZodOptional<z.ZodString>;
|
|
70
|
+
description: z.ZodOptional<z.ZodString>;
|
|
71
|
+
groupTheme: z.ZodOptional<z.ZodEnum<["related", "character", "lineage", "set", "generic"]>>;
|
|
72
|
+
productIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
73
|
+
minActiveMembers: z.ZodOptional<z.ZodNumber>;
|
|
74
|
+
coverImage: z.ZodOptional<z.ZodString>;
|
|
75
|
+
isActive: z.ZodOptional<z.ZodBoolean>;
|
|
76
|
+
isFeatured: z.ZodOptional<z.ZodBoolean>;
|
|
77
|
+
brandSlug: z.ZodOptional<z.ZodString>;
|
|
78
|
+
categorySlug: z.ZodOptional<z.ZodString>;
|
|
79
|
+
}, "strict", z.ZodTypeAny, {
|
|
80
|
+
title?: string | undefined;
|
|
81
|
+
categorySlug?: string | undefined;
|
|
82
|
+
brandSlug?: string | undefined;
|
|
83
|
+
description?: string | undefined;
|
|
84
|
+
isActive?: boolean | undefined;
|
|
85
|
+
isFeatured?: boolean | undefined;
|
|
86
|
+
coverImage?: string | undefined;
|
|
87
|
+
productIds?: string[] | undefined;
|
|
88
|
+
groupTheme?: "set" | "related" | "character" | "lineage" | "generic" | undefined;
|
|
89
|
+
minActiveMembers?: number | undefined;
|
|
90
|
+
}, {
|
|
91
|
+
title?: string | undefined;
|
|
92
|
+
categorySlug?: string | undefined;
|
|
93
|
+
brandSlug?: string | undefined;
|
|
94
|
+
description?: string | undefined;
|
|
95
|
+
isActive?: boolean | undefined;
|
|
96
|
+
isFeatured?: boolean | undefined;
|
|
97
|
+
coverImage?: string | undefined;
|
|
98
|
+
productIds?: string[] | undefined;
|
|
99
|
+
groupTheme?: "set" | "related" | "character" | "lineage" | "generic" | undefined;
|
|
100
|
+
minActiveMembers?: number | undefined;
|
|
101
|
+
}>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: `POST /api/store/grouped-listings` spread the raw request body into
|
|
3
|
+
* `.create()` and its PATCH built `{...body}` — no Zod on either. The two
|
|
4
|
+
* pages behind them validated one field between them (`new` checked
|
|
5
|
+
* `title` was non-empty and toasted; `[id]/edit` checked nothing at all).
|
|
6
|
+
* WHAT: One schema for the pages AND the store routes.
|
|
7
|
+
*
|
|
8
|
+
* ## `activeMemberCount` is NOT in this schema
|
|
9
|
+
*
|
|
10
|
+
* It is derived — both routes already recompute it from `productIds.length`,
|
|
11
|
+
* which is correct and was verified rather than assumed. Accepting it from the
|
|
12
|
+
* body would let a caller set a count that disagrees with the array, and the
|
|
13
|
+
* count is what the public visibility check reads.
|
|
14
|
+
*
|
|
15
|
+
* `slug`, `visibilityStatus` and `createdBy` are absent for the same reason:
|
|
16
|
+
* derived or session-owned, never typed.
|
|
17
|
+
*
|
|
18
|
+
* EXPORTS:
|
|
19
|
+
* groupedListingFormSchema, groupedListingCreateSchema,
|
|
20
|
+
* groupedListingUpdateSchema, type GroupedListingFormValues
|
|
21
|
+
*
|
|
22
|
+
* @tag domain:grouped
|
|
23
|
+
* @tag layer:schema
|
|
24
|
+
* @tag pattern:none
|
|
25
|
+
* @tag access:isomorphic
|
|
26
|
+
* @tag consumers:store/grouped-listings pages,/api/store/grouped-listings
|
|
27
|
+
* @tag sideEffects:none
|
|
28
|
+
*/
|
|
29
|
+
import { z } from "zod";
|
|
30
|
+
import { annotate } from "../../shell/field-ui-meta";
|
|
31
|
+
/** Mirrors `GroupTheme` in ./firestore. */
|
|
32
|
+
const groupThemeSchema = z.enum(["related", "character", "lineage", "set", "generic"]);
|
|
33
|
+
/**
|
|
34
|
+
* 🛑 `annotate()` must be the OUTERMOST call on each field — it keys a WeakMap
|
|
35
|
+
* by schema instance and every zod wrapper returns a new one.
|
|
36
|
+
*/
|
|
37
|
+
export const groupedListingFormSchema = z.object({
|
|
38
|
+
title: annotate(z.string().min(1, "Title is required").max(120, "Keep the title under 120 characters."), {
|
|
39
|
+
section: "basics", sectionLabel: "Group", sectionRequired: true,
|
|
40
|
+
quick: true, order: 1, row: "full",
|
|
41
|
+
}),
|
|
42
|
+
description: annotate(z.string().max(500, "Keep the description under 500 characters.").optional(), {
|
|
43
|
+
section: "basics", order: 2, row: "full",
|
|
44
|
+
}),
|
|
45
|
+
groupTheme: annotate(groupThemeSchema, {
|
|
46
|
+
section: "basics", quick: true, order: 3, row: "pair",
|
|
47
|
+
}),
|
|
48
|
+
productIds: annotate(z.array(z.string()), {
|
|
49
|
+
section: "members", sectionLabel: "Members", order: 1, row: "full", kind: "list",
|
|
50
|
+
}),
|
|
51
|
+
minActiveMembers: annotate(z.coerce.number().int("Must be a whole number.").min(1, "A group needs at least one member to show."), {
|
|
52
|
+
section: "members", order: 2, row: "pair",
|
|
53
|
+
help: "Below this many in-stock members, the group hides itself.",
|
|
54
|
+
}),
|
|
55
|
+
coverImage: annotate(z.string().optional(), {
|
|
56
|
+
section: "media", sectionLabel: "Media", order: 1, row: "full", kind: "media",
|
|
57
|
+
}),
|
|
58
|
+
isActive: annotate(z.boolean(), {
|
|
59
|
+
section: "visibility", sectionLabel: "Visibility", order: 1, row: "quarter",
|
|
60
|
+
}),
|
|
61
|
+
isFeatured: annotate(z.boolean(), {
|
|
62
|
+
section: "visibility", order: 2, row: "quarter",
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
65
|
+
/**
|
|
66
|
+
* Create contract. `storeId` is absent — the store route sets it from the
|
|
67
|
+
* session, so a seller cannot file a group under another store.
|
|
68
|
+
*/
|
|
69
|
+
export const groupedListingCreateSchema = groupedListingFormSchema.partial({
|
|
70
|
+
description: true,
|
|
71
|
+
coverImage: true,
|
|
72
|
+
isFeatured: true,
|
|
73
|
+
minActiveMembers: true,
|
|
74
|
+
});
|
|
75
|
+
/** Update contract — partial, `.strict()` so an unknown key is a 400. */
|
|
76
|
+
export const groupedListingUpdateSchema = z
|
|
77
|
+
.object({
|
|
78
|
+
title: z.string().min(1).max(120).optional(),
|
|
79
|
+
description: z.string().max(500).optional(),
|
|
80
|
+
groupTheme: groupThemeSchema.optional(),
|
|
81
|
+
productIds: z.array(z.string()).optional(),
|
|
82
|
+
minActiveMembers: z.coerce.number().int().min(1).optional(),
|
|
83
|
+
coverImage: z.string().optional(),
|
|
84
|
+
isActive: z.boolean().optional(),
|
|
85
|
+
isFeatured: z.boolean().optional(),
|
|
86
|
+
brandSlug: z.string().optional(),
|
|
87
|
+
categorySlug: z.string().optional(),
|
|
88
|
+
})
|
|
89
|
+
.strict();
|
|
@@ -43,8 +43,8 @@ export declare const groupedListingFirestoreSchema: z.ZodObject<{
|
|
|
43
43
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
44
44
|
}, z.ZodTypeAny, "passthrough">;
|
|
45
45
|
slug: string;
|
|
46
|
-
isActive: boolean;
|
|
47
46
|
createdBy: string;
|
|
47
|
+
isActive: boolean;
|
|
48
48
|
isFeatured: boolean;
|
|
49
49
|
productIds: string[];
|
|
50
50
|
groupTheme: "set" | "related" | "character" | "lineage" | "generic";
|
|
@@ -52,9 +52,9 @@ export declare const groupedListingFirestoreSchema: z.ZodObject<{
|
|
|
52
52
|
minActiveMembers: number;
|
|
53
53
|
activeMemberCount: number;
|
|
54
54
|
storeId?: string | undefined;
|
|
55
|
-
description?: string | undefined;
|
|
56
55
|
categorySlug?: string | undefined;
|
|
57
56
|
brandSlug?: string | undefined;
|
|
57
|
+
description?: string | undefined;
|
|
58
58
|
coverImage?: string | undefined;
|
|
59
59
|
}, {
|
|
60
60
|
id: string;
|
|
@@ -66,8 +66,8 @@ export declare const groupedListingFirestoreSchema: z.ZodObject<{
|
|
|
66
66
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
67
67
|
}, z.ZodTypeAny, "passthrough">;
|
|
68
68
|
slug: string;
|
|
69
|
-
isActive: boolean;
|
|
70
69
|
createdBy: string;
|
|
70
|
+
isActive: boolean;
|
|
71
71
|
isFeatured: boolean;
|
|
72
72
|
productIds: string[];
|
|
73
73
|
groupTheme: "set" | "related" | "character" | "lineage" | "generic";
|
|
@@ -75,9 +75,9 @@ export declare const groupedListingFirestoreSchema: z.ZodObject<{
|
|
|
75
75
|
minActiveMembers: number;
|
|
76
76
|
activeMemberCount: number;
|
|
77
77
|
storeId?: string | undefined;
|
|
78
|
-
description?: string | undefined;
|
|
79
78
|
categorySlug?: string | undefined;
|
|
80
79
|
brandSlug?: string | undefined;
|
|
80
|
+
description?: string | undefined;
|
|
81
81
|
coverImage?: string | undefined;
|
|
82
82
|
}>;
|
|
83
83
|
export type GroupedListingFromSchema = z.infer<typeof groupedListingFirestoreSchema>;
|
|
@@ -2,21 +2,29 @@ import { z } from "zod";
|
|
|
2
2
|
import type { HomepageSectionDocument } from "../schemas";
|
|
3
3
|
import type { FirebaseSieveResult } from "../../../providers/db-firebase";
|
|
4
4
|
export declare const createSectionSchema: z.ZodObject<{
|
|
5
|
-
type: z.
|
|
5
|
+
type: z.ZodEnum<["welcome", "carousel", "stats", "trust-indicators", "categories", "brands", "products", "pre-orders", "auctions", "banner", "features", "reviews", "whatsapp-community", "faq", "blog-articles", "newsletter", "stores", "events", "social-feed", "custom-cards", "google-reviews", "featured-bundles", "prize-draws", "event-raffles", "collection-cards"]>;
|
|
6
6
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
7
7
|
order: z.ZodDefault<z.ZodNumber>;
|
|
8
8
|
config: z.ZodOptional<z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>>;
|
|
9
9
|
}, "strip", z.ZodTypeAny, {
|
|
10
|
-
type:
|
|
10
|
+
type: "banner" | "stores" | "products" | "pre-orders" | "prize-draws" | "auctions" | "reviews" | "events" | "categories" | "brands" | "carousel" | "newsletter" | "features" | "stats" | "welcome" | "trust-indicators" | "whatsapp-community" | "faq" | "blog-articles" | "social-feed" | "custom-cards" | "google-reviews" | "featured-bundles" | "event-raffles" | "collection-cards";
|
|
11
11
|
enabled: boolean;
|
|
12
12
|
order: number;
|
|
13
13
|
config?: z.objectOutputType<{}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
14
14
|
}, {
|
|
15
|
-
type:
|
|
15
|
+
type: "banner" | "stores" | "products" | "pre-orders" | "prize-draws" | "auctions" | "reviews" | "events" | "categories" | "brands" | "carousel" | "newsletter" | "features" | "stats" | "welcome" | "trust-indicators" | "whatsapp-community" | "faq" | "blog-articles" | "social-feed" | "custom-cards" | "google-reviews" | "featured-bundles" | "event-raffles" | "collection-cards";
|
|
16
16
|
enabled?: boolean | undefined;
|
|
17
17
|
order?: number | undefined;
|
|
18
18
|
config?: z.objectInputType<{}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
19
19
|
}>;
|
|
20
|
+
/**
|
|
21
|
+
* The next free `order` value.
|
|
22
|
+
*
|
|
23
|
+
* `HomepageSectionCreateInput.order` is REQUIRED, and both API create routes
|
|
24
|
+
* need the same answer for "the caller did not choose one". Two copies of this
|
|
25
|
+
* query is how they would come to disagree about where a new section lands.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolveNextSectionOrder(): Promise<number>;
|
|
20
28
|
export declare const updateSectionSchema: z.ZodObject<{
|
|
21
29
|
order: z.ZodOptional<z.ZodNumber>;
|
|
22
30
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -1,13 +1,45 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { serverLogger } from "../../../monitoring";
|
|
3
|
+
import { sortBy } from "../../../constants/sort";
|
|
4
|
+
import { HOMEPAGE_SECTION_FIELDS } from "../../../constants/field-names";
|
|
3
5
|
import { homepageSectionsRepository } from "../repository/homepage-sections.repository";
|
|
6
|
+
import { homepageSectionTypeSchema } from "../schemas";
|
|
4
7
|
// --- Schemas --------------------------------------------------------------
|
|
8
|
+
/*
|
|
9
|
+
* 🛑 `type` was `z.string().min(1)` — ANY non-empty string.
|
|
10
|
+
*
|
|
11
|
+
* This is the third of three create paths for `homepageSections`
|
|
12
|
+
* (`POST /api/admin/sections`, `POST /api/homepage-sections`, and this server
|
|
13
|
+
* action via `createHomepageSectionAction`), and it was the loosest: a caller
|
|
14
|
+
* could store a section whose `type` matches no renderer, which the homepage
|
|
15
|
+
* then skips in silence — a row that exists, occupies an order slot, and draws
|
|
16
|
+
* nothing.
|
|
17
|
+
*
|
|
18
|
+
* All three now agree on `homepageSectionTypeSchema`, which is derived from
|
|
19
|
+
* the `SectionType` union.
|
|
20
|
+
*/
|
|
5
21
|
export const createSectionSchema = z.object({
|
|
6
|
-
type:
|
|
22
|
+
type: homepageSectionTypeSchema,
|
|
7
23
|
enabled: z.boolean().default(true),
|
|
8
24
|
order: z.number().int().default(0),
|
|
9
25
|
config: z.object({}).passthrough().optional(),
|
|
10
26
|
});
|
|
27
|
+
/**
|
|
28
|
+
* The next free `order` value.
|
|
29
|
+
*
|
|
30
|
+
* `HomepageSectionCreateInput.order` is REQUIRED, and both API create routes
|
|
31
|
+
* need the same answer for "the caller did not choose one". Two copies of this
|
|
32
|
+
* query is how they would come to disagree about where a new section lands.
|
|
33
|
+
*/
|
|
34
|
+
export async function resolveNextSectionOrder() {
|
|
35
|
+
const latest = await homepageSectionsRepository.list({
|
|
36
|
+
sorts: sortBy(HOMEPAGE_SECTION_FIELDS.ORDER),
|
|
37
|
+
page: "1",
|
|
38
|
+
pageSize: "1",
|
|
39
|
+
});
|
|
40
|
+
const top = latest.items[0]?.order;
|
|
41
|
+
return typeof top === "number" ? top + 1 : 1;
|
|
42
|
+
}
|
|
11
43
|
export const updateSectionSchema = z.object({
|
|
12
44
|
order: z.number().int().optional(),
|
|
13
45
|
enabled: z.boolean().optional(),
|
|
@@ -47,6 +47,37 @@ export declare const homepageSectionFirestoreSchema: z.ZodObject<{
|
|
|
47
47
|
order: number;
|
|
48
48
|
config: Record<string, JsonValue>;
|
|
49
49
|
}>;
|
|
50
|
+
/**
|
|
51
|
+
* The create contract for a homepage section, shared by BOTH routes that can
|
|
52
|
+
* create one — `POST /api/admin/sections` (what the editor calls) and
|
|
53
|
+
* `POST /api/homepage-sections` (reachable by URL only).
|
|
54
|
+
*
|
|
55
|
+
* It exists because those two had drifted into being one validated path and
|
|
56
|
+
* one raw `{...body}` spread, and because the validated one's hand-written
|
|
57
|
+
* type list had fallen four values behind `SectionType` — so an admin could
|
|
58
|
+
* configure a Featured Bundles / Prize Draws / Event Raffles / Collection
|
|
59
|
+
* Cards section in full and get a 400 on save.
|
|
60
|
+
*
|
|
61
|
+
* `type` comes from `homepageSectionTypeSchema`, which is derived from the
|
|
62
|
+
* union, so that gap cannot reopen.
|
|
63
|
+
*/
|
|
64
|
+
export declare const homepageSectionCreateSchema: z.ZodObject<{
|
|
65
|
+
type: z.ZodEnum<["welcome", "carousel", "stats", "trust-indicators", "categories", "brands", "products", "pre-orders", "auctions", "banner", "features", "reviews", "whatsapp-community", "faq", "blog-articles", "newsletter", "stores", "events", "social-feed", "custom-cards", "google-reviews", "featured-bundles", "prize-draws", "event-raffles", "collection-cards"]>;
|
|
66
|
+
enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
67
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
68
|
+
config: z.ZodRecord<z.ZodString, z.ZodType<JsonValue, z.ZodTypeDef, JsonValue>>;
|
|
69
|
+
}, "strip", z.ZodTypeAny, {
|
|
70
|
+
type: "banner" | "stores" | "products" | "pre-orders" | "prize-draws" | "auctions" | "reviews" | "events" | "categories" | "brands" | "carousel" | "newsletter" | "features" | "stats" | "welcome" | "trust-indicators" | "whatsapp-community" | "faq" | "blog-articles" | "social-feed" | "custom-cards" | "google-reviews" | "featured-bundles" | "event-raffles" | "collection-cards";
|
|
71
|
+
enabled: boolean;
|
|
72
|
+
config: Record<string, JsonValue>;
|
|
73
|
+
order?: number | undefined;
|
|
74
|
+
}, {
|
|
75
|
+
type: "banner" | "stores" | "products" | "pre-orders" | "prize-draws" | "auctions" | "reviews" | "events" | "categories" | "brands" | "carousel" | "newsletter" | "features" | "stats" | "welcome" | "trust-indicators" | "whatsapp-community" | "faq" | "blog-articles" | "social-feed" | "custom-cards" | "google-reviews" | "featured-bundles" | "event-raffles" | "collection-cards";
|
|
76
|
+
config: Record<string, JsonValue>;
|
|
77
|
+
enabled?: boolean | undefined;
|
|
78
|
+
order?: number | undefined;
|
|
79
|
+
}>;
|
|
80
|
+
export type HomepageSectionCreateValues = z.infer<typeof homepageSectionCreateSchema>;
|
|
50
81
|
export declare const carouselBackgroundSchema: z.ZodObject<{
|
|
51
82
|
type: z.ZodEnum<["image", "video", "color", "gradient"]>;
|
|
52
83
|
url: z.ZodOptional<z.ZodString>;
|
|
@@ -660,8 +691,8 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
|
|
|
660
691
|
id?: string | undefined;
|
|
661
692
|
} | undefined;
|
|
662
693
|
enabled?: boolean | undefined;
|
|
663
|
-
opacity?: number | undefined;
|
|
664
694
|
description?: string | undefined;
|
|
695
|
+
opacity?: number | undefined;
|
|
665
696
|
subtitle?: string | undefined;
|
|
666
697
|
}, {
|
|
667
698
|
color?: string | undefined;
|
|
@@ -674,8 +705,8 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
|
|
|
674
705
|
id?: string | undefined;
|
|
675
706
|
} | undefined;
|
|
676
707
|
enabled?: boolean | undefined;
|
|
677
|
-
opacity?: number | undefined;
|
|
678
708
|
description?: string | undefined;
|
|
709
|
+
opacity?: number | undefined;
|
|
679
710
|
subtitle?: string | undefined;
|
|
680
711
|
}>>;
|
|
681
712
|
settings: z.ZodOptional<z.ZodObject<{
|
|
@@ -718,9 +749,8 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
|
|
|
718
749
|
updatedAt: string | Date | z.objectOutputType<{
|
|
719
750
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
720
751
|
}, z.ZodTypeAny, "passthrough">;
|
|
721
|
-
active: boolean;
|
|
722
|
-
order: number;
|
|
723
752
|
createdBy: string;
|
|
753
|
+
active: boolean;
|
|
724
754
|
cards: {
|
|
725
755
|
id: string;
|
|
726
756
|
background: {
|
|
@@ -763,10 +793,22 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
|
|
|
763
793
|
isButtonOnly?: boolean | undefined;
|
|
764
794
|
gridCol?: 3 | 1 | 2 | undefined;
|
|
765
795
|
}[];
|
|
796
|
+
order: number;
|
|
766
797
|
link?: {
|
|
767
798
|
url: string;
|
|
768
799
|
openInNewTab: boolean;
|
|
769
800
|
} | undefined;
|
|
801
|
+
media?: {
|
|
802
|
+
type: "video" | "image";
|
|
803
|
+
url: string;
|
|
804
|
+
alt?: string | undefined;
|
|
805
|
+
thumbnail?: string | undefined;
|
|
806
|
+
} | undefined;
|
|
807
|
+
mobileMedia?: {
|
|
808
|
+
type: "video" | "image";
|
|
809
|
+
url: string;
|
|
810
|
+
alt?: string | undefined;
|
|
811
|
+
} | undefined;
|
|
770
812
|
background?: {
|
|
771
813
|
type: "color" | "gradient" | "video" | "image";
|
|
772
814
|
color?: string | undefined;
|
|
@@ -792,32 +834,21 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
|
|
|
792
834
|
id?: string | undefined;
|
|
793
835
|
} | undefined;
|
|
794
836
|
enabled?: boolean | undefined;
|
|
795
|
-
opacity?: number | undefined;
|
|
796
837
|
description?: string | undefined;
|
|
838
|
+
opacity?: number | undefined;
|
|
797
839
|
subtitle?: string | undefined;
|
|
798
840
|
} | undefined;
|
|
799
|
-
media?: {
|
|
800
|
-
type: "video" | "image";
|
|
801
|
-
url: string;
|
|
802
|
-
alt?: string | undefined;
|
|
803
|
-
thumbnail?: string | undefined;
|
|
804
|
-
} | undefined;
|
|
805
|
-
mobileMedia?: {
|
|
806
|
-
type: "video" | "image";
|
|
807
|
-
url: string;
|
|
808
|
-
alt?: string | undefined;
|
|
809
|
-
} | undefined;
|
|
810
|
-
settings?: {
|
|
811
|
-
height?: "medium" | "viewport" | "tall" | undefined;
|
|
812
|
-
autoplayDelayMs?: number | undefined;
|
|
813
|
-
} | undefined;
|
|
814
|
-
carouselId?: string | null | undefined;
|
|
815
841
|
analytics?: {
|
|
816
842
|
views: number;
|
|
817
843
|
lastViewed?: string | Date | z.objectOutputType<{
|
|
818
844
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
819
845
|
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
820
846
|
} | undefined;
|
|
847
|
+
settings?: {
|
|
848
|
+
height?: "medium" | "viewport" | "tall" | undefined;
|
|
849
|
+
autoplayDelayMs?: number | undefined;
|
|
850
|
+
} | undefined;
|
|
851
|
+
carouselId?: string | null | undefined;
|
|
821
852
|
}, {
|
|
822
853
|
id: string;
|
|
823
854
|
title: string;
|
|
@@ -827,9 +858,8 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
|
|
|
827
858
|
updatedAt: string | Date | z.objectInputType<{
|
|
828
859
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
829
860
|
}, z.ZodTypeAny, "passthrough">;
|
|
830
|
-
active: boolean;
|
|
831
|
-
order: number;
|
|
832
861
|
createdBy: string;
|
|
862
|
+
active: boolean;
|
|
833
863
|
cards: {
|
|
834
864
|
id: string;
|
|
835
865
|
background: {
|
|
@@ -872,10 +902,22 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
|
|
|
872
902
|
isButtonOnly?: boolean | undefined;
|
|
873
903
|
gridCol?: 3 | 1 | 2 | undefined;
|
|
874
904
|
}[];
|
|
905
|
+
order: number;
|
|
875
906
|
link?: {
|
|
876
907
|
url: string;
|
|
877
908
|
openInNewTab: boolean;
|
|
878
909
|
} | undefined;
|
|
910
|
+
media?: {
|
|
911
|
+
type: "video" | "image";
|
|
912
|
+
url: string;
|
|
913
|
+
alt?: string | undefined;
|
|
914
|
+
thumbnail?: string | undefined;
|
|
915
|
+
} | undefined;
|
|
916
|
+
mobileMedia?: {
|
|
917
|
+
type: "video" | "image";
|
|
918
|
+
url: string;
|
|
919
|
+
alt?: string | undefined;
|
|
920
|
+
} | undefined;
|
|
879
921
|
background?: {
|
|
880
922
|
type: "color" | "gradient" | "video" | "image";
|
|
881
923
|
color?: string | undefined;
|
|
@@ -901,32 +943,21 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
|
|
|
901
943
|
id?: string | undefined;
|
|
902
944
|
} | undefined;
|
|
903
945
|
enabled?: boolean | undefined;
|
|
904
|
-
opacity?: number | undefined;
|
|
905
946
|
description?: string | undefined;
|
|
947
|
+
opacity?: number | undefined;
|
|
906
948
|
subtitle?: string | undefined;
|
|
907
949
|
} | undefined;
|
|
908
|
-
media?: {
|
|
909
|
-
type: "video" | "image";
|
|
910
|
-
url: string;
|
|
911
|
-
alt?: string | undefined;
|
|
912
|
-
thumbnail?: string | undefined;
|
|
913
|
-
} | undefined;
|
|
914
|
-
mobileMedia?: {
|
|
915
|
-
type: "video" | "image";
|
|
916
|
-
url: string;
|
|
917
|
-
alt?: string | undefined;
|
|
918
|
-
} | undefined;
|
|
919
|
-
settings?: {
|
|
920
|
-
height?: "medium" | "viewport" | "tall" | undefined;
|
|
921
|
-
autoplayDelayMs?: number | undefined;
|
|
922
|
-
} | undefined;
|
|
923
|
-
carouselId?: string | null | undefined;
|
|
924
950
|
analytics?: {
|
|
925
951
|
views: number;
|
|
926
952
|
lastViewed?: string | Date | z.objectInputType<{
|
|
927
953
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
928
954
|
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
929
955
|
} | undefined;
|
|
956
|
+
settings?: {
|
|
957
|
+
height?: "medium" | "viewport" | "tall" | undefined;
|
|
958
|
+
autoplayDelayMs?: number | undefined;
|
|
959
|
+
} | undefined;
|
|
960
|
+
carouselId?: string | null | undefined;
|
|
930
961
|
}>;
|
|
931
962
|
export type HomepageSectionFromSchema = z.infer<typeof homepageSectionFirestoreSchema>;
|
|
932
963
|
export type CarouselFromSchema = z.infer<typeof carouselFirestoreSchema>;
|
|
@@ -56,6 +56,30 @@ export const homepageSectionFirestoreSchema = z.object({
|
|
|
56
56
|
config: z.record(z.string(), jsonValueSchema),
|
|
57
57
|
...auditTimestampsShape,
|
|
58
58
|
});
|
|
59
|
+
/**
|
|
60
|
+
* The create contract for a homepage section, shared by BOTH routes that can
|
|
61
|
+
* create one — `POST /api/admin/sections` (what the editor calls) and
|
|
62
|
+
* `POST /api/homepage-sections` (reachable by URL only).
|
|
63
|
+
*
|
|
64
|
+
* It exists because those two had drifted into being one validated path and
|
|
65
|
+
* one raw `{...body}` spread, and because the validated one's hand-written
|
|
66
|
+
* type list had fallen four values behind `SectionType` — so an admin could
|
|
67
|
+
* configure a Featured Bundles / Prize Draws / Event Raffles / Collection
|
|
68
|
+
* Cards section in full and get a 400 on save.
|
|
69
|
+
*
|
|
70
|
+
* `type` comes from `homepageSectionTypeSchema`, which is derived from the
|
|
71
|
+
* union, so that gap cannot reopen.
|
|
72
|
+
*/
|
|
73
|
+
export const homepageSectionCreateSchema = z.object({
|
|
74
|
+
type: homepageSectionTypeSchema,
|
|
75
|
+
enabled: z.boolean().optional().default(true),
|
|
76
|
+
order: z.number().int().optional(),
|
|
77
|
+
// Deliberately open. Every section type carries a different config shape,
|
|
78
|
+
// and a closed schema here would silently STRIP the builder's output for any
|
|
79
|
+
// type it did not enumerate — the `productBaseSchema` failure, one domain
|
|
80
|
+
// over.
|
|
81
|
+
config: z.record(z.string(), jsonValueSchema),
|
|
82
|
+
});
|
|
59
83
|
export const carouselBackgroundSchema = z.object({
|
|
60
84
|
type: z.enum(["image", "video", "color", "gradient"]),
|
|
61
85
|
url: z.string().optional(),
|
|
@@ -116,8 +116,8 @@ export declare const conversationFirestoreSchema: z.ZodObject<{
|
|
|
116
116
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
117
117
|
}, z.ZodTypeAny, "passthrough">;
|
|
118
118
|
storeId: string;
|
|
119
|
-
buyerId: string;
|
|
120
119
|
storeName: string;
|
|
120
|
+
buyerId: string;
|
|
121
121
|
lastMessageAt: string | Date | z.objectOutputType<{
|
|
122
122
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
123
123
|
}, z.ZodTypeAny, "passthrough">;
|
|
@@ -149,8 +149,8 @@ export declare const conversationFirestoreSchema: z.ZodObject<{
|
|
|
149
149
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
150
150
|
}, z.ZodTypeAny, "passthrough">;
|
|
151
151
|
storeId: string;
|
|
152
|
-
buyerId: string;
|
|
153
152
|
storeName: string;
|
|
153
|
+
buyerId: string;
|
|
154
154
|
lastMessageAt: string | Date | z.objectInputType<{
|
|
155
155
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
156
156
|
}, z.ZodTypeAny, "passthrough">;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { type TimelineEntry } from "../../status-history/components/StatusTimeline";
|
|
1
2
|
export interface OrderStatusTimelineProps {
|
|
2
3
|
orderStatus: string;
|
|
4
|
+
/** Recorded history. When present it wins over the scalar-date fallback. */
|
|
5
|
+
timeline?: TimelineEntry[];
|
|
6
|
+
timelineTruncated?: number;
|
|
3
7
|
orderDate?: string;
|
|
4
8
|
shippingDate?: string;
|
|
5
9
|
deliveryDate?: string;
|
|
@@ -9,4 +13,4 @@ export interface OrderStatusTimelineProps {
|
|
|
9
13
|
trackingUrl?: string;
|
|
10
14
|
className?: string;
|
|
11
15
|
}
|
|
12
|
-
export declare function OrderStatusTimeline({ orderStatus, orderDate, shippingDate, deliveryDate, cancellationDate, trackingNumber, shippingCarrier, trackingUrl, className, }: OrderStatusTimelineProps): import("react").JSX.Element;
|
|
16
|
+
export declare function OrderStatusTimeline({ orderStatus, timeline, timelineTruncated, orderDate, shippingDate, deliveryDate, cancellationDate, trackingNumber, shippingCarrier, trackingUrl, className, }: OrderStatusTimelineProps): import("react").JSX.Element;
|