@mohasinac/appkit 2.6.0 → 2.6.2
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/DashboardLayoutClient.d.ts +38 -0
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +75 -0
- package/dist/_internal/client/features/layout/RoleGuard.d.ts +15 -0
- package/dist/_internal/client/features/layout/RoleGuard.js +25 -0
- package/dist/_internal/client/features/layout/index.d.ts +5 -0
- package/dist/_internal/client/features/layout/index.js +4 -0
- package/dist/_internal/server/features/brands/actions.d.ts +3 -3
- package/dist/_internal/server/features/brands/actions.js +72 -5
- package/dist/_internal/server/features/brands/data.d.ts +8 -8
- package/dist/_internal/server/features/brands/data.js +10 -11
- package/dist/_internal/server/features/brands/service.d.ts +2 -2
- package/dist/_internal/server/features/brands/service.js +5 -5
- package/dist/_internal/server/features/categories/og.d.ts +33 -0
- package/dist/_internal/server/features/categories/og.js +75 -0
- package/dist/_internal/server/features/checkout/actions.d.ts +24 -0
- package/dist/_internal/server/features/checkout/actions.js +442 -13
- package/dist/_internal/server/features/checkout/index.d.ts +1 -1
- package/dist/_internal/server/features/checkout/index.js +1 -1
- package/dist/_internal/server/features/checkout/prize-bundle-gates.d.ts +59 -0
- package/dist/_internal/server/features/checkout/prize-bundle-gates.js +99 -0
- package/dist/_internal/server/features/grouped/data.js +12 -5
- package/dist/_internal/server/features/homepage/data.d.ts +1 -1
- package/dist/_internal/server/features/homepage/data.js +2 -2
- package/dist/_internal/server/features/media/contextGuards.d.ts +52 -0
- package/dist/_internal/server/features/media/contextGuards.js +198 -0
- package/dist/_internal/server/features/orders/adapters.js +12 -0
- package/dist/_internal/server/features/products/data.d.ts +1 -1
- package/dist/_internal/server/features/sublisting-categories/data.d.ts +1 -1
- package/dist/_internal/server/features/sublisting-categories/data.js +2 -2
- package/dist/_internal/server/jobs/handlers/assignSpinPrize.d.ts +24 -0
- package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +86 -0
- package/dist/_internal/server/jobs/handlers/bundleStockSync.d.ts +18 -0
- package/dist/_internal/server/jobs/handlers/bundleStockSync.js +80 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +8 -0
- package/dist/_internal/server/jobs/handlers/index.js +13 -0
- package/dist/_internal/server/jobs/handlers/listingProcessor.js +13 -3
- package/dist/_internal/server/jobs/handlers/onProductStockChange.d.ts +17 -0
- package/dist/_internal/server/jobs/handlers/onProductStockChange.js +136 -0
- package/dist/_internal/server/jobs/handlers/onProductWrite.js +17 -1
- package/dist/_internal/server/jobs/handlers/prizeRevealClose.d.ts +9 -0
- package/dist/_internal/server/jobs/handlers/prizeRevealClose.js +29 -0
- package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.d.ts +10 -0
- package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.js +58 -0
- package/dist/_internal/server/jobs/handlers/prizeRevealOpen.d.ts +10 -0
- package/dist/_internal/server/jobs/handlers/prizeRevealOpen.js +65 -0
- package/dist/_internal/server/jobs/handlers/prizeRevealReminder.d.ts +9 -0
- package/dist/_internal/server/jobs/handlers/prizeRevealReminder.js +45 -0
- package/dist/_internal/server/jobs/handlers/triggerEventRaffle.d.ts +30 -0
- package/dist/_internal/server/jobs/handlers/triggerEventRaffle.js +94 -0
- package/dist/_internal/shared/features/brands/schema.d.ts +3 -3
- package/dist/_internal/shared/features/cart/schema.d.ts +8 -8
- package/dist/_internal/shared/features/cart/schema.js +1 -1
- package/dist/_internal/shared/features/categories/bundle-config.d.ts +17 -0
- package/dist/_internal/shared/features/categories/bundle-config.js +17 -0
- package/dist/_internal/shared/features/layout/config.d.ts +35 -0
- package/dist/_internal/shared/features/layout/config.js +58 -0
- package/dist/_internal/shared/features/layout/index.d.ts +3 -0
- package/dist/_internal/shared/features/layout/index.js +2 -0
- package/dist/_internal/shared/features/layout/types.d.ts +137 -0
- package/dist/_internal/shared/features/layout/types.js +13 -0
- package/dist/_internal/shared/features/products/types.d.ts +1 -1
- package/dist/_internal/shared/listing-types/_registry.d.ts +57 -0
- package/dist/_internal/shared/listing-types/_registry.js +28 -0
- package/dist/_internal/shared/listing-types/auction/config.d.ts +7 -0
- package/dist/_internal/shared/listing-types/auction/config.js +8 -0
- package/dist/_internal/shared/listing-types/auction/ctas.d.ts +1 -0
- package/dist/_internal/shared/listing-types/auction/ctas.js +2 -0
- package/dist/_internal/shared/listing-types/auction/og.d.ts +1 -0
- package/dist/_internal/shared/listing-types/auction/og.js +1 -0
- package/dist/_internal/shared/listing-types/auction/schema.d.ts +1 -0
- package/dist/_internal/shared/listing-types/auction/schema.js +1 -0
- package/dist/_internal/shared/listing-types/auction/seed-factory.d.ts +1 -0
- package/dist/_internal/shared/listing-types/auction/seed-factory.js +1 -0
- package/dist/_internal/shared/listing-types/capabilities.d.ts +41 -0
- package/dist/_internal/shared/listing-types/capabilities.js +75 -0
- package/dist/_internal/shared/listing-types/pre-order/config.d.ts +7 -0
- package/dist/_internal/shared/listing-types/pre-order/config.js +8 -0
- package/dist/_internal/shared/listing-types/pre-order/ctas.d.ts +1 -0
- package/dist/_internal/shared/listing-types/pre-order/ctas.js +2 -0
- package/dist/_internal/shared/listing-types/pre-order/og.d.ts +1 -0
- package/dist/_internal/shared/listing-types/pre-order/og.js +1 -0
- package/dist/_internal/shared/listing-types/pre-order/schema.d.ts +1 -0
- package/dist/_internal/shared/listing-types/pre-order/schema.js +1 -0
- package/dist/_internal/shared/listing-types/pre-order/seed-factory.d.ts +1 -0
- package/dist/_internal/shared/listing-types/pre-order/seed-factory.js +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +7 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.js +8 -0
- package/dist/_internal/shared/listing-types/prize-draw/ctas.d.ts +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/ctas.js +2 -0
- package/dist/_internal/shared/listing-types/prize-draw/og.d.ts +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/og.js +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/schema.d.ts +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/schema.js +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/seed-factory.d.ts +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/seed-factory.js +1 -0
- package/dist/_internal/shared/listing-types/standard/config.d.ts +7 -0
- package/dist/_internal/shared/listing-types/standard/config.js +8 -0
- package/dist/_internal/shared/listing-types/standard/ctas.d.ts +1 -0
- package/dist/_internal/shared/listing-types/standard/ctas.js +3 -0
- package/dist/_internal/shared/listing-types/standard/og.d.ts +1 -0
- package/dist/_internal/shared/listing-types/standard/og.js +1 -0
- package/dist/_internal/shared/listing-types/standard/schema.d.ts +1 -0
- package/dist/_internal/shared/listing-types/standard/schema.js +1 -0
- package/dist/_internal/shared/listing-types/standard/seed-factory.d.ts +1 -0
- package/dist/_internal/shared/listing-types/standard/seed-factory.js +1 -0
- package/dist/_internal/shared/media/limits.d.ts +33 -0
- package/dist/_internal/shared/media/limits.js +97 -0
- package/dist/_internal/shared/schema-versions.d.ts +76 -0
- package/dist/_internal/shared/schema-versions.js +82 -0
- package/dist/client.d.ts +9 -0
- package/dist/client.js +7 -0
- package/dist/constants/api-endpoints.d.ts +6 -3
- package/dist/constants/api-endpoints.js +2 -1
- package/dist/errors/messages.d.ts +1 -1
- package/dist/errors/messages.js +1 -1
- package/dist/features/account/migrations.d.ts +2 -0
- package/dist/features/account/migrations.js +10 -0
- package/dist/features/admin/components/AdminMediaView.js +1 -1
- package/dist/features/admin/components/AdminProductsView.js +7 -3
- package/dist/features/admin/migrations.d.ts +2 -0
- package/dist/features/admin/migrations.js +10 -0
- package/dist/features/admin/types/product.types.d.ts +1 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +1 -1
- package/dist/features/auctions/migrations.d.ts +2 -0
- package/dist/features/auctions/migrations.js +10 -0
- package/dist/features/auctions/schemas/index.d.ts +3 -3
- package/dist/features/auctions/schemas/index.js +1 -1
- package/dist/features/auth/migrations.d.ts +2 -0
- package/dist/features/auth/migrations.js +10 -0
- package/dist/features/blog/migrations.d.ts +2 -0
- package/dist/features/blog/migrations.js +10 -0
- package/dist/features/brands/migrations.d.ts +2 -0
- package/dist/features/brands/migrations.js +10 -0
- package/dist/features/bundles/components/BundlesByCategoryListing.d.ts +6 -0
- package/dist/features/bundles/components/BundlesByCategoryListing.js +50 -0
- package/dist/features/bundles/components/index.d.ts +2 -0
- package/dist/features/bundles/components/index.js +1 -0
- package/dist/features/bundles/migrations.d.ts +2 -0
- package/dist/features/bundles/migrations.js +10 -0
- package/dist/features/bundles/schemas/index.d.ts +1 -0
- package/dist/features/bundles/schemas/index.js +1 -0
- package/dist/features/bundles/schemas/zod.d.ts +377 -0
- package/dist/features/bundles/schemas/zod.js +71 -0
- package/dist/features/cart/migrations.d.ts +2 -0
- package/dist/features/cart/migrations.js +10 -0
- package/dist/features/cart/schemas/firestore.d.ts +2 -2
- package/dist/features/categories/components/BrandDetailPageView.js +35 -4
- package/dist/features/categories/components/BrandDetailTabs.d.ts +5 -1
- package/dist/features/categories/components/BrandDetailTabs.js +22 -8
- package/dist/features/categories/components/CategoryBundlesListing.d.ts +6 -0
- package/dist/features/categories/components/CategoryBundlesListing.js +74 -0
- package/dist/features/categories/components/CategoryDetailPageView.js +29 -4
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +5 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +22 -8
- package/dist/features/categories/migrations.d.ts +2 -0
- package/dist/features/categories/migrations.js +10 -0
- package/dist/features/categories/repository/categories.repository.d.ts +29 -0
- package/dist/features/categories/repository/categories.repository.js +83 -0
- package/dist/features/categories/schemas/firestore.d.ts +59 -2
- package/dist/features/categories/schemas/firestore.js +6 -0
- package/dist/features/categories/types/index.d.ts +11 -3
- package/dist/features/events/migrations.d.ts +2 -0
- package/dist/features/events/migrations.js +10 -0
- package/dist/features/faq/migrations.d.ts +2 -0
- package/dist/features/faq/migrations.js +10 -0
- package/dist/features/grouped/migrations.d.ts +2 -0
- package/dist/features/grouped/migrations.js +10 -0
- package/dist/features/grouped/schemas/firestore.d.ts +29 -10
- package/dist/features/grouped/schemas/firestore.js +10 -5
- package/dist/features/history/migrations.d.ts +2 -0
- package/dist/features/history/migrations.js +10 -0
- package/dist/features/homepage/hooks/useFeaturedAuctions.js +2 -2
- package/dist/features/homepage/hooks/useFeaturedPreOrders.js +2 -2
- package/dist/features/homepage/lib/section-renderer.js +5 -3
- package/dist/features/media/AvatarUpload.js +6 -28
- package/dist/features/media/hooks/useMedia.d.ts +31 -15
- package/dist/features/media/hooks/useMedia.js +48 -13
- package/dist/features/media/upload/ImageUpload.js +1 -1
- package/dist/features/media/upload/MediaUploadField.js +1 -1
- package/dist/features/messages/migrations.d.ts +2 -0
- package/dist/features/messages/migrations.js +10 -0
- package/dist/features/orders/components/OrdersList.js +10 -1
- package/dist/features/orders/migrations.d.ts +2 -0
- package/dist/features/orders/migrations.js +10 -0
- package/dist/features/orders/repository/orders.repository.d.ts +16 -0
- package/dist/features/orders/repository/orders.repository.js +49 -0
- package/dist/features/orders/schemas/firestore.d.ts +8 -0
- package/dist/features/orders/types/index.d.ts +12 -0
- package/dist/features/orders/utils/order-splitter.d.ts +2 -2
- package/dist/features/orders/utils/order-splitter.js +5 -0
- package/dist/features/payments/migrations.d.ts +2 -0
- package/dist/features/payments/migrations.js +10 -0
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +4 -1
- package/dist/features/products/actions/product-actions.d.ts +1 -1
- package/dist/features/products/api/[id]/route.js +34 -0
- package/dist/features/products/api/route.js +1 -19
- package/dist/features/products/components/CompareOverlay.d.ts +1 -1
- package/dist/features/products/components/MarketplacePrizeDrawCard.d.ts +24 -0
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +102 -0
- package/dist/features/products/components/PrizeDrawCollage.d.ts +32 -0
- package/dist/features/products/components/PrizeDrawCollage.js +22 -0
- package/dist/features/products/components/PrizeDrawDetailPageView.d.ts +27 -0
- package/dist/features/products/components/PrizeDrawDetailPageView.js +118 -0
- package/dist/features/products/components/PrizeDrawEntryActions.d.ts +19 -0
- package/dist/features/products/components/PrizeDrawEntryActions.js +48 -0
- package/dist/features/products/components/PrizeDrawItemsEditor.d.ts +13 -0
- package/dist/features/products/components/PrizeDrawItemsEditor.js +97 -0
- package/dist/features/products/components/PrizeDrawsIndexListing.d.ts +8 -0
- package/dist/features/products/components/PrizeDrawsIndexListing.js +128 -0
- package/dist/features/products/components/PrizeDrawsListingView.d.ts +15 -0
- package/dist/features/products/components/PrizeDrawsListingView.js +49 -0
- package/dist/features/products/components/PrizeRevealModal.d.ts +34 -0
- package/dist/features/products/components/PrizeRevealModal.js +124 -0
- package/dist/features/products/components/ProductDetailPageView.js +13 -1
- package/dist/features/products/components/ProductForm.js +35 -2
- package/dist/features/products/components/ProductGrid.js +3 -1
- package/dist/features/products/components/index.d.ts +16 -0
- package/dist/features/products/components/index.js +8 -0
- package/dist/features/products/constants/listing-tabs.d.ts +113 -0
- package/dist/features/products/constants/listing-tabs.js +43 -0
- package/dist/features/products/index.d.ts +1 -0
- package/dist/features/products/index.js +1 -0
- package/dist/features/products/migrations.d.ts +2 -0
- package/dist/features/products/migrations.js +10 -0
- package/dist/features/products/repository/products.repository.d.ts +11 -7
- package/dist/features/products/repository/products.repository.js +49 -24
- package/dist/features/products/schemas/firestore.d.ts +3 -3
- package/dist/features/products/schemas/firestore.js +2 -2
- package/dist/features/products/schemas/index.d.ts +5 -5
- package/dist/features/products/schemas/index.js +3 -1
- package/dist/features/products/schemas/product-features.validators.d.ts +6 -6
- package/dist/features/products/types/index.d.ts +17 -1
- package/dist/features/products/utils/listing-type.d.ts +7 -4
- package/dist/features/products/utils/listing-type.js +8 -4
- package/dist/features/promotions/actions/coupon-actions.d.ts +1 -1
- package/dist/features/promotions/hooks/useCouponValidate.d.ts +1 -1
- package/dist/features/promotions/migrations.d.ts +2 -0
- package/dist/features/promotions/migrations.js +10 -0
- package/dist/features/promotions/repository/coupons.repository.d.ts +1 -1
- package/dist/features/promotions/schemas/index.d.ts +2 -2
- package/dist/features/reviews/migrations.d.ts +2 -0
- package/dist/features/reviews/migrations.js +10 -0
- package/dist/features/scams/migrations.d.ts +2 -0
- package/dist/features/scams/migrations.js +10 -0
- package/dist/features/search/api/route.d.ts +1 -1
- package/dist/features/search/api/route.js +3 -3
- package/dist/features/search/components/Search.d.ts +1 -1
- package/dist/features/search/schemas/index.d.ts +3 -3
- package/dist/features/search/schemas/index.js +3 -1
- package/dist/features/search/types/index.d.ts +2 -2
- package/dist/features/seller/components/SellerProductShell.d.ts +1 -1
- package/dist/features/seller/components/SellerProductsView.js +20 -6
- package/dist/features/seller/migrations.d.ts +2 -0
- package/dist/features/seller/migrations.js +10 -0
- package/dist/features/seller/schemas/index.d.ts +2 -2
- package/dist/features/stores/components/StoreBundlesPageView.d.ts +12 -0
- package/dist/features/stores/components/StoreBundlesPageView.js +24 -0
- package/dist/features/stores/components/StoreDetailLayoutView.js +15 -3
- package/dist/features/stores/components/StorePrizeDrawsPageView.d.ts +11 -0
- package/dist/features/stores/components/StorePrizeDrawsPageView.js +27 -0
- package/dist/features/stores/components/index.d.ts +2 -0
- package/dist/features/stores/migrations.d.ts +2 -0
- package/dist/features/stores/migrations.js +10 -0
- package/dist/features/stores/schemas/index.d.ts +2 -2
- package/dist/features/stores/types/index.d.ts +1 -1
- package/dist/features/sublisting/migrations.d.ts +2 -0
- package/dist/features/sublisting/migrations.js +10 -0
- package/dist/features/sublisting/schemas/firestore.d.ts +2 -0
- package/dist/features/support/migrations.d.ts +2 -0
- package/dist/features/support/migrations.js +10 -0
- package/dist/features/wishlist/migrations.d.ts +2 -0
- package/dist/features/wishlist/migrations.js +10 -0
- package/dist/features/wishlist/types/index.d.ts +1 -1
- package/dist/index.d.ts +26 -18
- package/dist/index.js +41 -24
- package/dist/jobs.d.ts +1 -1
- package/dist/jobs.js +4 -0
- package/dist/next/api/routeHandler.js +6 -4
- package/dist/next/routing/route-map.d.ts +4 -0
- package/dist/next/routing/route-map.js +2 -0
- package/dist/providers/db-firebase/filter-aliases.d.ts +2 -2
- package/dist/repositories/index.d.ts +0 -5
- package/dist/repositories/index.js +5 -4
- package/dist/seed/actions/demo-seed-actions.d.ts +1 -1
- package/dist/seed/categories-seed-data.js +1105 -6
- package/dist/seed/faq-seed-data.js +160 -0
- package/dist/seed/grouped-listings-seed-data.js +32 -32
- package/dist/seed/homepage-sections-seed-data.js +52 -6
- package/dist/seed/index.d.ts +1 -3
- package/dist/seed/index.js +4 -3
- package/dist/seed/manifest.js +8 -13
- package/dist/seed/products-prize-draws-seed-data.d.ts +17 -0
- package/dist/seed/products-prize-draws-seed-data.js +313 -0
- package/dist/seo/json-ld.d.ts +1 -1
- package/dist/server-entry.d.ts +2 -2
- package/dist/server-entry.js +5 -3
- package/dist/server.d.ts +9 -2
- package/dist/server.js +11 -5
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/Button.js +21 -2
- package/dist/ui/components/Button.style.css +34 -0
- package/dist/validation/schemas.d.ts +8 -8
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +2 -4
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DashboardLayoutClient — unified client island that replaces the ~75 lines of
|
|
3
|
+
* boilerplate previously duplicated across admin/store/user layout.tsx files.
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities:
|
|
6
|
+
* - Manage desktop + mobile drawer state (matchMedia-aware).
|
|
7
|
+
* - Register handlers with `useDashboardNav()` so the public TitleBar's
|
|
8
|
+
* hamburger forwards to this dashboard sidebar.
|
|
9
|
+
* - Pick the correct sidebar component for the supplied `variant`.
|
|
10
|
+
* - Resolve `activeHref` from `usePathname()` so consumers do not have to.
|
|
11
|
+
*
|
|
12
|
+
* Consumers pass:
|
|
13
|
+
* <DashboardLayoutClient variant="admin" groups={ADMIN_NAV_GROUPS}>
|
|
14
|
+
* {children}
|
|
15
|
+
* </DashboardLayoutClient>
|
|
16
|
+
*
|
|
17
|
+
* Theming: each variant uses its accent token map from shared/features/layout/config.
|
|
18
|
+
* Responsive: sidebar is overlay on <md, persistent rail on ≥lg — controlled by
|
|
19
|
+
* the underlying *Sidebar components.
|
|
20
|
+
*/
|
|
21
|
+
import { type ReactNode } from "react";
|
|
22
|
+
import type { DashboardVariant, SidebarNavGroup, SectionResponsive } from "../../../shared/features/layout/types";
|
|
23
|
+
export interface DashboardLayoutClientProps {
|
|
24
|
+
/** Drives sidebar component selection + accent colour. */
|
|
25
|
+
variant: DashboardVariant;
|
|
26
|
+
/** Grouped nav items. Shape matches all three sidebar components. */
|
|
27
|
+
groups: SidebarNavGroup[];
|
|
28
|
+
/** Override active-link highlight. Defaults to usePathname(). */
|
|
29
|
+
activeHref?: string;
|
|
30
|
+
/** Responsive controls — currently only hideAt is honoured. */
|
|
31
|
+
responsive?: SectionResponsive;
|
|
32
|
+
/** Optional render-prop slot for additional sidebar footer content. */
|
|
33
|
+
renderSidebarFooter?: () => ReactNode;
|
|
34
|
+
/** Optional className passed through to the sidebar component. */
|
|
35
|
+
className?: string;
|
|
36
|
+
children: ReactNode;
|
|
37
|
+
}
|
|
38
|
+
export declare function DashboardLayoutClient({ variant, groups, activeHref: explicitActiveHref, responsive: _responsive, className, children, }: DashboardLayoutClientProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* DashboardLayoutClient — unified client island that replaces the ~75 lines of
|
|
5
|
+
* boilerplate previously duplicated across admin/store/user layout.tsx files.
|
|
6
|
+
*
|
|
7
|
+
* Responsibilities:
|
|
8
|
+
* - Manage desktop + mobile drawer state (matchMedia-aware).
|
|
9
|
+
* - Register handlers with `useDashboardNav()` so the public TitleBar's
|
|
10
|
+
* hamburger forwards to this dashboard sidebar.
|
|
11
|
+
* - Pick the correct sidebar component for the supplied `variant`.
|
|
12
|
+
* - Resolve `activeHref` from `usePathname()` so consumers do not have to.
|
|
13
|
+
*
|
|
14
|
+
* Consumers pass:
|
|
15
|
+
* <DashboardLayoutClient variant="admin" groups={ADMIN_NAV_GROUPS}>
|
|
16
|
+
* {children}
|
|
17
|
+
* </DashboardLayoutClient>
|
|
18
|
+
*
|
|
19
|
+
* Theming: each variant uses its accent token map from shared/features/layout/config.
|
|
20
|
+
* Responsive: sidebar is overlay on <md, persistent rail on ≥lg — controlled by
|
|
21
|
+
* the underlying *Sidebar components.
|
|
22
|
+
*/
|
|
23
|
+
import { useCallback, useEffect, useState, startTransition } from "react";
|
|
24
|
+
import { usePathname } from "next/navigation";
|
|
25
|
+
import { useDashboardNav } from "../../../../features/layout/DashboardNavContext";
|
|
26
|
+
import { AdminSidebar } from "../../../../features/admin/components/AdminSidebar";
|
|
27
|
+
import { StoreSidebar } from "../../../../features/seller/components/SellerSidebar";
|
|
28
|
+
import { UserSidebar } from "../../../../features/account/components/UserSidebar";
|
|
29
|
+
import { DASHBOARD_DESKTOP_MEDIA_QUERY } from "../../../shared/features/layout/config";
|
|
30
|
+
/**
|
|
31
|
+
* Hoisted drawer-state hook — the matchMedia-aware open/close logic that was
|
|
32
|
+
* triplicated across admin/store/user layouts. Used internally by
|
|
33
|
+
* DashboardLayoutClient; not exported because it's not generically useful.
|
|
34
|
+
*/
|
|
35
|
+
function useResponsiveDrawer() {
|
|
36
|
+
const [desktopOpen, setDesktopOpen] = useState(false);
|
|
37
|
+
const [mobileOpen, setMobileOpen] = useState(false);
|
|
38
|
+
const { registerNav, unregisterNav } = useDashboardNav();
|
|
39
|
+
const isDesktop = useCallback(() => typeof window !== "undefined" && window.matchMedia(DASHBOARD_DESKTOP_MEDIA_QUERY).matches, []);
|
|
40
|
+
const open = useCallback(() => {
|
|
41
|
+
startTransition(() => {
|
|
42
|
+
if (isDesktop())
|
|
43
|
+
setDesktopOpen(true);
|
|
44
|
+
else
|
|
45
|
+
setMobileOpen(true);
|
|
46
|
+
});
|
|
47
|
+
}, [isDesktop]);
|
|
48
|
+
const close = useCallback(() => {
|
|
49
|
+
startTransition(() => {
|
|
50
|
+
if (isDesktop())
|
|
51
|
+
setDesktopOpen(false);
|
|
52
|
+
else
|
|
53
|
+
setMobileOpen(false);
|
|
54
|
+
});
|
|
55
|
+
}, [isDesktop]);
|
|
56
|
+
const toggle = useCallback(() => {
|
|
57
|
+
startTransition(() => {
|
|
58
|
+
if (isDesktop())
|
|
59
|
+
setDesktopOpen((prev) => !prev);
|
|
60
|
+
else
|
|
61
|
+
setMobileOpen((prev) => !prev);
|
|
62
|
+
});
|
|
63
|
+
}, [isDesktop]);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
registerNav({ open, close, toggle });
|
|
66
|
+
return () => unregisterNav();
|
|
67
|
+
}, [registerNav, unregisterNav, open, close, toggle]);
|
|
68
|
+
return { desktopOpen, mobileOpen, close, toggle };
|
|
69
|
+
}
|
|
70
|
+
export function DashboardLayoutClient({ variant, groups, activeHref: explicitActiveHref, responsive: _responsive, className, children, }) {
|
|
71
|
+
const pathname = usePathname();
|
|
72
|
+
const activeHref = explicitActiveHref ?? pathname ?? "";
|
|
73
|
+
const { desktopOpen, mobileOpen, close, toggle } = useResponsiveDrawer();
|
|
74
|
+
return (_jsxs(_Fragment, { children: [variant === "admin" && (_jsx(AdminSidebar, { variant: "sidebar", desktopOpen: desktopOpen, mobileOpen: mobileOpen, activePath: activeHref, groups: groups, onCloseMobile: close, onToggle: toggle, className: className })), variant === "store" && (_jsx(StoreSidebar, { variant: "sidebar", desktopOpen: desktopOpen, mobileOpen: mobileOpen, activeHref: activeHref, items: [], groups: groups, onCloseMobile: close, onToggle: toggle, className: className })), variant === "user" && (_jsx(UserSidebar, { variant: "sidebar", desktopOpen: desktopOpen, mobileOpen: mobileOpen, items: groups.flatMap((g) => g.items), groups: groups, onCloseMobile: close, onToggle: toggle, className: className })), children] }));
|
|
75
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { LayoutRole } from "../../../shared/features/layout/types";
|
|
3
|
+
export interface RoleGuardProps {
|
|
4
|
+
/** Single role or array. Omit for auth-only (any signed-in user). */
|
|
5
|
+
role?: LayoutRole | LayoutRole[];
|
|
6
|
+
/** When true, unauthenticated users are redirected (default true). */
|
|
7
|
+
requireAuth?: boolean;
|
|
8
|
+
/** Optional route overrides (defaults come from appkit ROUTES). */
|
|
9
|
+
loginPath?: string;
|
|
10
|
+
unauthorizedPath?: string;
|
|
11
|
+
/** Render while loading the session. */
|
|
12
|
+
loadingComponent?: ReactNode;
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
export declare function RoleGuard({ role, requireAuth, loginPath, unauthorizedPath, loadingComponent, children, }: RoleGuardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* RoleGuard — preset wrapper over ProtectedRoute.
|
|
5
|
+
*
|
|
6
|
+
* Collapses the boilerplate that every dashboard layout repeats:
|
|
7
|
+
* - reading `useSession()`
|
|
8
|
+
* - resolving `onNavigate` against the i18n router
|
|
9
|
+
* - passing default `routes.loginPath` / `routes.unauthorizedPath`
|
|
10
|
+
*
|
|
11
|
+
* Consumers supply only the `role` (or none, for auth-only) plus optional
|
|
12
|
+
* route overrides. Everything else defaults to appkit's ROUTES.
|
|
13
|
+
*/
|
|
14
|
+
import { useRouter } from "next/navigation";
|
|
15
|
+
import { ProtectedRoute } from "../../../../features/auth/components/Guards";
|
|
16
|
+
import { useSession } from "../../../../react/contexts/SessionContext";
|
|
17
|
+
import { ROUTES } from "../../../../next/routing/route-map";
|
|
18
|
+
export function RoleGuard({ role, requireAuth = true, loginPath, unauthorizedPath, loadingComponent, children, }) {
|
|
19
|
+
const { user, loading } = useSession();
|
|
20
|
+
const router = useRouter();
|
|
21
|
+
return (_jsx(ProtectedRoute, { user: user, loading: loading, requireAuth: requireAuth, requireRole: role, onNavigate: (path) => router.push(path), routes: {
|
|
22
|
+
loginPath: loginPath ?? String(ROUTES.AUTH.LOGIN),
|
|
23
|
+
unauthorizedPath: unauthorizedPath ?? String(ROUTES.ERRORS.UNAUTHORIZED),
|
|
24
|
+
}, loadingComponent: loadingComponent, children: children }));
|
|
25
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Layout feature — client islands barrel. */
|
|
2
|
+
export { DashboardLayoutClient } from "./DashboardLayoutClient";
|
|
3
|
+
export type { DashboardLayoutClientProps } from "./DashboardLayoutClient";
|
|
4
|
+
export { RoleGuard } from "./RoleGuard";
|
|
5
|
+
export type { RoleGuardProps } from "./RoleGuard";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function createBrandAction(input: unknown): Promise<import("../../../..").
|
|
2
|
-
export declare function updateBrandAction(brandId: string, input: unknown): Promise<import("../../../..").
|
|
1
|
+
export declare function createBrandAction(input: unknown): Promise<import("../../../..").CategoryDocument>;
|
|
2
|
+
export declare function updateBrandAction(brandId: string, input: unknown): Promise<import("../../../..").CategoryDocument>;
|
|
3
3
|
export declare function deleteBrandAction(brandId: string): Promise<void>;
|
|
4
|
-
export declare function toggleBrandActiveAction(brandId: string, isActive: boolean): Promise<import("../../../..").
|
|
4
|
+
export declare function toggleBrandActiveAction(brandId: string, isActive: boolean): Promise<import("../../../..").CategoryDocument>;
|
|
@@ -1,16 +1,83 @@
|
|
|
1
1
|
"use server";
|
|
2
|
-
import {
|
|
2
|
+
import { categoriesRepository } from "../../../../repositories";
|
|
3
3
|
import { requireRoleUser } from "../../../../providers/auth-firebase/helpers";
|
|
4
4
|
import { brandInputSchema, brandUpdateSchema } from "../../../shared/features/brands/schema";
|
|
5
5
|
import { assertBrandExists, assertBrandSlugUnique } from "./service";
|
|
6
6
|
import { ValidationError } from "../../../shared/errors/index";
|
|
7
|
+
/**
|
|
8
|
+
* Translate the brand-input wire format (logoURL / bannerURL / website /
|
|
9
|
+
* country / founded) to the CategoryDocument storage shape after
|
|
10
|
+
* SB-UNI-C consolidated brands into the categories collection.
|
|
11
|
+
*/
|
|
12
|
+
function brandInputToCategoryFields(input) {
|
|
13
|
+
const out = {};
|
|
14
|
+
if ("name" in input && input.name !== undefined)
|
|
15
|
+
out.name = input.name;
|
|
16
|
+
if ("slug" in input && input.slug !== undefined) {
|
|
17
|
+
out.slug = input.slug;
|
|
18
|
+
out.path = input.slug;
|
|
19
|
+
}
|
|
20
|
+
if (input.description !== undefined)
|
|
21
|
+
out.description = input.description;
|
|
22
|
+
if (input.website !== undefined)
|
|
23
|
+
out.brandWebsite = input.website;
|
|
24
|
+
if (input.country !== undefined)
|
|
25
|
+
out.brandCountry = input.country;
|
|
26
|
+
if (input.founded !== undefined)
|
|
27
|
+
out.brandFounded = input.founded;
|
|
28
|
+
if (input.bannerURL !== undefined)
|
|
29
|
+
out.brandBannerImage = input.bannerURL;
|
|
30
|
+
if (input.logoURL !== undefined) {
|
|
31
|
+
out.display = { coverImage: input.logoURL, showInMenu: false, showInFooter: false };
|
|
32
|
+
}
|
|
33
|
+
if (input.isActive !== undefined)
|
|
34
|
+
out.isActive = input.isActive;
|
|
35
|
+
if (input.displayOrder !== undefined)
|
|
36
|
+
out.order = input.displayOrder;
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
7
39
|
export async function createBrandAction(input) {
|
|
8
40
|
await requireRoleUser("admin");
|
|
9
41
|
const parsed = brandInputSchema.safeParse(input);
|
|
10
42
|
if (!parsed.success)
|
|
11
43
|
throw new ValidationError(parsed.error.errors[0]?.message ?? "Invalid brand input");
|
|
12
44
|
await assertBrandSlugUnique(parsed.data.slug);
|
|
13
|
-
|
|
45
|
+
const fields = brandInputToCategoryFields(parsed.data);
|
|
46
|
+
return categoriesRepository.createWithId(parsed.data.slug, {
|
|
47
|
+
id: parsed.data.slug,
|
|
48
|
+
name: parsed.data.name,
|
|
49
|
+
slug: parsed.data.slug,
|
|
50
|
+
categoryType: "brand",
|
|
51
|
+
rootId: parsed.data.slug,
|
|
52
|
+
parentIds: [],
|
|
53
|
+
childrenIds: [],
|
|
54
|
+
tier: 0,
|
|
55
|
+
path: parsed.data.slug,
|
|
56
|
+
position: 0,
|
|
57
|
+
subtreeSize: 1,
|
|
58
|
+
order: parsed.data.displayOrder,
|
|
59
|
+
isLeaf: true,
|
|
60
|
+
isFeatured: false,
|
|
61
|
+
isBrand: true,
|
|
62
|
+
isActive: parsed.data.isActive,
|
|
63
|
+
isSearchable: true,
|
|
64
|
+
metrics: {
|
|
65
|
+
productCount: 0,
|
|
66
|
+
productIds: [],
|
|
67
|
+
auctionCount: 0,
|
|
68
|
+
auctionIds: [],
|
|
69
|
+
totalProductCount: 0,
|
|
70
|
+
totalAuctionCount: 0,
|
|
71
|
+
totalItemCount: 0,
|
|
72
|
+
lastUpdated: new Date(),
|
|
73
|
+
},
|
|
74
|
+
seo: { title: parsed.data.name, description: parsed.data.description ?? "", keywords: [parsed.data.name] },
|
|
75
|
+
ancestors: [],
|
|
76
|
+
createdBy: "admin",
|
|
77
|
+
createdAt: new Date(),
|
|
78
|
+
updatedAt: new Date(),
|
|
79
|
+
...fields,
|
|
80
|
+
});
|
|
14
81
|
}
|
|
15
82
|
export async function updateBrandAction(brandId, input) {
|
|
16
83
|
await requireRoleUser("admin");
|
|
@@ -18,15 +85,15 @@ export async function updateBrandAction(brandId, input) {
|
|
|
18
85
|
const parsed = brandUpdateSchema.safeParse(input);
|
|
19
86
|
if (!parsed.success)
|
|
20
87
|
throw new ValidationError(parsed.error.errors[0]?.message ?? "Invalid brand input");
|
|
21
|
-
return
|
|
88
|
+
return categoriesRepository.update(brandId, brandInputToCategoryFields(parsed.data));
|
|
22
89
|
}
|
|
23
90
|
export async function deleteBrandAction(brandId) {
|
|
24
91
|
await requireRoleUser("admin");
|
|
25
92
|
await assertBrandExists(brandId);
|
|
26
|
-
return
|
|
93
|
+
return categoriesRepository.delete(brandId);
|
|
27
94
|
}
|
|
28
95
|
export async function toggleBrandActiveAction(brandId, isActive) {
|
|
29
96
|
await requireRoleUser("admin");
|
|
30
97
|
await assertBrandExists(brandId);
|
|
31
|
-
return
|
|
98
|
+
return categoriesRepository.update(brandId, { isActive });
|
|
32
99
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { BrandDocument } from "../../../../features/brands/schemas";
|
|
2
1
|
import type { CategoryDocument } from "../../../../features/categories/schemas/firestore";
|
|
3
|
-
export declare const getBrandForDetail: (slug: string) => Promise<BrandDocument | null>;
|
|
4
2
|
/**
|
|
5
|
-
* Brand
|
|
6
|
-
*
|
|
7
|
-
* BrandDetailPageView
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
* Brand detail loader — SB-UNI-C moved brands into the `categories`
|
|
4
|
+
* collection with `categoryType: "brand"`. Both `generateMetadata` and
|
|
5
|
+
* `BrandDetailPageView` consume the same `CategoryDocument` shape.
|
|
6
|
+
*/
|
|
7
|
+
export declare const getBrandForDetail: (slug: string) => Promise<CategoryDocument | null>;
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated Identical to getBrandForDetail after SB-UNI-C. Kept as an
|
|
10
|
+
* alias so existing imports don't break.
|
|
11
11
|
*/
|
|
12
12
|
export declare const getBrandCategoryForDetail: (slug: string) => Promise<CategoryDocument | null>;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { cache } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { categoriesRepository } from "../../../../repositories";
|
|
3
|
+
/**
|
|
4
|
+
* Brand detail loader — SB-UNI-C moved brands into the `categories`
|
|
5
|
+
* collection with `categoryType: "brand"`. Both `generateMetadata` and
|
|
6
|
+
* `BrandDetailPageView` consume the same `CategoryDocument` shape.
|
|
7
|
+
*/
|
|
3
8
|
export const getBrandForDetail = cache(async (slug) => {
|
|
4
|
-
return
|
|
9
|
+
return categoriesRepository.findBySlugAndType(slug, "brand").catch(() => null);
|
|
5
10
|
});
|
|
6
11
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* BrandDetailPageView renders the categories-collection record (display + metrics
|
|
10
|
-
* fields), not the brands-collection record. Keep both fetchers so
|
|
11
|
-
* generateMetadata can pull BrandDocument fields (logoURL) while the view pulls
|
|
12
|
-
* CategoryDocument.
|
|
12
|
+
* @deprecated Identical to getBrandForDetail after SB-UNI-C. Kept as an
|
|
13
|
+
* alias so existing imports don't break.
|
|
13
14
|
*/
|
|
14
|
-
export const getBrandCategoryForDetail =
|
|
15
|
-
return categoriesRepository.getCategoryBySlug(slug).catch(() => null);
|
|
16
|
-
});
|
|
15
|
+
export const getBrandCategoryForDetail = getBrandForDetail;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function assertBrandExists(slugOrId: string): Promise<
|
|
1
|
+
import type { CategoryDocument } from "../../../../features/categories/schemas/firestore";
|
|
2
|
+
export declare function assertBrandExists(slugOrId: string): Promise<CategoryDocument>;
|
|
3
3
|
export declare function assertBrandSlugUnique(slug: string): Promise<void>;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { categoriesRepository } from "../../../../repositories";
|
|
2
2
|
import { BrandNotFoundError, BrandSlugConflictError } from "../../../shared/features/brands/errors";
|
|
3
3
|
export async function assertBrandExists(slugOrId) {
|
|
4
|
-
const brand = await
|
|
5
|
-
|
|
6
|
-
if (!brand)
|
|
4
|
+
const brand = (await categoriesRepository.findBySlugAndType(slugOrId, "brand").catch(() => null)) ??
|
|
5
|
+
(await categoriesRepository.findById(slugOrId).catch(() => null));
|
|
6
|
+
if (!brand || brand.categoryType !== "brand")
|
|
7
7
|
throw new BrandNotFoundError(slugOrId);
|
|
8
8
|
return brand;
|
|
9
9
|
}
|
|
10
10
|
export async function assertBrandSlugUnique(slug) {
|
|
11
|
-
const existing = await
|
|
11
|
+
const existing = await categoriesRepository.findBySlugAndType(slug, "brand").catch(() => null);
|
|
12
12
|
if (existing)
|
|
13
13
|
throw new BrandSlugConflictError(slug);
|
|
14
14
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Category OG image renderer — S6 OG1.
|
|
3
|
+
*
|
|
4
|
+
* Two layers:
|
|
5
|
+
* - `renderCategoryOg(doc, opts)` — high-level: maps a raw category doc
|
|
6
|
+
* (from `getCategoryForDetail`) into the OG data shape.
|
|
7
|
+
* - `renderCategoryOgImage(data, siteName)` — pure JSX primitive, no
|
|
8
|
+
* next/og dependency; consumer wraps with `new ImageResponse(...)`.
|
|
9
|
+
*
|
|
10
|
+
* Mirrors the brand/store OG layout so the public catalog feels uniform.
|
|
11
|
+
*/
|
|
12
|
+
import type { ReactElement } from "react";
|
|
13
|
+
export interface CategoryOgData {
|
|
14
|
+
name: string;
|
|
15
|
+
description?: string | null;
|
|
16
|
+
coverImageUrl?: string | null;
|
|
17
|
+
productCount?: number | null;
|
|
18
|
+
}
|
|
19
|
+
interface CategoryDocLike {
|
|
20
|
+
name?: string | null;
|
|
21
|
+
description?: string | null;
|
|
22
|
+
display?: {
|
|
23
|
+
coverImage?: string | null;
|
|
24
|
+
} | null;
|
|
25
|
+
metrics?: {
|
|
26
|
+
totalItemCount?: number | null;
|
|
27
|
+
} | null;
|
|
28
|
+
}
|
|
29
|
+
export declare function renderCategoryOg(doc: CategoryDocLike | null | undefined, opts: {
|
|
30
|
+
siteName: string;
|
|
31
|
+
}): ReactElement;
|
|
32
|
+
export declare function renderCategoryOgImage(data: CategoryOgData, siteName: string): ReactElement;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function renderCategoryOg(doc, opts) {
|
|
3
|
+
const name = doc?.name ?? "Category";
|
|
4
|
+
return renderCategoryOgImage({
|
|
5
|
+
name,
|
|
6
|
+
description: doc?.description?.slice(0, 140) ??
|
|
7
|
+
`Browse ${name} on ${opts.siteName}.`,
|
|
8
|
+
coverImageUrl: doc?.display?.coverImage ?? null,
|
|
9
|
+
productCount: doc?.metrics?.totalItemCount ?? null,
|
|
10
|
+
}, opts.siteName);
|
|
11
|
+
}
|
|
12
|
+
export function renderCategoryOgImage(data, siteName) {
|
|
13
|
+
const { name, description, coverImageUrl, productCount } = data;
|
|
14
|
+
const itemLabel = typeof productCount === "number" && productCount > 0
|
|
15
|
+
? `${productCount.toLocaleString("en-IN")} item${productCount === 1 ? "" : "s"}`
|
|
16
|
+
: null;
|
|
17
|
+
return (_jsxs("div", { style: {
|
|
18
|
+
display: "flex",
|
|
19
|
+
width: "100%",
|
|
20
|
+
height: "100%",
|
|
21
|
+
background: "#0f172a",
|
|
22
|
+
fontFamily: "sans-serif",
|
|
23
|
+
position: "relative",
|
|
24
|
+
overflow: "hidden",
|
|
25
|
+
}, children: [coverImageUrl && (_jsx("img", { src: coverImageUrl, alt: "", style: {
|
|
26
|
+
position: "absolute",
|
|
27
|
+
inset: 0,
|
|
28
|
+
width: "100%",
|
|
29
|
+
height: "100%",
|
|
30
|
+
objectFit: "cover",
|
|
31
|
+
opacity: 0.35,
|
|
32
|
+
} })), _jsx("div", { style: {
|
|
33
|
+
position: "absolute",
|
|
34
|
+
inset: 0,
|
|
35
|
+
background: "linear-gradient(135deg, rgba(15, 23, 42, 0.85) 0%, rgba(30, 41, 59, 0.7) 100%)",
|
|
36
|
+
} }), _jsxs("div", { style: {
|
|
37
|
+
position: "relative",
|
|
38
|
+
display: "flex",
|
|
39
|
+
flexDirection: "column",
|
|
40
|
+
gap: 24,
|
|
41
|
+
padding: "80px 72px",
|
|
42
|
+
width: "100%",
|
|
43
|
+
height: "100%",
|
|
44
|
+
justifyContent: "flex-end",
|
|
45
|
+
}, children: [_jsxs("div", { style: {
|
|
46
|
+
fontSize: 18,
|
|
47
|
+
color: "#94a3b8",
|
|
48
|
+
fontWeight: 600,
|
|
49
|
+
letterSpacing: 2,
|
|
50
|
+
textTransform: "uppercase",
|
|
51
|
+
}, children: [siteName, " \u00B7 Category"] }), _jsx("div", { style: {
|
|
52
|
+
fontSize: 76,
|
|
53
|
+
fontWeight: 800,
|
|
54
|
+
color: "#f8fafc",
|
|
55
|
+
lineHeight: 1.05,
|
|
56
|
+
letterSpacing: -1,
|
|
57
|
+
}, children: name }), description && (_jsx("div", { style: {
|
|
58
|
+
fontSize: 26,
|
|
59
|
+
color: "#cbd5e1",
|
|
60
|
+
fontWeight: 400,
|
|
61
|
+
lineHeight: 1.35,
|
|
62
|
+
maxWidth: 960,
|
|
63
|
+
}, children: description })), itemLabel && (_jsx("div", { style: {
|
|
64
|
+
display: "inline-flex",
|
|
65
|
+
alignSelf: "flex-start",
|
|
66
|
+
padding: "10px 22px",
|
|
67
|
+
borderRadius: 999,
|
|
68
|
+
background: "rgba(56, 189, 248, 0.18)",
|
|
69
|
+
color: "#e0f2fe",
|
|
70
|
+
fontSize: 22,
|
|
71
|
+
fontWeight: 600,
|
|
72
|
+
border: "1px solid rgba(56, 189, 248, 0.4)",
|
|
73
|
+
marginTop: 8,
|
|
74
|
+
}, children: itemLabel }))] })] }));
|
|
75
|
+
}
|
|
@@ -33,3 +33,27 @@ export declare function attachPaymentAction(input: {
|
|
|
33
33
|
paymentId: string;
|
|
34
34
|
paidAmount: number;
|
|
35
35
|
}): Promise<void>;
|
|
36
|
+
export interface VerifyAndPlaceRazorpayOrderInput {
|
|
37
|
+
userId: string;
|
|
38
|
+
userName: string;
|
|
39
|
+
userEmail: string;
|
|
40
|
+
razorpay_order_id: string;
|
|
41
|
+
razorpay_payment_id: string;
|
|
42
|
+
razorpay_signature: string;
|
|
43
|
+
addressId: string;
|
|
44
|
+
notes?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Place order(s) from the user's cart after a Razorpay payment is verified.
|
|
48
|
+
* Mirrors the existing /api/payment/verify route handler.
|
|
49
|
+
*
|
|
50
|
+
* Consumers must authenticate the user before calling. The action performs:
|
|
51
|
+
* 1. HMAC signature verification (rejects forged callbacks)
|
|
52
|
+
* 2. Cart re-validation against current product prices/stock
|
|
53
|
+
* 3. Amount cross-check against the Razorpay order record
|
|
54
|
+
* 4. Atomic stock decrement + cart clear via unitOfWork batch
|
|
55
|
+
* 5. Multi-coupon pro-rating per order group
|
|
56
|
+
* 6. order_placed notifications (buyer + seller)
|
|
57
|
+
* 7. Confirmation email + RTDB success signal (both fire-and-forget)
|
|
58
|
+
*/
|
|
59
|
+
export declare function verifyAndPlaceRazorpayOrderAction(input: VerifyAndPlaceRazorpayOrderInput): Promise<CheckoutOrderResult>;
|