@mohasinac/appkit 2.7.53 → 2.7.55
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.js +1 -1
- package/dist/_internal/server/jobs/core/auctionSettlement.js +6 -3
- package/dist/_internal/server/jobs/core/bundleStockSync.js +9 -7
- package/dist/_internal/server/jobs/core/onProductStockChange.d.ts +12 -3
- package/dist/_internal/server/jobs/core/onProductStockChange.js +12 -13
- package/dist/_internal/server/jobs/core/onProductWrite.js +1 -3
- package/dist/_internal/server/jobs/handlers/onProductStockChange.js +11 -2
- package/dist/_internal/server/jobs/runtime/adapters/firebase.js +5 -14
- package/dist/_internal/shared/actions/action-registry.js +827 -4
- package/dist/_internal/shared/features/events/schema.d.ts +4 -4
- package/dist/client.d.ts +2 -0
- package/dist/client.js +1 -0
- package/dist/constants/api-endpoints.d.ts +3 -0
- package/dist/constants/api-endpoints.js +1 -0
- package/dist/constants/field-names.d.ts +4 -3
- package/dist/constants/field-names.js +8 -8
- package/dist/errors/error-codes.d.ts +3 -0
- package/dist/errors/error-codes.js +3 -0
- package/dist/errors/messages.d.ts +3 -0
- package/dist/errors/messages.js +3 -0
- package/dist/features/account/components/UserOffersPanel.js +2 -1
- package/dist/features/admin/components/AdminAllEventEntriesView.js +4 -3
- package/dist/features/admin/components/AdminBidsView.js +5 -3
- package/dist/features/admin/components/AdminBlogView.js +3 -2
- package/dist/features/admin/components/AdminBrandsView.js +2 -1
- package/dist/features/admin/components/AdminBundleEditorView.js +4 -5
- package/dist/features/admin/components/AdminBundlesView.js +3 -3
- package/dist/features/admin/components/AdminCarouselView.d.ts +2 -1
- package/dist/features/admin/components/AdminCarouselView.js +14 -5
- package/dist/features/admin/components/AdminCategoriesView.js +2 -1
- package/dist/features/admin/components/AdminContactView.d.ts +4 -1
- package/dist/features/admin/components/AdminContactView.js +27 -7
- package/dist/features/admin/components/AdminCouponsView.d.ts +3 -1
- package/dist/features/admin/components/AdminCouponsView.js +17 -3
- package/dist/features/admin/components/AdminFaqsView.d.ts +3 -1
- package/dist/features/admin/components/AdminFaqsView.js +18 -4
- package/dist/features/admin/components/AdminFeaturesView.js +2 -1
- package/dist/features/admin/components/AdminMediaView.js +3 -2
- package/dist/features/admin/components/AdminNavigationView.js +3 -2
- package/dist/features/admin/components/AdminNewsletterView.d.ts +2 -1
- package/dist/features/admin/components/AdminNewsletterView.js +13 -4
- package/dist/features/admin/components/AdminNotificationsView.js +6 -4
- package/dist/features/admin/components/AdminOrdersView.js +4 -3
- package/dist/features/admin/components/AdminPayoutsView.js +2 -2
- package/dist/features/admin/components/AdminPrizeDrawsView.js +2 -1
- package/dist/features/admin/components/AdminProductsView.js +3 -3
- package/dist/features/admin/components/AdminReviewsView.js +4 -3
- package/dist/features/admin/components/AdminScammersView.js +2 -1
- package/dist/features/admin/components/AdminSessionsView.js +5 -3
- package/dist/features/admin/components/AdminStoresView.js +2 -2
- package/dist/features/admin/components/AdminSublistingCategoriesView.d.ts +5 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +12 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +2 -1
- package/dist/features/admin/components/AdminTeamView.d.ts +2 -1
- package/dist/features/admin/components/AdminTeamView.js +13 -4
- package/dist/features/admin/components/AdminUsersView.js +2 -2
- package/dist/features/admin/types/product.types.d.ts +1 -1
- package/dist/features/admin/types/product.types.js +2 -3
- package/dist/features/auctions/actions/bid-actions.d.ts +9 -0
- package/dist/features/auctions/actions/bid-actions.js +61 -0
- package/dist/features/auctions/components/AuctionDetailPageView.d.ts +2 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +5 -4
- package/dist/features/auctions/components/PlaceBidFormClient.d.ts +3 -1
- package/dist/features/auctions/components/PlaceBidFormClient.js +32 -2
- package/dist/features/auctions/types/index.d.ts +1 -1
- package/dist/features/layout/AppLayoutShell.js +1 -1
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +2 -11
- package/dist/features/products/api/[id]/route.js +4 -8
- package/dist/features/products/api/route.js +1 -3
- package/dist/features/products/components/AuctionsIndexListing.js +3 -11
- package/dist/features/products/components/PrizeDrawsIndexListing.js +2 -10
- package/dist/features/products/components/ProductFilters.d.ts +33 -9
- package/dist/features/products/components/ProductFilters.js +6 -29
- package/dist/features/products/components/ProductForm.js +2 -3
- package/dist/features/products/constants/action-defs.d.ts +86 -7
- package/dist/features/products/constants/action-defs.js +99 -7
- package/dist/features/products/constants/sieve.d.ts +162 -0
- package/dist/features/products/constants/sieve.js +95 -0
- package/dist/features/products/repository/products.repository.d.ts +5 -0
- package/dist/features/products/repository/products.repository.js +23 -3
- package/dist/features/products/schemas/firestore.d.ts +4 -4
- package/dist/features/products/schemas/firestore.js +2 -3
- package/dist/features/products/schemas/index.d.ts +6 -6
- package/dist/features/products/schemas/index.js +2 -6
- package/dist/features/products/types/index.d.ts +1 -1
- package/dist/features/seller/actions/offer-actions.js +2 -2
- package/dist/features/seller/components/QuickProductForm.d.ts +13 -0
- package/dist/features/seller/components/QuickProductForm.js +50 -0
- package/dist/features/seller/components/SellerAuctionsView.d.ts +4 -1
- package/dist/features/seller/components/SellerAuctionsView.js +37 -3
- package/dist/features/seller/components/SellerBidsView.js +2 -1
- package/dist/features/seller/components/SellerBundlesView.d.ts +3 -1
- package/dist/features/seller/components/SellerBundlesView.js +38 -5
- package/dist/features/seller/components/SellerClassifiedView.d.ts +3 -1
- package/dist/features/seller/components/SellerClassifiedView.js +37 -4
- package/dist/features/seller/components/SellerDigitalCodesView.d.ts +3 -1
- package/dist/features/seller/components/SellerDigitalCodesView.js +37 -4
- package/dist/features/seller/components/SellerGoogleReviewsView.js +2 -1
- package/dist/features/seller/components/SellerGroupedListingsView.js +3 -2
- package/dist/features/seller/components/SellerLiveView.d.ts +3 -1
- package/dist/features/seller/components/SellerLiveView.js +37 -4
- package/dist/features/seller/components/SellerOffersPanel.js +2 -1
- package/dist/features/seller/components/SellerOffersView.d.ts +4 -1
- package/dist/features/seller/components/SellerOffersView.js +8 -3
- package/dist/features/seller/components/SellerPayoutsView.d.ts +3 -1
- package/dist/features/seller/components/SellerPayoutsView.js +7 -3
- package/dist/features/seller/components/SellerPreOrdersView.d.ts +2 -1
- package/dist/features/seller/components/SellerPreOrdersView.js +30 -7
- package/dist/features/seller/components/SellerPrizeDrawsView.d.ts +2 -1
- package/dist/features/seller/components/SellerPrizeDrawsView.js +30 -7
- package/dist/features/seller/components/SellerProductShell.js +12 -0
- package/dist/features/seller/components/SellerReviewsView.js +2 -1
- package/dist/features/seller/components/SellerShippingConfigsView.js +3 -2
- package/dist/features/seller/components/SellerStoreCategoriesView.js +6 -5
- package/dist/features/seller/components/SellerTemplatesView.js +4 -3
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +30 -16
- package/dist/features/wishlist/types/index.d.ts +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +6 -4
- package/dist/seed/addresses-seed-data.d.ts +2 -18
- package/dist/seed/addresses-seed-data.js +137 -203
- package/dist/seed/bids-seed-data.d.ts +2 -8
- package/dist/seed/bids-seed-data.js +172 -648
- package/dist/seed/blog-posts-seed-data.d.ts +0 -5
- package/dist/seed/blog-posts-seed-data.js +341 -596
- package/dist/seed/carousel-slides-seed-data.d.ts +0 -5
- package/dist/seed/carousel-slides-seed-data.js +61 -192
- package/dist/seed/carousels-seed-data.js +18 -1
- package/dist/seed/cart-seed-data.d.ts +1 -18
- package/dist/seed/cart-seed-data.js +116 -293
- package/dist/seed/categories-seed-data.d.ts +0 -6
- package/dist/seed/categories-seed-data.js +1409 -1537
- package/dist/seed/claimed-coupons-seed-data.d.ts +0 -11
- package/dist/seed/claimed-coupons-seed-data.js +32 -29
- package/dist/seed/conversations-seed-data.d.ts +0 -6
- package/dist/seed/conversations-seed-data.js +132 -280
- package/dist/seed/coupon-usage-seed-data.d.ts +0 -16
- package/dist/seed/coupon-usage-seed-data.js +30 -44
- package/dist/seed/coupons-seed-data.d.ts +0 -6
- package/dist/seed/coupons-seed-data.js +141 -489
- package/dist/seed/events-seed-data.d.ts +0 -6
- package/dist/seed/events-seed-data.js +201 -379
- package/dist/seed/faq-seed-data.d.ts +0 -14
- package/dist/seed/faq-seed-data.js +609 -1184
- package/dist/seed/grouped-listings-seed-data.d.ts +119 -8
- package/dist/seed/grouped-listings-seed-data.js +148 -233
- package/dist/seed/history-seed-data.d.ts +0 -7
- package/dist/seed/history-seed-data.js +50 -54
- package/dist/seed/homepage-sections-seed-data.d.ts +0 -5
- package/dist/seed/homepage-sections-seed-data.js +83 -175
- package/dist/seed/index.d.ts +1 -1
- package/dist/seed/index.js +1 -1
- package/dist/seed/manifest.js +2 -2
- package/dist/seed/notifications-seed-data.d.ts +0 -6
- package/dist/seed/notifications-seed-data.js +309 -196
- package/dist/seed/offers-seed-data.d.ts +0 -8
- package/dist/seed/offers-seed-data.js +118 -197
- package/dist/seed/orders-seed-data.d.ts +2 -8
- package/dist/seed/orders-seed-data.js +248 -1510
- package/dist/seed/payouts-seed-data.d.ts +0 -6
- package/dist/seed/payouts-seed-data.js +102 -441
- package/dist/seed/products-auctions-seed-data.d.ts +1 -14
- package/dist/seed/products-auctions-seed-data.js +612 -1084
- package/dist/seed/products-preorders-seed-data.d.ts +119 -14
- package/dist/seed/products-preorders-seed-data.js +154 -455
- package/dist/seed/products-standard-seed-data.d.ts +1 -15
- package/dist/seed/products-standard-seed-data.js +1355 -4128
- package/dist/seed/reviews-seed-data.d.ts +2 -8
- package/dist/seed/reviews-seed-data.js +99 -1182
- package/dist/seed/scammers-seed-data.d.ts +0 -15
- package/dist/seed/scammers-seed-data.js +36 -37
- package/dist/seed/sessions-seed-data.d.ts +0 -13
- package/dist/seed/sessions-seed-data.js +58 -335
- package/dist/seed/site-settings-seed-data.d.ts +0 -4
- package/dist/seed/site-settings-seed-data.js +61 -52
- package/dist/seed/store-addresses-seed-data.js +27 -151
- package/dist/seed/store-extensions-seed-data.d.ts +0 -7
- package/dist/seed/store-extensions-seed-data.js +147 -261
- package/dist/seed/stores-seed-data.d.ts +0 -5
- package/dist/seed/stores-seed-data.js +222 -184
- package/dist/seed/sub-listings-seed-data.d.ts +119 -0
- package/dist/seed/sub-listings-seed-data.js +447 -0
- package/dist/seed/support-tickets-seed-data.d.ts +0 -7
- package/dist/seed/support-tickets-seed-data.js +82 -75
- package/dist/seed/users-seed-data.d.ts +0 -5
- package/dist/seed/users-seed-data.js +279 -634
- package/dist/seed/wishlists-seed-data.d.ts +0 -9
- package/dist/seed/wishlists-seed-data.js +36 -52
- package/dist/seo/json-ld.js +6 -4
- package/dist/styles.css +8052 -3
- package/dist/tailwind-utilities.css +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/search-tokens.d.ts +2 -0
- package/dist/utils/search-tokens.js +21 -0
- package/package.json +2 -2
- package/scripts/seed-cli.mjs +2 -2
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
4
4
|
import { Alert, Badge, BulkActionBar, Button, Checkbox, Div, Modal, Row, Select, SideDrawer, Stack, Text, Textarea, } from "../../../ui";
|
|
5
5
|
import { StackedViewShell } from "../../../ui";
|
|
6
|
+
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
6
7
|
const STAR = "★";
|
|
7
8
|
const EMPTY_STAR = "☆";
|
|
8
9
|
function Stars({ rating }) {
|
|
@@ -158,6 +159,6 @@ export function SellerReviewsView({ reviewsApiBase = "/api/store/reviews", reply
|
|
|
158
159
|
label: "Reply to selected",
|
|
159
160
|
onClick: () => setBulkReplyOpen(true),
|
|
160
161
|
},
|
|
161
|
-
] })), loading ? (_jsx(Div, { className: "py-8 text-center", children: _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", children: "Loading reviews\u2026" }) })) : reviews.length === 0 ? (_jsx(Div, { className: "py-12 text-center", children: _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", children: "No reviews found." }) })) : (_jsx(Stack, { gap: "md", children: reviews.map((review) => (_jsx(Div, { className: "p-4 rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)]", children: _jsxs(Div, { className: "flex items-start justify-between gap-3 flex-wrap", children: [_jsxs(Row, { className: "gap-3 items-start flex-1 min-w-0", children: [_jsx(Checkbox, { checked: selectedIds.has(review.id), onChange: () => toggleSelected(review.id), "aria-label": "Select review" }), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsx(Text, { className: "font-medium truncate", children: review.productTitle }), _jsxs(Div, { className: "flex items-center gap-2 mt-1 flex-wrap", children: [_jsx(Stars, { rating: review.rating }), _jsxs(Text, { className: "text-sm text-[var(--appkit-color-text-muted)]", children: ["by ", review.userName] }), review.verified && _jsx(Badge, { variant: "success", children: "Verified" }), statusBadge(review.status), _jsx(Badge, { variant: review.sellerReply ? "success" : "warning", children: review.sellerReply ? "Store replied" : "Awaiting store reply" })] }), review.title && _jsx(Text, { className: "mt-2 font-medium", children: review.title }), _jsx(Text, { className: "mt-1 text-sm text-[var(--appkit-color-text-secondary)] line-clamp-3", children: review.comment }), review.sellerReply && (_jsxs(Div, { className: "mt-2 pl-3 border-l-2 border-[var(--appkit-color-primary)]", children: [_jsx(Text, { className: "text-xs text-[var(--appkit-color-text-muted)]", children: "Store reply:" }), _jsx(Text, { className: "text-sm", children: review.sellerReply })] }))] })] }), _jsxs(Row, { className: "gap-2 flex-shrink-0", children: [_jsx(Button, { variant: "outline", size: "sm", onClick: () => openReply(review), children: review.sellerReply ? "Edit Reply" : "
|
|
162
|
+
] })), loading ? (_jsx(Div, { className: "py-8 text-center", children: _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", children: "Loading reviews\u2026" }) })) : reviews.length === 0 ? (_jsx(Div, { className: "py-12 text-center", children: _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", children: "No reviews found." }) })) : (_jsx(Stack, { gap: "md", children: reviews.map((review) => (_jsx(Div, { className: "p-4 rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)]", children: _jsxs(Div, { className: "flex items-start justify-between gap-3 flex-wrap", children: [_jsxs(Row, { className: "gap-3 items-start flex-1 min-w-0", children: [_jsx(Checkbox, { checked: selectedIds.has(review.id), onChange: () => toggleSelected(review.id), "aria-label": "Select review" }), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsx(Text, { className: "font-medium truncate", children: review.productTitle }), _jsxs(Div, { className: "flex items-center gap-2 mt-1 flex-wrap", children: [_jsx(Stars, { rating: review.rating }), _jsxs(Text, { className: "text-sm text-[var(--appkit-color-text-muted)]", children: ["by ", review.userName] }), review.verified && _jsx(Badge, { variant: "success", children: "Verified" }), statusBadge(review.status), _jsx(Badge, { variant: review.sellerReply ? "success" : "warning", children: review.sellerReply ? "Store replied" : "Awaiting store reply" })] }), review.title && _jsx(Text, { className: "mt-2 font-medium", children: review.title }), _jsx(Text, { className: "mt-1 text-sm text-[var(--appkit-color-text-secondary)] line-clamp-3", children: review.comment }), review.sellerReply && (_jsxs(Div, { className: "mt-2 pl-3 border-l-2 border-[var(--appkit-color-primary)]", children: [_jsx(Text, { className: "text-xs text-[var(--appkit-color-text-muted)]", children: "Store reply:" }), _jsx(Text, { className: "text-sm", children: review.sellerReply })] }))] })] }), _jsxs(Row, { className: "gap-2 flex-shrink-0", children: [_jsx(Button, { variant: "outline", size: "sm", onClick: () => openReply(review), children: review.sellerReply ? "Edit Reply" : ACTIONS.STORE["reply-review"].label }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setContestTarget(review), children: ACTIONS.STORE["contest-review"].label }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setFeedbackTarget(review), children: ACTIONS.STORE["buyer-feedback"].label })] })] }) }, review.id))) })), meta && meta.totalPages > 1 && (_jsxs(Div, { className: "flex items-center justify-center gap-2", children: [_jsx(Button, { variant: "outline", size: "sm", onClick: () => setPage((p) => Math.max(1, p - 1)), disabled: page <= 1 || loading, children: "Previous" }), _jsxs(Text, { className: "text-sm", children: ["Page ", meta.page, " of ", meta.totalPages] }), _jsx(Button, { variant: "outline", size: "sm", onClick: () => setPage((p) => p + 1), disabled: !meta.hasMore || loading, children: "Next" })] }))] }, "reviews"),
|
|
162
163
|
] }), _jsx(SideDrawer, { isOpen: !!replyTarget, onClose: () => setReplyTarget(null), title: replyTarget?.sellerReply ? "Edit Reply" : "Reply to Review", mode: "create", children: _jsxs(Stack, { gap: "md", className: "p-4", children: [replyTarget && (_jsxs(Div, { className: "p-3 rounded bg-[var(--appkit-color-surface-muted)]", children: [_jsx(Stars, { rating: replyTarget.rating }), _jsx(Text, { className: "text-sm mt-1", children: replyTarget.comment })] })), replyError && _jsx(Alert, { variant: "error", children: replyError }), _jsxs(Div, { children: [_jsx(Text, { className: "text-sm font-medium mb-1.5", children: "Store reply" }), _jsx("textarea", { className: "w-full rounded-md border border-[var(--appkit-color-border)] bg-[var(--appkit-color-input-bg,var(--appkit-color-surface))] p-2.5 text-sm resize-none focus:outline-none focus:ring-2 focus:ring-[var(--appkit-color-primary)] dark:bg-[var(--appkit-color-surface-dark,#1e2330)] dark:border-[var(--appkit-color-border-dark)]", rows: 5, value: replyText, onChange: (e) => setReplyText(e.target.value), maxLength: 1000, placeholder: "Write your response to this review\u2026" }), _jsxs(Text, { className: "text-xs text-[var(--appkit-color-text-muted)] text-right mt-1", children: [replyText.length, "/1000"] })] }), _jsxs(Div, { className: "flex gap-2 justify-end", children: [_jsx(Button, { variant: "outline", onClick: () => setReplyTarget(null), disabled: replySaving, children: "Cancel" }), _jsx(Button, { variant: "primary", onClick: handleReplySave, disabled: replySaving || !replyText.trim(), isLoading: replySaving, children: replyTarget?.sellerReply ? "Update Reply" : "Post Reply" })] })] }) }), _jsx(Modal, { isOpen: bulkReplyOpen, onClose: () => setBulkReplyOpen(false), title: `Bulk reply to ${selectedIds.size} review${selectedIds.size === 1 ? "" : "s"}`, actions: _jsxs(Row, { className: "gap-2", children: [_jsx(Button, { variant: "ghost", onClick: () => setBulkReplyOpen(false), disabled: bulkSaving, children: "Cancel" }), _jsx(Button, { variant: "primary", onClick: () => void submitBulkReply(), disabled: !bulkReplyText.trim() || bulkSaving, isLoading: bulkSaving, children: "Send reply" })] }), children: _jsxs(Stack, { gap: "md", className: "p-1", children: [_jsx(Text, { className: "text-sm text-[var(--appkit-color-text-muted)]", children: "The same reply will be posted on all selected reviews." }), _jsx(Textarea, { value: bulkReplyText, onChange: (e) => setBulkReplyText(e.target.value), rows: 5, placeholder: "Thanks for your review\u2026", label: "Reply" })] }) }), _jsx(Modal, { isOpen: !!contestTarget, onClose: () => setContestTarget(null), title: "Contest this review", actions: _jsxs(Row, { className: "gap-2", children: [_jsx(Button, { variant: "ghost", onClick: () => setContestTarget(null), children: "Cancel" }), _jsx(Button, { variant: "primary", onClick: () => void submitContest(), disabled: !contestReason.trim(), children: "Submit" })] }), children: _jsxs(Stack, { gap: "md", className: "p-1", children: [_jsx(Text, { className: "text-sm text-[var(--appkit-color-text-muted)]", children: "Flag this review for admin investigation. Provide a clear reason \u2014 fake, abusive, off-topic, etc." }), _jsx(Textarea, { value: contestReason, onChange: (e) => setContestReason(e.target.value), rows: 4, label: "Reason" })] }) }), _jsx(Modal, { isOpen: !!feedbackTarget, onClose: () => setFeedbackTarget(null), title: "Send feedback to buyer", actions: _jsxs(Row, { className: "gap-2", children: [_jsx(Button, { variant: "ghost", onClick: () => setFeedbackTarget(null), children: "Cancel" }), _jsx(Button, { variant: "primary", onClick: () => void submitFeedback(), disabled: !feedbackText.trim(), children: "Send" })] }), children: _jsxs(Stack, { gap: "md", className: "p-1", children: [_jsx(Text, { className: "text-sm text-[var(--appkit-color-text-muted)]", children: "Private message sent to the buyer's notification inbox. Does not appear on the public review." }), _jsx(Textarea, { value: feedbackText, onChange: (e) => setFeedbackText(e.target.value), rows: 4, label: "Feedback" })] }) })] }));
|
|
163
164
|
}
|
|
@@ -5,6 +5,7 @@ import { Plus } from "lucide-react";
|
|
|
5
5
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
6
6
|
import { Button, ConfirmDeleteModal, DataTable, Div, ListingToolbar, RowActionMenu, Text, } from "../../../ui";
|
|
7
7
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
|
+
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
8
9
|
import { ROUTES } from "../../..";
|
|
9
10
|
import { toRecordArray, toStringValue, useSellerListingData, } from "../hooks/useSellerListingData";
|
|
10
11
|
import { TABLE_KEYS } from "../../../constants/table-keys";
|
|
@@ -127,7 +128,7 @@ export function SellerShippingConfigsView({ onCreateClick, onEditClick, onDelete
|
|
|
127
128
|
}, [onEditClick]);
|
|
128
129
|
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: 0, searchValue: searchInput, searchPlaceholder: "Search shipping configs...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { size: "sm", onClick: handleCreate, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx("span", { children: "New Config" })] }) }), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-red-200 bg-red-50 dark:bg-red-950/40 dark:border-red-900/60 px-4 py-3 text-sm text-red-700 dark:text-red-200", children: errorMessage })), isLoading ? (_jsx(Div, { className: "space-y-2", children: Array.from({ length: 3 }).map((_, i) => (_jsx(Div, { className: "h-14 animate-pulse rounded-xl border border-zinc-100 dark:border-slate-700 bg-zinc-50 dark:bg-slate-800" }, i))) })) : rows.length === 0 ? (_jsxs(Div, { className: "py-16 text-center", children: [_jsx(Text, { className: "text-zinc-400 dark:text-zinc-500", children: "No shipping configs yet \u2014 define your first shipping rule" }), _jsx("div", { className: "mt-4", children: _jsx(Button, { size: "sm", onClick: handleCreate, children: "Add shipping config" }) })] })) : (_jsx(DataTable, { columns: COLUMNS, data: rows, keyExtractor: (r) => r.id, actions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
129
130
|
{
|
|
130
|
-
label: "
|
|
131
|
+
label: ACTIONS.STORE["edit-listing"].label,
|
|
131
132
|
onClick: () => handleEdit(row.id),
|
|
132
133
|
},
|
|
133
134
|
...(!row.isDefault
|
|
@@ -140,7 +141,7 @@ export function SellerShippingConfigsView({ onCreateClick, onEditClick, onDelete
|
|
|
140
141
|
]
|
|
141
142
|
: []),
|
|
142
143
|
{
|
|
143
|
-
label: "
|
|
144
|
+
label: ACTIONS.STORE["delete-listing"].label,
|
|
144
145
|
destructive: true,
|
|
145
146
|
onClick: () => setDeleteTargetId(row.id),
|
|
146
147
|
disabled: deletingId === row.id,
|
|
@@ -6,6 +6,7 @@ import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
|
6
6
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
7
7
|
import { BulkActionBar, Button, ConfirmDeleteModal, DataTable, Div, ListingToolbar, Pagination, RowActionMenu, Text, } from "../../../ui";
|
|
8
8
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
9
|
+
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
9
10
|
import { ROUTES } from "../../../next";
|
|
10
11
|
import { toRecordArray, toStringValue, useSellerListingData, } from "../hooks/useSellerListingData";
|
|
11
12
|
import { TABLE_KEYS } from "../../../constants/table-keys";
|
|
@@ -83,18 +84,18 @@ export function SellerStoreCategoriesView({ onCreateClick, onEditClick, onDelete
|
|
|
83
84
|
const bulkActions = [
|
|
84
85
|
...(onBulkDelete ? [{
|
|
85
86
|
id: "bulk-delete",
|
|
86
|
-
label: "
|
|
87
|
+
label: ACTIONS.STORE["delete-listing"].label,
|
|
87
88
|
variant: "danger",
|
|
88
89
|
onClick: async () => { await onBulkDelete(selection.selectedIds); selection.clearSelection(); refetch?.(); },
|
|
89
90
|
}] : []),
|
|
90
91
|
...(onBulkActivate ? [{
|
|
91
92
|
id: "bulk-activate",
|
|
92
|
-
label: "
|
|
93
|
+
label: ACTIONS.ADMIN["activate-bundle"].label,
|
|
93
94
|
onClick: async () => { await onBulkActivate(selection.selectedIds); selection.clearSelection(); refetch?.(); },
|
|
94
95
|
}] : []),
|
|
95
96
|
...(onBulkDeactivate ? [{
|
|
96
97
|
id: "bulk-deactivate",
|
|
97
|
-
label: "
|
|
98
|
+
label: ACTIONS.ADMIN["deactivate-bundle"].label,
|
|
98
99
|
onClick: async () => { await onBulkDeactivate(selection.selectedIds); selection.clearSelection(); refetch?.(); },
|
|
99
100
|
}] : []),
|
|
100
101
|
];
|
|
@@ -107,13 +108,13 @@ export function SellerStoreCategoriesView({ onCreateClick, onEditClick, onDelete
|
|
|
107
108
|
};
|
|
108
109
|
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: 0, searchValue: searchInput, searchPlaceholder: "Search categories by label...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, showTableView: true, view: "table", onViewChange: () => { }, onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { size: "sm", onClick: handleNavigateNew, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx("span", { children: "New Category" })] }) }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedCount > 0 && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, actions: bulkActions, onClearSelection: selection.clearSelection })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-red-200 bg-red-50 dark:bg-red-950/40 dark:border-red-900/60 px-4 py-3 text-sm text-red-700 dark:text-red-200", children: errorMessage })), isLoading ? (_jsx(Div, { className: "space-y-2", children: Array.from({ length: 5 }).map((_, i) => (_jsx(Div, { className: "h-14 animate-pulse rounded-xl border border-zinc-100 dark:border-slate-700 bg-zinc-50 dark:bg-slate-800" }, i))) })) : rows.length === 0 ? (_jsx(Div, { className: "py-16 text-center", children: _jsx(Text, { className: "text-zinc-400 dark:text-zinc-500", children: "No categories yet \u2014 add your first storefront category" }) })) : (_jsx(DataTable, { columns: COLUMNS, data: rows, keyExtractor: (r) => r.id, selectable: bulkActions.length > 0, selectedIds: selection.selectedIds, onSelectionChange: (ids) => selection.setSelectedIds(ids), actions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
109
110
|
{
|
|
110
|
-
label: "
|
|
111
|
+
label: ACTIONS.STORE["edit-listing"].label,
|
|
111
112
|
onClick: () => onEditClick
|
|
112
113
|
? onEditClick(row.id)
|
|
113
114
|
: (window.location.href = String(ROUTES.STORE.STORE_CATEGORIES_EDIT(row.id))),
|
|
114
115
|
},
|
|
115
116
|
...(onDelete ? [{
|
|
116
|
-
label: "
|
|
117
|
+
label: ACTIONS.STORE["delete-listing"].label,
|
|
117
118
|
destructive: true,
|
|
118
119
|
onClick: () => setDeleteTargetId(row.id),
|
|
119
120
|
disabled: deletingId === row.id,
|
|
@@ -6,6 +6,7 @@ import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
|
6
6
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
7
7
|
import { BulkActionBar, Button, ConfirmDeleteModal, DataTable, Div, FilterDrawer, Input, ListingToolbar, Pagination, RowActionMenu, Select, SideDrawer, Stack, Text, } from "../../../ui";
|
|
8
8
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
9
|
+
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
9
10
|
import { toRecordArray, toStringValue, useSellerListingData, } from "../hooks/useSellerListingData";
|
|
10
11
|
import { TABLE_KEYS } from "../../../constants/table-keys";
|
|
11
12
|
const PAGE_SIZE = 25;
|
|
@@ -226,7 +227,7 @@ export function SellerTemplatesView({ onDelete, onBulkDelete, onDuplicate, }) {
|
|
|
226
227
|
const bulkActions = [
|
|
227
228
|
{
|
|
228
229
|
id: "bulk-delete",
|
|
229
|
-
label: "
|
|
230
|
+
label: ACTIONS.STORE["delete-template"].label,
|
|
230
231
|
variant: "danger",
|
|
231
232
|
onClick: async () => {
|
|
232
233
|
if (onBulkDelete) {
|
|
@@ -247,7 +248,7 @@ export function SellerTemplatesView({ onDelete, onBulkDelete, onDuplicate, }) {
|
|
|
247
248
|
? "No templates match your search or filters"
|
|
248
249
|
: "No templates yet — add your first product template" }) })) : (_jsx(DataTable, { columns: COLUMNS, data: pageRows, keyExtractor: (r) => r.id, selectable: bulkActions.length > 0, selectedIds: selection.selectedIds, onSelectionChange: (ids) => selection.setSelectedIds(ids), actions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
249
250
|
{
|
|
250
|
-
label: "
|
|
251
|
+
label: ACTIONS.STORE["edit-template"].label,
|
|
251
252
|
onClick: () => openEdit(row),
|
|
252
253
|
},
|
|
253
254
|
{
|
|
@@ -256,7 +257,7 @@ export function SellerTemplatesView({ onDelete, onBulkDelete, onDuplicate, }) {
|
|
|
256
257
|
onClick: () => handleDuplicate(row),
|
|
257
258
|
},
|
|
258
259
|
{
|
|
259
|
-
label: "
|
|
260
|
+
label: ACTIONS.STORE["delete-template"].label,
|
|
260
261
|
destructive: true,
|
|
261
262
|
onClick: () => setDeleteTargetId(row.id),
|
|
262
263
|
disabled: deletingId === row.id,
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
const CLS_SECTION_CARD = "border border-zinc-200 dark:border-zinc-700 rounded-xl p-5";
|
|
5
5
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
6
|
-
import { Alert, Button, Div, Form, FormActions, Heading, Input, Section, Text, Toggle, useToast } from "../../../ui";
|
|
6
|
+
import { Alert, Badge, Button, Div, Form, FormActions, Heading, Input, Row, Section, Stack, Text, Toggle, useToast } from "../../../ui";
|
|
7
7
|
import { apiClient } from "../../../http";
|
|
8
8
|
import { WHATSAPP_SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
9
|
+
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
9
10
|
import { buildPurchaseAnnouncementMessage } from "../helpers/whatsapp";
|
|
10
11
|
// ---------------------------------------------------------------------------
|
|
11
12
|
// Sub-components
|
|
12
13
|
// ---------------------------------------------------------------------------
|
|
13
14
|
function MaskedTokenInput({ label, value, onChange, placeholder, helperText, }) {
|
|
14
15
|
const [revealed, setRevealed] = React.useState(false);
|
|
15
|
-
return (_jsxs(
|
|
16
|
+
return (_jsxs(Div, { className: "relative", children: [_jsx(Input, { label: label, value: value, onChange: (e) => onChange(e.target.value), type: revealed ? "text" : "password", placeholder: placeholder, helperText: helperText }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setRevealed((r) => !r), className: "absolute right-3 top-8 text-xs", children: revealed ? "Hide" : "Reveal" })] }));
|
|
16
17
|
}
|
|
17
18
|
const STEPS = [
|
|
18
19
|
{
|
|
@@ -46,10 +47,10 @@ const STEPS = [
|
|
|
46
47
|
checkKey: "connected",
|
|
47
48
|
},
|
|
48
49
|
];
|
|
49
|
-
const
|
|
50
|
-
success: "
|
|
51
|
-
partial: "
|
|
52
|
-
failed: "
|
|
50
|
+
const STATUS_VARIANT = {
|
|
51
|
+
success: "success",
|
|
52
|
+
partial: "warning",
|
|
53
|
+
failed: "danger",
|
|
53
54
|
};
|
|
54
55
|
// ---------------------------------------------------------------------------
|
|
55
56
|
// Sample catalog items for preview
|
|
@@ -115,7 +116,7 @@ export function SellerWhatsAppSettingsView({ hasCapability }) {
|
|
|
115
116
|
showToast(msg, "error");
|
|
116
117
|
},
|
|
117
118
|
});
|
|
118
|
-
// Catalog sync mutation
|
|
119
|
+
// Catalog sync mutation (push: site → WhatsApp)
|
|
119
120
|
const syncMutation = useMutation({
|
|
120
121
|
mutationFn: async () => apiClient.post(WHATSAPP_SELLER_ENDPOINTS.CATALOG_SYNC, {}),
|
|
121
122
|
onSuccess: (res) => {
|
|
@@ -128,28 +129,41 @@ export function SellerWhatsAppSettingsView({ hasCapability }) {
|
|
|
128
129
|
showToast(msg, "error");
|
|
129
130
|
},
|
|
130
131
|
});
|
|
132
|
+
// Catalog import mutation (pull: WhatsApp → site)
|
|
133
|
+
const importMutation = useMutation({
|
|
134
|
+
mutationFn: async () => apiClient.post(WHATSAPP_SELLER_ENDPOINTS.CATALOG_IMPORT, {}),
|
|
135
|
+
onSuccess: (res) => {
|
|
136
|
+
const r = res ?? {};
|
|
137
|
+
showToast(`Imported ${r.imported ?? 0} product${(r.imported ?? 0) !== 1 ? "s" : ""} from WhatsApp (${r.skipped ?? 0} already synced)`, "success");
|
|
138
|
+
void queryClient.invalidateQueries({ queryKey: ["store", "whatsapp-settings"] });
|
|
139
|
+
},
|
|
140
|
+
onError: (err) => {
|
|
141
|
+
const msg = err instanceof Error ? err.message : "Import failed";
|
|
142
|
+
showToast(msg, "error");
|
|
143
|
+
},
|
|
144
|
+
});
|
|
131
145
|
if (!hasCapability) {
|
|
132
|
-
return (_jsx(
|
|
146
|
+
return (_jsx(Div, { className: "max-w-xl mx-auto py-8 px-4", children: _jsxs(Alert, { variant: "warning", children: [_jsx(Text, { className: "font-medium", children: "WhatsApp catalog sync is not enabled for your store." }), _jsx(Text, { className: "text-sm mt-1", children: "Contact LetItRip support to request access to the WhatsApp Business integration." })] }) }));
|
|
133
147
|
}
|
|
134
|
-
return (_jsxs("
|
|
148
|
+
return (_jsxs(Stack, { gap: "xl", className: "max-w-2xl mx-auto py-6 px-4", children: [_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "text-base font-semibold text-zinc-900 dark:text-zinc-100 mb-4", children: "How to connect your WhatsApp Business account" }), _jsx(Stack, { gap: "sm", children: STEPS.map((step) => {
|
|
135
149
|
const done = step.checkKey === undefined
|
|
136
150
|
? false
|
|
137
151
|
: step.checkKey === "connected"
|
|
138
152
|
? cfg?.connected === true
|
|
139
153
|
: Boolean(cfg?.[step.checkKey]);
|
|
140
|
-
return (_jsxs(
|
|
141
|
-
? "bg-
|
|
142
|
-
: "bg-zinc-200 dark:bg-zinc-700 text-zinc-600 dark:text-zinc-300"}`, children: done ? "✓" : step.n }), _jsxs(
|
|
143
|
-
}) })] }), _jsxs(Section, { className: CLS_SECTION_CARD, children: [_jsxs(
|
|
154
|
+
return (_jsxs(Row, { gap: "sm", align: "start", children: [_jsx(Div, { className: `flex-shrink-0 w-6 h-6 rounded-full text-xs font-bold flex items-center justify-center mt-0.5 ${done
|
|
155
|
+
? "bg-[var(--appkit-color-success)] text-white"
|
|
156
|
+
: "bg-zinc-200 dark:bg-zinc-700 text-zinc-600 dark:text-zinc-300"}`, children: done ? "✓" : step.n }), _jsxs(Div, { children: [_jsx(Text, { className: "text-sm font-medium text-zinc-900 dark:text-zinc-100", children: step.title }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: step.body })] })] }, step.n));
|
|
157
|
+
}) })] }), _jsxs(Section, { className: CLS_SECTION_CARD, children: [_jsxs(Row, { justify: "between", align: "center", className: "mb-4", children: [_jsx(Heading, { level: 2, className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: "Connection" }), isLoading ? null : cfg?.connected ? (_jsx(Badge, { variant: "success", children: "Connected" })) : (_jsx(Badge, { variant: "default", children: "Not configured" }))] }), _jsxs(Form, { onSubmit: (e) => {
|
|
144
158
|
e.preventDefault();
|
|
145
159
|
saveMutation.mutate();
|
|
146
|
-
}, className: "space-y-4", children: [_jsx(Input, { label: "WhatsApp Business Phone Number", value: phoneNumber, onChange: (e) => setPhoneNumber(e.target.value), placeholder: "919876543210", helperText: "Digits only, include country code (e.g. 91 for India)" }), _jsx(Input, { label: "WABA ID (WhatsApp Business Account ID)", value: wabaId, onChange: (e) => setWabaId(e.target.value), placeholder: "123456789012345", helperText: "From Meta Business Manager \u2192 WhatsApp Accounts" }), _jsx(Input, { label: "Catalog ID", value: catalogId, onChange: (e) => setCatalogId(e.target.value), placeholder: "987654321098765", helperText: "From Meta Commerce Manager \u2192 Catalogs" }), _jsx(MaskedTokenInput, { label: "System User Access Token", value: accessToken, onChange: setAccessToken, placeholder: "EAAxxxxxxxx\u2026", helperText: "Long-lived token with WhatsApp Business permissions" }), _jsx(FormActions, { align: "right", children: _jsx(Button, { type: "submit", isLoading: saveMutation.isPending, disabled: saveMutation.isPending, children: saveMutation.isPending ? "Saving…" : "
|
|
160
|
+
}, className: "space-y-4", children: [_jsx(Input, { label: "WhatsApp Business Phone Number", value: phoneNumber, onChange: (e) => setPhoneNumber(e.target.value), placeholder: "919876543210", helperText: "Digits only, include country code (e.g. 91 for India)" }), _jsx(Input, { label: "WABA ID (WhatsApp Business Account ID)", value: wabaId, onChange: (e) => setWabaId(e.target.value), placeholder: "123456789012345", helperText: "From Meta Business Manager \u2192 WhatsApp Accounts" }), _jsx(Input, { label: "Catalog ID", value: catalogId, onChange: (e) => setCatalogId(e.target.value), placeholder: "987654321098765", helperText: "From Meta Commerce Manager \u2192 Catalogs" }), _jsx(MaskedTokenInput, { label: "System User Access Token", value: accessToken, onChange: setAccessToken, placeholder: "EAAxxxxxxxx\u2026", helperText: "Long-lived token with WhatsApp Business permissions" }), _jsx(FormActions, { align: "right", children: _jsx(Button, { type: "submit", isLoading: saveMutation.isPending, disabled: saveMutation.isPending, children: saveMutation.isPending ? "Saving…" : ACTIONS.STORE["whatsapp-connect"].label }) })] })] }), _jsxs(Section, { className: CLS_SECTION_CARD, children: [_jsx(Heading, { level: 2, className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 mb-4", children: "Catalog Sync" }), _jsxs(Row, { justify: "between", align: "center", className: "mb-4", children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-sm text-zinc-700 dark:text-zinc-300", children: "Enable catalog sync" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "When enabled, your published standard products can be synced to WhatsApp." })] }), _jsx(Toggle, { checked: syncEnabled, onChange: setSyncEnabled, disabled: !cfg?.connected })] }), cfg?.lastCatalogSyncAt && (_jsxs(Row, { gap: "sm", align: "center", className: "text-xs text-zinc-500 dark:text-zinc-400 mb-3", children: [_jsxs(Text, { children: ["Last sync: ", new Date(cfg.lastCatalogSyncAt).toLocaleString("en-IN")] }), cfg.lastSyncCount !== undefined && _jsxs(Text, { children: ["\u00B7 ", cfg.lastSyncCount, " products"] }), cfg.lastSyncStatus && (_jsx(Badge, { variant: STATUS_VARIANT[cfg.lastSyncStatus] ?? "default", children: cfg.lastSyncStatus }))] })), _jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-500 mb-3", children: "Only published standard products are synced. Auctions and pre-orders are excluded. Batches of up to 50 products per call." }), _jsxs(Div, { className: "flex gap-3", children: [_jsx(Button, { onClick: () => syncMutation.mutate(), isLoading: syncMutation.isPending, disabled: !cfg?.connected || !syncEnabled || syncMutation.isPending, variant: "secondary", children: syncMutation.isPending ? "Syncing…" : ACTIONS.STORE["whatsapp-catalog-sync"].label }), _jsx(Button, { onClick: () => importMutation.mutate(), isLoading: importMutation.isPending, disabled: !cfg?.connected || !syncEnabled || importMutation.isPending, variant: "secondary", children: importMutation.isPending ? "Importing…" : ACTIONS.STORE["whatsapp-catalog-import"].label })] }), _jsxs(Text, { className: "text-xs text-zinc-400 dark:text-zinc-500 mt-3", children: [_jsx("strong", { children: "Push" }), " sends your published standard products to WhatsApp.", " ", _jsx("strong", { children: "Import" }), " creates draft products from your WhatsApp catalog. Products are matched by slug in the description field."] })] }), _jsxs(Section, { className: CLS_SECTION_CARD, children: [_jsx(Heading, { level: 2, className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 mb-2", children: "Purchase Announcement Preview" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mb-3", children: "This message is sent automatically to your phone and the platform admin when a new order is placed." }), _jsx(Div, { className: "bg-zinc-50 dark:bg-zinc-800/60 rounded-lg px-4 py-3 text-sm text-zinc-700 dark:text-zinc-200 font-mono", children: buildPurchaseAnnouncementMessage({
|
|
147
161
|
buyerName: "Ravi K.",
|
|
148
162
|
firstItemName: "Charizard PSA 9",
|
|
149
163
|
additionalItemCount: 2,
|
|
150
164
|
totalAmount: 450000,
|
|
151
165
|
orderId: "order-3-20260510-a1b2c3",
|
|
152
|
-
}) })] }), _jsxs(Section, { className: CLS_SECTION_CARD, children: [_jsx(Heading, { level: 2, className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 mb-2", children: "Catalog Preview" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mb-4", children: "This is how your products appear in the WhatsApp Catalog when a buyer taps \"View Catalog\" in the chat. Only published standard products are included." }), _jsxs(
|
|
166
|
+
}) })] }), _jsxs(Section, { className: CLS_SECTION_CARD, children: [_jsx(Heading, { level: 2, className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 mb-2", children: "Catalog Preview" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mb-4", children: "This is how your products appear in the WhatsApp Catalog when a buyer taps \"View Catalog\" in the chat. Only published standard products are included." }), _jsxs(Div, { className: "border border-zinc-200 dark:border-zinc-700 rounded-xl overflow-hidden bg-[#ECE5DD] dark:bg-zinc-800 p-3", children: [_jsxs(Row, { gap: "sm", align: "center", className: "mb-3", children: [_jsx(Div, { className: "w-8 h-8 rounded-full bg-[#25D366] flex items-center justify-center", children: _jsx(Text, { className: "text-white text-xs font-bold", children: "W" }) }), _jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-semibold text-zinc-900 dark:text-zinc-100", children: cfg?.connected ? "Your Store" : "Store Name" }), _jsx(Text, { className: "text-[10px] text-zinc-500 dark:text-zinc-400", children: "WhatsApp Business" })] })] }), _jsx(Div, { className: "grid grid-cols-2 gap-2", children: SAMPLE_CATALOG_ITEMS.map((item) => (_jsxs(Div, { className: "bg-white dark:bg-zinc-900 rounded-lg overflow-hidden shadow-sm", children: [_jsx(Div, { className: "aspect-square bg-zinc-100 dark:bg-zinc-800 flex items-center justify-center", children: _jsx(Text, { className: "text-2xl", children: item.emoji }) }), _jsxs(Div, { className: "p-2", children: [_jsx(Text, { className: "text-xs font-medium text-zinc-900 dark:text-zinc-100 line-clamp-2 leading-tight", children: item.name }), _jsx(Text, { className: "text-xs text-[#25D366] font-semibold mt-0.5", children: item.price })] })] }, item.id))) }), _jsx(Div, { className: "mt-3 text-center", children: _jsx(Text, { className: "text-[10px] text-zinc-500 dark:text-zinc-400", children: cfg?.lastSyncCount
|
|
153
167
|
? `${cfg.lastSyncCount} products synced to catalog`
|
|
154
168
|
: "Sync your products to populate the catalog" }) })] }), !cfg?.connected && (_jsx(Text, { className: "text-xs text-amber-600 dark:text-amber-400 mt-2", children: "Connect your WhatsApp Business account above to enable the catalog." }))] })] }));
|
|
155
169
|
}
|
|
@@ -21,7 +21,7 @@ export interface WishlistProductData {
|
|
|
21
21
|
price?: number;
|
|
22
22
|
currency?: string;
|
|
23
23
|
images?: string[];
|
|
24
|
-
status?: "draft" | "published" | "
|
|
24
|
+
status?: "draft" | "published" | "in_review" | "archived";
|
|
25
25
|
isFeatured?: boolean;
|
|
26
26
|
/** Canonical listing-kind discriminator (SB1-G Phase 4). */
|
|
27
27
|
listingType?: "standard" | "auction" | "pre-order" | "prize-draw" | "classified" | "digital-code" | "live";
|
package/dist/index.d.ts
CHANGED
|
@@ -623,7 +623,7 @@ export { ordersSeedData } from "./seed/index";
|
|
|
623
623
|
export { payoutsSeedData } from "./seed/index";
|
|
624
624
|
export { productsStandardSeedData } from "./seed/index";
|
|
625
625
|
export { productsAuctionsSeedData } from "./seed/index";
|
|
626
|
-
export {
|
|
626
|
+
export { productsPreordersSeedData } from "./seed/index";
|
|
627
627
|
export { productsPrizeDrawsSeedData } from "./seed/index";
|
|
628
628
|
export { registerSeedLocale } from "./seed/index";
|
|
629
629
|
export { reviewsSeedData } from "./seed/index";
|
|
@@ -1360,8 +1360,8 @@ export { GET } from "./features/auctions/server";
|
|
|
1360
1360
|
export { bidsGET } from "./features/auctions/server";
|
|
1361
1361
|
export { getBidById } from "./features/auctions/server";
|
|
1362
1362
|
export { listBidsByProduct } from "./features/auctions/server";
|
|
1363
|
-
export { placeBid } from "./features/auctions/server";
|
|
1364
|
-
export type { PlaceBidInput } from "./features/auctions/server";
|
|
1363
|
+
export { placeBid, buyNowAuction } from "./features/auctions/server";
|
|
1364
|
+
export type { PlaceBidInput, BuyNowAuctionInput, BuyNowAuctionResult } from "./features/auctions/server";
|
|
1365
1365
|
export type { PlaceBidResult } from "./features/auctions/server";
|
|
1366
1366
|
export { CONSENT_OTP_COOLDOWN_MS } from "./features/auth/server";
|
|
1367
1367
|
export { CONSENT_OTP_EXPIRY_MINUTES } from "./features/auth/server";
|
|
@@ -3048,6 +3048,8 @@ export type { ListingParams } from "./utils/listing-params";
|
|
|
3048
3048
|
export { PRODUCT_FEATURE_CATEGORY_OPTIONS, PRODUCT_FEATURE_PRODUCT_TYPE_OPTIONS, PRODUCT_FEATURE_SCOPE_OPTIONS, PRODUCT_FEATURE_ICON_COLOR_OPTIONS, PRODUCT_FEATURE_SCOPE_TABS, PRODUCT_FEATURE_DEFAULT_DISPLAY_ORDER, PRODUCT_FEATURE_CARD_MAX_VISIBLE, PRODUCT_FEATURE_QUERY_STALE_MS, } from "./features/products/constants/product-features.constants";
|
|
3049
3049
|
export { CATEGORY_PAGE_TABS, STORE_PAGE_TABS, SELLER_LISTING_TABS, SEARCH_RESULT_TABS, } from "./features/products/constants/listing-tabs";
|
|
3050
3050
|
export type { ListingTab, CategoryTabId, StoreTabId, SellerListingTabId, SearchTabId, } from "./features/products/constants/listing-tabs";
|
|
3051
|
+
export { STANDARD_SORT_OPTIONS, STANDARD_PUBLIC_SORT_OPTIONS, AUCTION_SORT_OPTIONS, AUCTION_PUBLIC_SORT_OPTIONS, PREORDER_SORT_OPTIONS, BUNDLE_SORT_OPTIONS, PRIZE_DRAW_SORT_OPTIONS, SORT_OPTIONS_BY_LISTING_TYPE, } from "./features/products/constants/sieve";
|
|
3052
|
+
export type { SortOption } from "./features/products/constants/sieve";
|
|
3051
3053
|
export { ALL_TAB, EMPTY_TAB, ADMIN_PRODUCT_STATUS_TABS, ADMIN_PRODUCT_LISTING_TYPE_TABS, ADMIN_BLOG_STATUS_TABS, ADMIN_USER_STATUS_TABS, ADMIN_USER_ROLE_TABS, ADMIN_STORE_STATUS_TABS, ADMIN_PAYOUT_STATUS_TABS, ADMIN_ORDER_STATUS_TABS, ADMIN_REVIEW_STATUS_TABS, ADMIN_REVIEW_RATING_TABS, ADMIN_BID_STATUS_TABS, ADMIN_CONTACT_STATUS_TABS, ADMIN_NEWSLETTER_STATUS_TABS, ADMIN_EVENT_ENTRY_STATUS_TABS, ADMIN_EVENT_STATUS_TABS, ADMIN_CART_OWNERSHIP_TABS, ADMIN_COUPON_TYPE_TABS, SELLER_PRODUCT_STATUS_TABS, SELLER_AUCTION_STATUS_TABS, SELLER_ORDER_STATUS_TABS, SELLER_OFFER_STATUS_TABS, SELLER_BID_STATUS_TABS, } from "./features/admin/constants/filter-tabs";
|
|
3052
3054
|
export type { AdminFilterTab } from "./features/admin/constants/filter-tabs";
|
|
3053
3055
|
export { GROUPED_LISTINGS_COLLECTION } from "./features/grouped/schemas/firestore";
|
|
@@ -3119,6 +3121,7 @@ export { TABLE_KEYS, VIEW_MODE } from "./constants/table-keys";
|
|
|
3119
3121
|
export type { TableKey, ViewMode } from "./constants/table-keys";
|
|
3120
3122
|
export { SIEVE_OP, SIEVE_PIPE_OPS, sieveFilter, sieveMultiEq, expandSieveParam, sieveAnd, } from "./utils/sieve-builder";
|
|
3121
3123
|
export type { SieveOp } from "./utils/sieve-builder";
|
|
3124
|
+
export { buildSearchTokens, tokenizeQuery } from "./utils/search-tokens";
|
|
3122
3125
|
export { ActionPermissionsManager } from "./features/site-settings/components/ActionPermissionsManager";
|
|
3123
3126
|
export type { ActionPermissionsManagerProps } from "./features/site-settings/components/ActionPermissionsManager";
|
|
3124
3127
|
export { NavPermissionsManager } from "./features/site-settings/components/NavPermissionsManager";
|
package/dist/index.js
CHANGED
|
@@ -1317,8 +1317,8 @@ export { productsStandardSeedData } from "./seed/index";
|
|
|
1317
1317
|
// productsAuctionsSeedData - Seed data for auction product listings.
|
|
1318
1318
|
export { productsAuctionsSeedData } from "./seed/index";
|
|
1319
1319
|
// [SERVER-ONLY]-Server-only â€" uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
1320
|
-
//
|
|
1321
|
-
export {
|
|
1320
|
+
// productsPreordersSeedData - Seed data for pre-order product listings.
|
|
1321
|
+
export { productsPreordersSeedData } from "./seed/index";
|
|
1322
1322
|
// [SERVER-ONLY]-Server-only â€" uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
1323
1323
|
// productsPrizeDrawsSeedData - Seed data for prize-draw product listings (SB5-E).
|
|
1324
1324
|
export { productsPrizeDrawsSeedData } from "./seed/index";
|
|
@@ -2546,8 +2546,8 @@ export { getBidById } from "./features/auctions/server";
|
|
|
2546
2546
|
// listBidsByProduct - Helper for list bids by product.
|
|
2547
2547
|
export { listBidsByProduct } from "./features/auctions/server";
|
|
2548
2548
|
// [SERVER-ONLY]-Server-only â€" uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
2549
|
-
// placeBid - Shared export for
|
|
2550
|
-
export { placeBid } from "./features/auctions/server";
|
|
2549
|
+
// placeBid / buyNowAuction - Shared export for bid + buy-now actions.
|
|
2550
|
+
export { placeBid, buyNowAuction } from "./features/auctions/server";
|
|
2551
2551
|
// ./features/auth/server
|
|
2552
2552
|
// [SERVER-ONLY]-Server-only â€" uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
2553
2553
|
// CONSENT_OTP_COOLDOWN_MS - Constant used across modules.
|
|
@@ -5488,6 +5488,7 @@ export { LISTING_PARAM_NAMES, parseListingParams, parseListingSearchParams, seri
|
|
|
5488
5488
|
export { PRODUCT_FEATURE_CATEGORY_OPTIONS, PRODUCT_FEATURE_PRODUCT_TYPE_OPTIONS, PRODUCT_FEATURE_SCOPE_OPTIONS, PRODUCT_FEATURE_ICON_COLOR_OPTIONS, PRODUCT_FEATURE_SCOPE_TABS, PRODUCT_FEATURE_DEFAULT_DISPLAY_ORDER, PRODUCT_FEATURE_CARD_MAX_VISIBLE, PRODUCT_FEATURE_QUERY_STALE_MS, } from "./features/products/constants/product-features.constants";
|
|
5489
5489
|
// SB10-A listing tab constants
|
|
5490
5490
|
export { CATEGORY_PAGE_TABS, STORE_PAGE_TABS, SELLER_LISTING_TABS, SEARCH_RESULT_TABS, } from "./features/products/constants/listing-tabs";
|
|
5491
|
+
export { STANDARD_SORT_OPTIONS, STANDARD_PUBLIC_SORT_OPTIONS, AUCTION_SORT_OPTIONS, AUCTION_PUBLIC_SORT_OPTIONS, PREORDER_SORT_OPTIONS, BUNDLE_SORT_OPTIONS, PRIZE_DRAW_SORT_OPTIONS, SORT_OPTIONS_BY_LISTING_TYPE, } from "./features/products/constants/sieve";
|
|
5491
5492
|
// SB10-C admin + seller filter-chip tab sets (S8 2026-05-13)
|
|
5492
5493
|
export { ALL_TAB, EMPTY_TAB, ADMIN_PRODUCT_STATUS_TABS, ADMIN_PRODUCT_LISTING_TYPE_TABS, ADMIN_BLOG_STATUS_TABS, ADMIN_USER_STATUS_TABS, ADMIN_USER_ROLE_TABS, ADMIN_STORE_STATUS_TABS, ADMIN_PAYOUT_STATUS_TABS, ADMIN_ORDER_STATUS_TABS, ADMIN_REVIEW_STATUS_TABS, ADMIN_REVIEW_RATING_TABS, ADMIN_BID_STATUS_TABS, ADMIN_CONTACT_STATUS_TABS, ADMIN_NEWSLETTER_STATUS_TABS, ADMIN_EVENT_ENTRY_STATUS_TABS, ADMIN_EVENT_STATUS_TABS, ADMIN_CART_OWNERSHIP_TABS, ADMIN_COUPON_TYPE_TABS, SELLER_PRODUCT_STATUS_TABS, SELLER_AUCTION_STATUS_TABS, SELLER_ORDER_STATUS_TABS, SELLER_OFFER_STATUS_TABS, SELLER_BID_STATUS_TABS, } from "./features/admin/constants/filter-tabs";
|
|
5493
5494
|
// Grouped listings feature schemas
|
|
@@ -5561,6 +5562,7 @@ export { SORT_DIR, sortBy } from "./constants/sort";
|
|
|
5561
5562
|
export { TABLE_KEYS, VIEW_MODE } from "./constants/table-keys";
|
|
5562
5563
|
// ── Sieve query builder ───────────────────────────────────────────────────────
|
|
5563
5564
|
export { SIEVE_OP, SIEVE_PIPE_OPS, sieveFilter, sieveMultiEq, expandSieveParam, sieveAnd, } from "./utils/sieve-builder";
|
|
5565
|
+
export { buildSearchTokens, tokenizeQuery } from "./utils/search-tokens";
|
|
5564
5566
|
// [CLIENT-ONLY] — Admin panel components for action/nav permission management.
|
|
5565
5567
|
export { ActionPermissionsManager } from "./features/site-settings/components/ActionPermissionsManager";
|
|
5566
5568
|
export { NavPermissionsManager } from "./features/site-settings/components/NavPermissionsManager";
|
|
@@ -1,18 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
label: string;
|
|
4
|
-
fullName: string;
|
|
5
|
-
phone: string;
|
|
6
|
-
addressLine1: string;
|
|
7
|
-
addressLine2?: string;
|
|
8
|
-
landmark?: string;
|
|
9
|
-
city: string;
|
|
10
|
-
state: string;
|
|
11
|
-
postalCode: string;
|
|
12
|
-
country: string;
|
|
13
|
-
isDefault: boolean;
|
|
14
|
-
createdAt: Date;
|
|
15
|
-
updatedAt: Date;
|
|
16
|
-
userId: string;
|
|
17
|
-
}
|
|
18
|
-
export declare const addressesSeedData: AddressSeedData[];
|
|
1
|
+
import type { AddressDocument } from "../features/addresses/schemas/firestore";
|
|
2
|
+
export declare const addressesSeedData: AddressDocument[];
|