@mohasinac/appkit 2.8.3 → 2.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/layout/SidebarCollapseToggle.js +2 -0
- package/dist/_internal/shared/listing-types/action-tracker.js +0 -2
- package/dist/client.d.ts +2 -0
- package/dist/client.js +2 -0
- package/dist/core/hooks/useSiteSettings.d.ts +1 -1
- package/dist/core/unit-of-work.js +0 -1
- package/dist/features/account/components/NotificationBell.js +1 -0
- package/dist/features/account/components/UserOffersPanel.js +1 -0
- package/dist/features/account/components/UserSidebar.js +3 -1
- package/dist/features/account/hooks/useAccount.d.ts +2 -2
- package/dist/features/account/hooks/useAddressSelector.d.ts +1 -1
- package/dist/features/account/hooks/useAddresses.d.ts +2 -2
- package/dist/features/account/hooks/useNotifications.d.ts +1 -1
- package/dist/features/account/hooks/useProfile.d.ts +1 -1
- package/dist/features/account/hooks/usePublicProfile.d.ts +2 -2
- package/dist/features/admin/components/AdminAllEventEntriesView.js +5 -3
- package/dist/features/admin/components/AdminBidsView.js +6 -4
- package/dist/features/admin/components/AdminBlogView.js +6 -4
- package/dist/features/admin/components/AdminBrandsView.js +8 -6
- package/dist/features/admin/components/AdminBundlesView.js +10 -8
- package/dist/features/admin/components/AdminCarouselEditorView.js +3 -1
- package/dist/features/admin/components/AdminCartsView.js +6 -4
- package/dist/features/admin/components/AdminCategoriesView.js +7 -5
- package/dist/features/admin/components/AdminClassifiedView.js +4 -3
- package/dist/features/admin/components/AdminContactView.js +6 -4
- package/dist/features/admin/components/AdminCouponsView.js +6 -4
- package/dist/features/admin/components/AdminDigitalCodesView.js +4 -3
- package/dist/features/admin/components/AdminFaqsView.js +5 -3
- package/dist/features/admin/components/AdminFeaturesView.js +5 -4
- package/dist/features/admin/components/AdminGroupedListingsView.js +4 -3
- package/dist/features/admin/components/AdminHistoryView.js +4 -3
- package/dist/features/admin/components/AdminLiveView.js +4 -3
- package/dist/features/admin/components/AdminNewsletterView.js +5 -3
- package/dist/features/admin/components/AdminNotificationsView.js +6 -4
- package/dist/features/admin/components/AdminOrdersView.js +6 -4
- package/dist/features/admin/components/AdminPayoutsView.js +7 -5
- package/dist/features/admin/components/AdminPrizeDrawsView.js +6 -4
- package/dist/features/admin/components/AdminProductsView.js +7 -5
- package/dist/features/admin/components/AdminReturnRequestsView.js +4 -3
- package/dist/features/admin/components/AdminReviewsView.js +8 -6
- package/dist/features/admin/components/AdminScammersView.js +8 -6
- package/dist/features/admin/components/AdminSessionsView.js +6 -4
- package/dist/features/admin/components/AdminSidebar.js +3 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +3 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +2 -1
- package/dist/features/admin/components/AdminStoresView.js +6 -4
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +6 -5
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +0 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +8 -6
- package/dist/features/admin/components/AdminTeamView.js +6 -4
- package/dist/features/admin/components/AdminUsersView.js +6 -4
- package/dist/features/admin/components/AdminWishlistsView.js +4 -3
- package/dist/features/admin/components/DashboardStats.js +5 -1
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +3 -1
- package/dist/features/admin/components/analytics/AdminStatCard.js +5 -1
- package/dist/features/admin/constants/filter-tabs.d.ts +1 -1
- package/dist/features/admin/constants/filter-tabs.js +0 -11
- package/dist/features/admin/hooks/useAdmin.d.ts +1 -1
- package/dist/features/admin/hooks/useAdminSectionsListing.d.ts +1 -1
- package/dist/features/admin/hooks/useChat.d.ts +1 -1
- package/dist/features/admin/hooks/useChat.js +1 -0
- package/dist/features/admin/types/index.d.ts +1 -1
- package/dist/features/auctions/actions/bid-actions.js +4 -2
- package/dist/features/auctions/components/AuctionBidsTable.js +5 -1
- package/dist/features/auctions/components/AuctionsListView.js +7 -6
- package/dist/features/auctions/hooks/useAuctions.d.ts +8 -8
- package/dist/features/auth/hooks/useAuth.d.ts +2 -2
- package/dist/features/auth/hooks/useAuth.js +1 -0
- package/dist/features/blog/actions/blog-actions.js +3 -2
- package/dist/features/blog/components/BlogFeaturedCard.js +3 -1
- package/dist/features/blog/components/BlogListView.js +5 -1
- package/dist/features/blog/components/BlogPostView.js +3 -1
- package/dist/features/cart/components/CartDrawer.js +3 -1
- package/dist/features/cart/hooks/useCart.d.ts +1 -1
- package/dist/features/cart/hooks/useCartQuery.d.ts +1 -1
- package/dist/features/cart/hooks/useCheckoutReadQueries.d.ts +2 -2
- package/dist/features/cart/hooks/useOrder.d.ts +2 -2
- package/dist/features/categories/components/BrandDetailPageView.js +15 -9
- package/dist/features/categories/components/CategoriesIndexListing.js +1 -1
- package/dist/features/categories/components/CategoriesIndexPageView.js +5 -4
- package/dist/features/categories/components/CategoryBundlesListing.js +5 -4
- package/dist/features/categories/components/CategoryDetailPageView.js +15 -11
- package/dist/features/categories/components/CategoryFilters.d.ts +12 -12
- package/dist/features/categories/components/CategoryFilters.js +13 -12
- package/dist/features/categories/components/CategoryGrid.js +5 -1
- package/dist/features/categories/components/CategoryTableColumns.js +6 -2
- package/dist/features/categories/components/CategoryTree.d.ts +1 -1
- package/dist/features/categories/components/CategoryTree.js +4 -2
- package/dist/features/categories/components/ConcernCard.js +3 -1
- package/dist/features/categories/hooks/useCategories.d.ts +3 -3
- package/dist/features/categories/hooks/useCategorySelector.d.ts +3 -3
- package/dist/features/categories/hooks/useCategoryTree.d.ts +1 -1
- package/dist/features/categories/schemas/firestore.d.ts +2 -2
- package/dist/features/checkout/actions/checkout-actions.d.ts +1 -1
- package/dist/features/checkout/actions/checkout-actions.js +1 -1
- package/dist/features/checkout/hooks/useCheckoutApi.d.ts +2 -2
- package/dist/features/classified/components/ClassifiedListView.js +6 -5
- package/dist/features/collections/components/CollectionCard.js +3 -1
- package/dist/features/collections/hooks/useCollections.d.ts +2 -2
- package/dist/features/cron/jobs/auction-expiry.job.d.ts +2 -2
- package/dist/features/cron/jobs/auction-expiry.job.js +2 -1
- package/dist/features/cron/jobs/preorder-reminder.job.d.ts +1 -1
- package/dist/features/cron/jobs/preorder-reminder.job.js +2 -1
- package/dist/features/digital-codes/components/DigitalCodesListView.js +4 -3
- package/dist/features/events/actions/event-actions.js +6 -4
- package/dist/features/events/components/AdminEventEditorView.js +1 -1
- package/dist/features/events/components/AdminEventsView.js +7 -5
- package/dist/features/events/components/EventCard.js +3 -1
- package/dist/features/events/components/EventFilters.d.ts +4 -4
- package/dist/features/events/components/EventFilters.js +2 -2
- package/dist/features/events/components/EventRafflesSection.js +4 -2
- package/dist/features/events/hooks/useEvent.d.ts +3 -3
- package/dist/features/events/hooks/useEvents.d.ts +1 -1
- package/dist/features/faq/actions/faq-actions.js +4 -2
- package/dist/features/faq/components/FAQPageContent.js +2 -1
- package/dist/features/faq/hooks/useFAQs.d.ts +1 -1
- package/dist/features/faq/hooks/useFaqList.d.ts +15 -15
- package/dist/features/forms/Slider.js +3 -1
- package/dist/features/history/hooks/useHistory.js +1 -0
- package/dist/features/homepage/components/AdSlot.js +6 -2
- package/dist/features/homepage/components/AdvertisementBanner.js +3 -1
- package/dist/features/homepage/components/BeforeAfterCard.js +5 -1
- package/dist/features/homepage/components/CustomCardsSection.js +5 -1
- package/dist/features/homepage/components/HowItWorksSection.js +3 -1
- package/dist/features/homepage/components/MarketplaceHomepageView.js +4 -2
- package/dist/features/homepage/components/NewsletterBanner.js +6 -2
- package/dist/features/homepage/components/SecurityHighlightsSection.js +3 -1
- package/dist/features/homepage/components/StatsCounterSection.js +3 -1
- package/dist/features/homepage/components/TrustFeaturesSection.js +3 -1
- package/dist/features/homepage/hooks/useBlogArticles.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedAuctions.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedPreOrders.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedProducts.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedStores.d.ts +1 -1
- package/dist/features/homepage/hooks/useHeroCarousel.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageEvents.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageReviews.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageSections.d.ts +1 -1
- package/dist/features/homepage/hooks/useTopBrands.d.ts +1 -1
- package/dist/features/homepage/hooks/useTopCategories.d.ts +1 -1
- package/dist/features/layout/AppLayoutShell.js +3 -1
- package/dist/features/layout/BottomActions.js +0 -27
- package/dist/features/layout/BottomActionsContext.d.ts +0 -36
- package/dist/features/layout/BottomActionsContext.js +1 -39
- package/dist/features/layout/BottomNavbar.js +1 -1
- package/dist/features/live/components/LiveItemsListView.js +6 -5
- package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +1 -1
- package/dist/features/media/MediaLightbox.js +9 -3
- package/dist/features/media/modals/ImageEditor.js +6 -2
- package/dist/features/media/upload/MediaUploadField.js +1 -1
- package/dist/features/messages/hooks/useConversation.js +2 -0
- package/dist/features/messages/hooks/useConversations.js +1 -0
- package/dist/features/orders/components/OrdersList.js +3 -1
- package/dist/features/orders/hooks/useOrders.d.ts +2 -2
- package/dist/features/payments/hooks/usePayments.d.ts +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +1 -1
- package/dist/features/pre-orders/components/PreOrdersListView.js +5 -4
- package/dist/features/pre-orders/hooks/usePreOrders.d.ts +2 -2
- package/dist/features/products/actions/product-actions.js +17 -15
- package/dist/features/products/columns/index.d.ts +1 -1
- package/dist/features/products/columns/index.js +1 -1
- package/dist/features/products/components/CompareOverlay.js +5 -1
- package/dist/features/products/components/FeatureBadge.js +3 -1
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +1 -1
- package/dist/features/products/components/PrizeDrawCollage.js +0 -14
- package/dist/features/products/components/PrizeDrawsListingView.js +5 -4
- package/dist/features/products/components/PrizeDrawsSection.js +4 -2
- package/dist/features/products/components/ProductGrid.js +3 -1
- package/dist/features/products/constants/sieve.d.ts +2 -2
- package/dist/features/products/constants/sieve.js +2 -2
- package/dist/features/products/hooks/useProductDetail.d.ts +1 -1
- package/dist/features/products/hooks/useRelatedProducts.d.ts +1 -1
- package/dist/features/products/hooks/useRelatedProducts.js +5 -4
- package/dist/features/promotions/hooks/usePromotions.d.ts +2 -2
- package/dist/features/reviews/actions/review-actions.js +2 -1
- package/dist/features/reviews/components/ReviewDetailShell.js +8 -2
- package/dist/features/reviews/components/ReviewModal.js +5 -1
- package/dist/features/reviews/components/ReviewSummary.js +3 -1
- package/dist/features/reviews/components/ReviewsIndexPageView.js +7 -6
- package/dist/features/reviews/components/ReviewsList.js +5 -1
- package/dist/features/reviews/hooks/useReviews.d.ts +2 -2
- package/dist/features/scams/actions/scam-actions.js +3 -2
- package/dist/features/scams/components/ScamRegistryView.js +5 -4
- package/dist/features/search/actions/search-actions.js +7 -6
- package/dist/features/search/components/Search.js +3 -1
- package/dist/features/search/hooks/useSearch.d.ts +2 -2
- package/dist/features/seller/components/CouponInlineSelect.js +2 -1
- package/dist/features/seller/components/PhysicalLocationModal.js +1 -1
- package/dist/features/seller/components/SellerAddressesView.js +2 -1
- package/dist/features/seller/components/SellerAuctionsView.js +7 -5
- package/dist/features/seller/components/SellerBidsView.js +8 -4
- package/dist/features/seller/components/SellerBundlesView.js +7 -6
- package/dist/features/seller/components/SellerClassifiedView.js +6 -5
- package/dist/features/seller/components/SellerCouponEditorView.js +3 -1
- package/dist/features/seller/components/SellerCouponsView.js +6 -4
- package/dist/features/seller/components/SellerDigitalCodesView.js +5 -4
- package/dist/features/seller/components/SellerGroupedListingsView.js +5 -4
- package/dist/features/seller/components/SellerLiveView.js +6 -5
- package/dist/features/seller/components/SellerOffersPanel.js +1 -0
- package/dist/features/seller/components/SellerOffersView.js +6 -4
- package/dist/features/seller/components/SellerOrdersView.js +5 -3
- package/dist/features/seller/components/SellerPayoutMethodsView.js +4 -2
- package/dist/features/seller/components/SellerPayoutsView.js +6 -4
- package/dist/features/seller/components/SellerPreOrdersView.js +6 -4
- package/dist/features/seller/components/SellerPrizeDrawsView.js +6 -4
- package/dist/features/seller/components/SellerProductsView.js +14 -8
- package/dist/features/seller/components/SellerReviewsView.js +1 -0
- package/dist/features/seller/components/SellerShippingConfigsView.js +4 -2
- package/dist/features/seller/components/SellerSidebar.js +12 -4
- package/dist/features/seller/components/SellerStoreCategoriesView.js +5 -3
- package/dist/features/seller/components/SellerTemplatesView.js +5 -3
- package/dist/features/seller/components/SublistingInlineSelect.js +2 -1
- package/dist/features/seller/hooks/useSellerPayouts.d.ts +3 -3
- package/dist/features/seller/hooks/useSellerStore.d.ts +6 -6
- package/dist/features/seller/hooks/useSellerStorefront.d.ts +2 -2
- package/dist/features/shell/FormShell.js +10 -2
- package/dist/features/shell/QuickFormDrawer.js +5 -2
- package/dist/features/stores/actions/store-query-actions.js +3 -2
- package/dist/features/stores/components/StoreAuctionsPageView.js +4 -2
- package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
- package/dist/features/stores/components/StoreDetailLayoutView.js +7 -6
- package/dist/features/stores/components/StoreHeader.js +5 -1
- package/dist/features/stores/components/StorePreOrdersPageView.js +4 -2
- package/dist/features/stores/components/StorePrizeDrawsPageView.js +4 -2
- package/dist/features/stores/components/StoreProductsPageView.js +2 -1
- package/dist/features/stores/components/StoreProductsView.js +5 -4
- package/dist/features/stores/components/StoresIndexListing.js +4 -3
- package/dist/features/stores/hooks/useStoreAddressSelector.d.ts +1 -1
- package/dist/features/stores/hooks/useStores.d.ts +6 -6
- package/dist/features/wishlist/components/WishlistPage.js +3 -1
- package/dist/features/wishlist/components/WishlistView.js +4 -3
- package/dist/features/wishlist/hooks/useUserWishlist.d.ts +15 -15
- package/dist/features/wishlist/hooks/useWishlist.d.ts +1 -1
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/providers/db-firebase/admin.js +0 -1
- package/dist/ui/DataTable.js +6 -2
- package/dist/ui/components/AvatarDisplay.js +3 -1
- package/dist/ui/components/BackgroundRenderer.js +4 -2
- package/dist/ui/components/Card.js +6 -2
- package/dist/ui/components/ImageGallery.js +3 -1
- package/dist/ui/components/ImageLightbox.js +3 -1
- package/dist/ui/components/PasswordStrengthIndicator.js +3 -1
- package/dist/ui/components/Progress.js +6 -2
- package/dist/ui/components/RowActionMenu.js +3 -1
- package/dist/ui/components/SiteLogo.js +7 -1
- package/dist/ui/components/Skeleton.js +3 -1
- package/dist/ui/components/Slider.js +3 -1
- package/dist/ui/components/TabStrip.js +3 -1
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
2
3
|
import { productRepository } from "../../../repositories";
|
|
3
4
|
import { Container, Heading, Main, Section } from "../../../ui";
|
|
4
5
|
import { AdSlot } from "../../homepage/components/AdSlot";
|
|
@@ -16,18 +17,18 @@ function buildClassifiedFilters(params) {
|
|
|
16
17
|
const minPrice = sp(params, "minPrice");
|
|
17
18
|
const maxPrice = sp(params, "maxPrice");
|
|
18
19
|
if (minPrice)
|
|
19
|
-
parts.push(
|
|
20
|
+
parts.push(sieveFilter("price", SIEVE_OP.GTE, minPrice));
|
|
20
21
|
if (maxPrice)
|
|
21
|
-
parts.push(
|
|
22
|
+
parts.push(sieveFilter("price", SIEVE_OP.LTE, maxPrice));
|
|
22
23
|
const city = sp(params, "city");
|
|
23
24
|
if (city)
|
|
24
|
-
parts.push(
|
|
25
|
+
parts.push(sieveFilter("classifiedCity", SIEVE_OP.EQ, city));
|
|
25
26
|
const negotiable = sp(params, "negotiable");
|
|
26
27
|
if (negotiable === "true")
|
|
27
|
-
parts.push(
|
|
28
|
+
parts.push(sieveFilter("classifiedNegotiable", SIEVE_OP.EQ, "true"));
|
|
28
29
|
const acceptsShipping = sp(params, "acceptsShipping");
|
|
29
30
|
if (acceptsShipping === "true")
|
|
30
|
-
parts.push(
|
|
31
|
+
parts.push(sieveFilter("classifiedAcceptsShipping", SIEVE_OP.EQ, "true"));
|
|
31
32
|
return parts.join(",");
|
|
32
33
|
}
|
|
33
34
|
export async function ClassifiedListView({ searchParams = {} }) {
|
|
@@ -3,7 +3,9 @@ import { Div, Heading, Text, TextLink } from "../../../ui";
|
|
|
3
3
|
import { LAYOUT } from "../../../tokens";
|
|
4
4
|
const CLS_PLACEHOLDER = "w-full bg-gradient-to-br from-indigo-100 to-purple-100 dark:from-indigo-900/30 dark:to-purple-900/30";
|
|
5
5
|
export function CollectionCard({ collection, href }) {
|
|
6
|
-
return (_jsxs(TextLink, { href: href, className: "group relative block overflow-hidden rounded-xl bg-gray-100 dark:bg-slate-800 transition-shadow hover:shadow-lg", children: [collection.image ? (_jsx(Div, { role: "img", "aria-label": collection.title, className: `${LAYOUT.cardHeight.md} w-full bg-cover bg-center transition-transform duration-300 group-hover:scale-105`,
|
|
6
|
+
return (_jsxs(TextLink, { href: href, className: "group relative block overflow-hidden rounded-xl bg-gray-100 dark:bg-slate-800 transition-shadow hover:shadow-lg", children: [collection.image ? (_jsx(Div, { role: "img", "aria-label": collection.title, className: `${LAYOUT.cardHeight.md} w-full bg-cover bg-center transition-transform duration-300 group-hover:scale-105`,
|
|
7
|
+
// audit-inline-style-ok: dynamic image URL
|
|
8
|
+
style: { backgroundImage: `url(${collection.image})` } })) : (_jsx(Div, { className: `${LAYOUT.cardHeight.md} ${CLS_PLACEHOLDER}` })), _jsxs(Div, { surface: "default", padding: "sm", children: [_jsx(Heading, { level: 3, className: "font-semibold text-gray-900 dark:text-zinc-100", children: collection.title }), collection.subtitle && (_jsx(Text, { className: "mt-1 text-sm text-gray-500 dark:text-zinc-400", children: collection.subtitle })), collection.productCount !== undefined && (_jsxs(Text, { className: "mt-2 text-xs text-gray-400 dark:text-zinc-500", children: [collection.productCount, " ", collection.productCount === 1 ? "item" : "items"] }))] })] }));
|
|
7
9
|
}
|
|
8
10
|
export function CollectionGrid({ collections, getHref }) {
|
|
9
11
|
return (_jsx(Div, { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: collections.map((c) => (_jsx(CollectionCard, { collection: c, href: getHref(c.slug) }, c.slug))) }));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CollectionItem, CollectionListItem } from "../types";
|
|
2
2
|
export declare function useCollections(opts?: {
|
|
3
3
|
endpoint?: string;
|
|
4
|
-
}): import("@tanstack/react-query").UseQueryResult<
|
|
4
|
+
}): import("@tanstack/react-query").UseQueryResult<CollectionListItem[], Error>;
|
|
5
5
|
export declare function useCollection(slug: string | undefined, opts?: {
|
|
6
6
|
endpoint?: string;
|
|
7
|
-
}): import("@tanstack/react-query").UseQueryResult<
|
|
7
|
+
}): import("@tanstack/react-query").UseQueryResult<CollectionItem | null, Error>;
|
|
@@ -3,7 +3,7 @@ import type { IRepository } from "../../../contracts";
|
|
|
3
3
|
* Built-in job: Close live auctions whose `endTime` has passed.
|
|
4
4
|
*
|
|
5
5
|
* Run interval: every 5 minutes (recommended).
|
|
6
|
-
* Requires an
|
|
6
|
+
* Requires an sieveFilter("IRepository", SIEVE_OP.LT, "AuctionDocument>") injected at registration time.
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* ```ts
|
|
@@ -23,5 +23,5 @@ interface AuctionDocument {
|
|
|
23
23
|
highestBidAmount?: number;
|
|
24
24
|
closedAt?: string;
|
|
25
25
|
}
|
|
26
|
-
export declare function createAuctionExpiryJob(auctionRepo: IRepository<AuctionDocument>): import("
|
|
26
|
+
export declare function createAuctionExpiryJob(auctionRepo: IRepository<AuctionDocument>): import("@mohasinac/appkit").CronJobDefinition;
|
|
27
27
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
|
|
1
2
|
import { createCronJob } from "../registry";
|
|
2
3
|
export function createAuctionExpiryJob(auctionRepo) {
|
|
3
4
|
return createCronJob({
|
|
@@ -9,7 +10,7 @@ export function createAuctionExpiryJob(auctionRepo) {
|
|
|
9
10
|
timeoutSeconds: 60,
|
|
10
11
|
}, async (ctx) => {
|
|
11
12
|
const result = await auctionRepo.findAll({
|
|
12
|
-
filters:
|
|
13
|
+
filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "live"), sieveFilter("endTime", SIEVE_OP.LTE, ctx.scheduleTime)),
|
|
13
14
|
perPage: 500,
|
|
14
15
|
});
|
|
15
16
|
let processed = 0;
|
|
@@ -10,5 +10,5 @@ interface PreOrderDocument {
|
|
|
10
10
|
status: string;
|
|
11
11
|
expectedShippingDate?: string;
|
|
12
12
|
}
|
|
13
|
-
export declare function createPreOrderReminderJob(preOrderRepo: IRepository<PreOrderDocument>): import("
|
|
13
|
+
export declare function createPreOrderReminderJob(preOrderRepo: IRepository<PreOrderDocument>): import("@mohasinac/appkit").CronJobDefinition;
|
|
14
14
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
|
|
1
2
|
import { createCronJob } from "../registry";
|
|
2
3
|
export function createPreOrderReminderJob(preOrderRepo) {
|
|
3
4
|
const sevenDaysFromNow = () => {
|
|
@@ -15,7 +16,7 @@ export function createPreOrderReminderJob(preOrderRepo) {
|
|
|
15
16
|
}, async () => {
|
|
16
17
|
const cutoff = sevenDaysFromNow();
|
|
17
18
|
const result = await preOrderRepo.findAll({
|
|
18
|
-
filters:
|
|
19
|
+
filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "confirmed"), sieveFilter("expectedShippingDate", SIEVE_OP.LTE, cutoff)),
|
|
19
20
|
perPage: 500,
|
|
20
21
|
});
|
|
21
22
|
let processed = 0;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
2
3
|
import { productRepository } from "../../../repositories";
|
|
3
4
|
import { Container, Heading, Main, Section } from "../../../ui";
|
|
4
5
|
import { AdSlot } from "../../homepage/components/AdSlot";
|
|
@@ -16,12 +17,12 @@ function buildDigitalCodeFilters(params) {
|
|
|
16
17
|
const minPrice = sp(params, "minPrice");
|
|
17
18
|
const maxPrice = sp(params, "maxPrice");
|
|
18
19
|
if (minPrice)
|
|
19
|
-
parts.push(
|
|
20
|
+
parts.push(sieveFilter("price", SIEVE_OP.GTE, minPrice));
|
|
20
21
|
if (maxPrice)
|
|
21
|
-
parts.push(
|
|
22
|
+
parts.push(sieveFilter("price", SIEVE_OP.LTE, maxPrice));
|
|
22
23
|
const deliveryMethod = sp(params, "deliveryMethod");
|
|
23
24
|
if (deliveryMethod)
|
|
24
|
-
parts.push(
|
|
25
|
+
parts.push(sieveFilter("digitalCodeDelivery", SIEVE_OP.EQ, deliveryMethod));
|
|
25
26
|
return parts.join(",");
|
|
26
27
|
}
|
|
27
28
|
export async function DigitalCodesListView({ searchParams = {} }) {
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Business logic for event CRUD, status changes, entries, and public access.
|
|
5
5
|
* Auth, rate-limiting, and input validation are handled by the calling server action.
|
|
6
6
|
*/
|
|
7
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
8
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
7
9
|
import { serverLogger } from "../../../monitoring";
|
|
8
10
|
import { eventRepository } from "../repository/events.repository";
|
|
9
11
|
import { eventEntryRepository } from "../repository/event-entry.repository";
|
|
@@ -108,13 +110,13 @@ export async function listPublicEvents(params) {
|
|
|
108
110
|
if (!filters) {
|
|
109
111
|
const parts = [];
|
|
110
112
|
if (sp.has("status"))
|
|
111
|
-
parts.push(
|
|
113
|
+
parts.push(sieveFilter("status", SIEVE_OP.EQ, sp.get("status")));
|
|
112
114
|
if (sp.has("type"))
|
|
113
|
-
parts.push(
|
|
115
|
+
parts.push(sieveFilter("type", SIEVE_OP.EQ, sp.get("type")));
|
|
114
116
|
if (sp.has("types")) {
|
|
115
117
|
const types = sp.get("types").split(",");
|
|
116
118
|
if (types.length === 1)
|
|
117
|
-
parts.push(
|
|
119
|
+
parts.push(sieveFilter("type", SIEVE_OP.EQ, types[0]));
|
|
118
120
|
}
|
|
119
121
|
if (parts.length)
|
|
120
122
|
filters = parts.join(",");
|
|
@@ -157,7 +159,7 @@ export async function adminGetEventById(id) {
|
|
|
157
159
|
}
|
|
158
160
|
export async function adminGetEventEntries(eventId, params) {
|
|
159
161
|
const result = await eventEntryRepository.listForEvent(eventId, {
|
|
160
|
-
sorts: "
|
|
162
|
+
sorts: sortBy("createdAt", "DESC"),
|
|
161
163
|
page: params?.page ?? 1,
|
|
162
164
|
pageSize: params?.pageSize ?? 50,
|
|
163
165
|
});
|
|
@@ -52,7 +52,7 @@ const FORM_FIELD_TYPE_OPTIONS = [
|
|
|
52
52
|
{ label: "Checkbox", value: "checkbox" },
|
|
53
53
|
{ label: "Radio", value: "radio" },
|
|
54
54
|
{ label: "Date", value: "date" },
|
|
55
|
-
{ label: "Rating (1–5)", value: "rating" },
|
|
55
|
+
{ label: "Rating (1–5)", value: "rating" }, // audit-sieve-views-ok — form field type, not sort key
|
|
56
56
|
{ label: "File upload", value: "file" },
|
|
57
57
|
];
|
|
58
58
|
const FIELD_TYPES_WITH_OPTIONS = ["select", "multiselect", "radio", "checkbox"];
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
4
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
5
|
import React from "react";
|
|
4
6
|
import { FilterChipGroup, ListingLayout } from "../../../ui";
|
|
5
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
@@ -29,13 +31,13 @@ export function AdminEventsView({ children, ...props }) {
|
|
|
29
31
|
searchPlaceholder: "Search events by title or type",
|
|
30
32
|
emptyLabel: "No events found",
|
|
31
33
|
filterKeys: ["status", "type"],
|
|
32
|
-
defaultSort: "
|
|
34
|
+
defaultSort: sortBy("startsAt", "DESC"),
|
|
33
35
|
queryKey: ["admin", "events", "listing"],
|
|
34
36
|
endpoint: ADMIN_ENDPOINTS.EVENTS,
|
|
35
37
|
sortOptions: [
|
|
36
|
-
{ value: "
|
|
38
|
+
{ value: sortBy("startsAt", "DESC"), label: "Starting soonest" },
|
|
37
39
|
{ value: "startsAt", label: "Starting latest" },
|
|
38
|
-
{ value: "
|
|
40
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
39
41
|
{ value: "title", label: "Title A–Z" },
|
|
40
42
|
],
|
|
41
43
|
mapRows: (response) => toRecordArray(response.items).map((item, index) => ({
|
|
@@ -51,9 +53,9 @@ export function AdminEventsView({ children, ...props }) {
|
|
|
51
53
|
buildFilters: (state) => {
|
|
52
54
|
const parts = [];
|
|
53
55
|
if (state.status && state.status !== "All")
|
|
54
|
-
parts.push(
|
|
56
|
+
parts.push(sieveFilter("status", SIEVE_OP.EQ, state.status));
|
|
55
57
|
if (state.type && state.type !== "All")
|
|
56
|
-
parts.push(
|
|
58
|
+
parts.push(sieveFilter("type", SIEVE_OP.EQ, state.type));
|
|
57
59
|
return parts.join(",") || undefined;
|
|
58
60
|
},
|
|
59
61
|
primaryAction: {
|
|
@@ -31,6 +31,8 @@ export function EventCard({ event, labels = {}, onParticipate, className = "", s
|
|
|
31
31
|
const msLeft = endsAt.getTime() - now.getTime();
|
|
32
32
|
const daysLeft = Math.max(0, Math.ceil(msLeft / (1000 * 60 * 60 * 24)));
|
|
33
33
|
const detailHref = String(ROUTES.PUBLIC.EVENT_DETAIL(event.slug ?? event.id));
|
|
34
|
-
return (_jsxs(Article, { className: `group relative flex h-full ${LAYOUT.cardHeight.event} flex-col overflow-hidden rounded-xl border bg-white shadow-sm transition-shadow hover:shadow-md dark:bg-slate-900 ${isSelected ? "border-primary outline outline-2 outline-primary" : "border-zinc-200 dark:border-slate-700"} ${className}`, onMouseDown: onSelect && !isSelected ? longPress.onMouseDown : undefined, onMouseUp: onSelect && !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: onSelect && !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: onSelect && !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: onSelect && !isSelected ? longPress.onTouchEnd : undefined, children: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (e) => { e.preventDefault(); onSelect(event.id, !isSelected); }, label: isSelected ? "Deselect event" : "Select event", position: "top-2 left-2", className: selectable || isSelected ? "opacity-100" : "opacity-0 group-hover:opacity-100 transition-opacity" })), _jsx(Link, { href: detailHref, className: "block flex-shrink-0", children: event.coverImageUrl ? (_jsx(Div, { className: `aspect-video ${__O.hidden}`, children: _jsx(Div, { role: "img", "aria-label": safeTitle, className: "h-full w-full bg-cover bg-center transition-transform duration-300 group-hover:scale-105",
|
|
34
|
+
return (_jsxs(Article, { className: `group relative flex h-full ${LAYOUT.cardHeight.event} flex-col overflow-hidden rounded-xl border bg-white shadow-sm transition-shadow hover:shadow-md dark:bg-slate-900 ${isSelected ? "border-primary outline outline-2 outline-primary" : "border-zinc-200 dark:border-slate-700"} ${className}`, onMouseDown: onSelect && !isSelected ? longPress.onMouseDown : undefined, onMouseUp: onSelect && !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: onSelect && !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: onSelect && !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: onSelect && !isSelected ? longPress.onTouchEnd : undefined, children: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (e) => { e.preventDefault(); onSelect(event.id, !isSelected); }, label: isSelected ? "Deselect event" : "Select event", position: "top-2 left-2", className: selectable || isSelected ? "opacity-100" : "opacity-0 group-hover:opacity-100 transition-opacity" })), _jsx(Link, { href: detailHref, className: "block flex-shrink-0", children: event.coverImageUrl ? (_jsx(Div, { className: `aspect-video ${__O.hidden}`, children: _jsx(Div, { role: "img", "aria-label": safeTitle, className: "h-full w-full bg-cover bg-center transition-transform duration-300 group-hover:scale-105",
|
|
35
|
+
// audit-inline-style-ok: dynamic image URL
|
|
36
|
+
style: { backgroundImage: `url(${event.coverImageUrl})` } }) })) : (_jsx(Div, { className: "aspect-video bg-gradient-to-br from-zinc-100 to-zinc-200 dark:from-slate-800 dark:to-slate-700 flex items-center justify-center", children: _jsx(Span, { className: "text-5xl opacity-40", "aria-hidden": "true", children: TYPE_ICONS[event.type] }) })) }), _jsxs(Div, { className: `flex flex-1 flex-col ${__P.p4}`, children: [_jsxs(Div, { className: "flex items-start justify-between gap-2 mb-2", children: [_jsx(Span, { size: "lg", "aria-hidden": "true", children: TYPE_ICONS[event.type] }), _jsx(EventStatusBadge, { status: event.status })] }), _jsx(Link, { href: detailHref, className: "block", children: _jsx(Heading, { level: 3, className: "font-semibold text-gray-900 dark:text-zinc-100 text-base leading-snug mb-1 group-hover:text-primary transition-colors", children: safeTitle }) }), _jsx(RichText, { html: normalizeRichTextHtml(event.description ?? ""), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: `mb-3 ${THEME_CONSTANTS.utilities.textClamp3} text-sm text-zinc-600 dark:text-zinc-400` }), _jsxs(Div, { className: "mb-3 mt-auto flex items-center justify-between text-xs text-zinc-500 dark:text-zinc-400", children: [event.status === EVENT_FIELDS.STATUS_VALUES.ACTIVE &&
|
|
35
37
|
daysLeft > 0 && _jsxs(Span, { children: ["\u23F1 ", daysLeft, "d remaining"] }), _jsxs(Span, { children: ["\uD83D\uDC65 ", event.stats.totalEntries, " ", labels.entries ?? "entries"] })] }), event.status === EVENT_FIELDS.STATUS_VALUES.ACTIVE && onParticipate ? (_jsx(Button, { type: "button", onClick: () => onParticipate(event), className: "w-full rounded-lg bg-primary py-2 text-sm font-medium text-white transition-colors hover:bg-primary-600", children: labels.participate ?? "Participate" })) : (_jsxs(TextLink, { href: detailHref, className: "inline-flex w-full items-center justify-center gap-1.5 rounded-lg border border-zinc-300 px-3 py-2 text-sm font-medium text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-slate-600 dark:text-zinc-200 dark:hover:bg-slate-800", children: [labels.viewDetails ?? "View details", " \u2192"] }))] })] }));
|
|
36
38
|
}
|
|
@@ -24,7 +24,7 @@ export declare const EVENT_ADMIN_SORT_OPTIONS: readonly [{
|
|
|
24
24
|
readonly value: string;
|
|
25
25
|
readonly label: "Ends Soonest";
|
|
26
26
|
}, {
|
|
27
|
-
readonly value:
|
|
27
|
+
readonly value: string;
|
|
28
28
|
readonly label: "Most Entries";
|
|
29
29
|
}, {
|
|
30
30
|
readonly value: string;
|
|
@@ -49,7 +49,7 @@ export declare const EVENT_SELLER_SORT_OPTIONS: readonly [{
|
|
|
49
49
|
readonly value: string;
|
|
50
50
|
readonly label: "Ends Soonest";
|
|
51
51
|
}, {
|
|
52
|
-
readonly value:
|
|
52
|
+
readonly value: string;
|
|
53
53
|
readonly label: "Most Entries";
|
|
54
54
|
}, {
|
|
55
55
|
readonly value: string;
|
|
@@ -68,7 +68,7 @@ export declare const EVENT_PUBLIC_SORT_OPTIONS: readonly [{
|
|
|
68
68
|
readonly value: string;
|
|
69
69
|
readonly label: "Title Z–A";
|
|
70
70
|
}, {
|
|
71
|
-
readonly value:
|
|
71
|
+
readonly value: string;
|
|
72
72
|
readonly label: "Most Entries";
|
|
73
73
|
}];
|
|
74
74
|
export declare const EVENT_SORT_OPTIONS: readonly [{
|
|
@@ -90,7 +90,7 @@ export declare const EVENT_SORT_OPTIONS: readonly [{
|
|
|
90
90
|
readonly value: string;
|
|
91
91
|
readonly label: "Ends Soonest";
|
|
92
92
|
}, {
|
|
93
|
-
readonly value:
|
|
93
|
+
readonly value: string;
|
|
94
94
|
readonly label: "Most Entries";
|
|
95
95
|
}, {
|
|
96
96
|
readonly value: string;
|
|
@@ -20,7 +20,7 @@ export const EVENT_ADMIN_SORT_OPTIONS = [
|
|
|
20
20
|
{ value: sortBy(EVENT_FIELDS.STARTS_AT, "ASC"), label: "Starts Soonest" },
|
|
21
21
|
{ value: sortBy(EVENT_FIELDS.ENDS_AT), label: "Ends Latest" },
|
|
22
22
|
{ value: sortBy(EVENT_FIELDS.ENDS_AT, "ASC"), label: "Ends Soonest" },
|
|
23
|
-
{ value: "
|
|
23
|
+
{ value: sortBy("stats.totalEntries", "DESC"), label: "Most Entries" },
|
|
24
24
|
{ value: sortBy(EVENT_FIELDS.CREATED_AT), label: "Newest First" },
|
|
25
25
|
];
|
|
26
26
|
export const EVENT_SELLER_SORT_OPTIONS = EVENT_ADMIN_SORT_OPTIONS;
|
|
@@ -29,7 +29,7 @@ export const EVENT_PUBLIC_SORT_OPTIONS = [
|
|
|
29
29
|
{ value: sortBy(EVENT_FIELDS.STARTS_AT), label: "Starts Latest" },
|
|
30
30
|
{ value: sortBy(EVENT_FIELDS.TITLE, "ASC"), label: "Title A–Z" },
|
|
31
31
|
{ value: sortBy(EVENT_FIELDS.TITLE), label: "Title Z–A" },
|
|
32
|
-
{ value: "
|
|
32
|
+
{ value: sortBy("stats.totalEntries", "DESC"), label: "Most Entries" },
|
|
33
33
|
];
|
|
34
34
|
// Backward-compatible alias.
|
|
35
35
|
export const EVENT_SORT_OPTIONS = EVENT_ADMIN_SORT_OPTIONS;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
2
4
|
import Link from "next/link";
|
|
3
5
|
import { Container, Div, Heading, Section, Stack, Text, } from "../../../ui";
|
|
4
6
|
import { ROUTES } from "../../../next";
|
|
@@ -15,8 +17,8 @@ export async function EventRafflesSection({ config, }) {
|
|
|
15
17
|
let events = [];
|
|
16
18
|
try {
|
|
17
19
|
const result = await eventRepository.list({
|
|
18
|
-
filters: "hasRaffle
|
|
19
|
-
sorts: "
|
|
20
|
+
filters: sieveAnd(sieveFilter("hasRaffle", SIEVE_OP.EQ, "true"), sieveFilter("status", SIEVE_OP.EQ, "active")),
|
|
21
|
+
sorts: sortBy("startsAt", "DESC"),
|
|
20
22
|
pageSize: limit,
|
|
21
23
|
});
|
|
22
24
|
events = (result.items ?? []);
|
|
@@ -16,7 +16,7 @@ export declare function useEvent<T extends EventItem = EventItem>(id: string, op
|
|
|
16
16
|
event: T | null;
|
|
17
17
|
isLoading: boolean;
|
|
18
18
|
error: string | null;
|
|
19
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
19
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<EventItem | null, Error>>;
|
|
20
20
|
};
|
|
21
21
|
export declare function useEventEntries(eventId: string, params?: {
|
|
22
22
|
page?: number;
|
|
@@ -30,13 +30,13 @@ export declare function useEventEntries(eventId: string, params?: {
|
|
|
30
30
|
total: number;
|
|
31
31
|
isLoading: boolean;
|
|
32
32
|
error: string | null;
|
|
33
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
33
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<EventEntryListResponse, Error>>;
|
|
34
34
|
};
|
|
35
35
|
export declare function useEventLeaderboard(eventId: string, limit?: number, opts?: {
|
|
36
36
|
enabled?: boolean;
|
|
37
37
|
endpoint?: string;
|
|
38
38
|
}): {
|
|
39
|
-
leaderboard:
|
|
39
|
+
leaderboard: LeaderboardEntry[];
|
|
40
40
|
isLoading: boolean;
|
|
41
41
|
error: string | null;
|
|
42
42
|
};
|
|
@@ -23,6 +23,6 @@ export declare function useEvents<T extends EventItem = EventItem>(params?: Even
|
|
|
23
23
|
hasMore: boolean;
|
|
24
24
|
isLoading: boolean;
|
|
25
25
|
error: string | null;
|
|
26
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
26
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<EventListResponse, Error>>;
|
|
27
27
|
};
|
|
28
28
|
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
import { serverLogger } from "../../../monitoring";
|
|
4
|
+
import { sortBy } from "../../../constants/sort";
|
|
3
5
|
import { faqsRepository } from "../repository/faqs.repository";
|
|
4
6
|
// --- Schemas --------------------------------------------------------------
|
|
5
7
|
const faqBaseSchema = z.object({
|
|
@@ -89,10 +91,10 @@ export async function listFaqs(params) {
|
|
|
89
91
|
export async function listPublicFaqs(category, limit = 20) {
|
|
90
92
|
const filters = ["isActive==true"];
|
|
91
93
|
if (category)
|
|
92
|
-
filters.push(
|
|
94
|
+
filters.push(sieveFilter("category", SIEVE_OP.EQ, category));
|
|
93
95
|
const result = await faqsRepository.list({
|
|
94
96
|
filters: filters.join(","),
|
|
95
|
-
sorts: "
|
|
97
|
+
sorts: [sortBy("priority", "DESC"), sortBy("order", "ASC")].join(","),
|
|
96
98
|
page: 1,
|
|
97
99
|
pageSize: limit,
|
|
98
100
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Div, Heading, Input, SlottedListingView, Text } from "../../../ui";
|
|
4
|
+
import { sortBy } from "../../../constants/sort";
|
|
4
5
|
import { FAQCategorySidebar } from "./FAQCategorySidebar";
|
|
5
6
|
import { FAQSortDropdown } from "./FAQSortDropdown";
|
|
6
7
|
import { FAQAccordion } from "./FAQAccordion";
|
|
@@ -22,7 +23,7 @@ export function FAQPageContent({ initialCategory = "all", categories, routeHelpe
|
|
|
22
23
|
});
|
|
23
24
|
const { faqs: allMatchingFaqs } = useFaqList({
|
|
24
25
|
search: searchValue.trim() || undefined,
|
|
25
|
-
sorts: "
|
|
26
|
+
sorts: [sortBy("priority", "DESC"), sortBy("order", "ASC")].join(","),
|
|
26
27
|
page: 1,
|
|
27
28
|
pageSize: 200,
|
|
28
29
|
});
|
|
@@ -14,7 +14,7 @@ export declare function useFaqList(options?: UseFaqListOptions): {
|
|
|
14
14
|
faqs: import("..").FAQ[];
|
|
15
15
|
total: number;
|
|
16
16
|
categories: readonly string[];
|
|
17
|
-
data:
|
|
17
|
+
data: FAQListResponse;
|
|
18
18
|
error: Error;
|
|
19
19
|
isError: true;
|
|
20
20
|
isPending: false;
|
|
@@ -37,14 +37,14 @@ export declare function useFaqList(options?: UseFaqListOptions): {
|
|
|
37
37
|
isRefetching: boolean;
|
|
38
38
|
isStale: boolean;
|
|
39
39
|
isEnabled: boolean;
|
|
40
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
40
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
|
|
41
41
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
42
|
-
promise: Promise<
|
|
42
|
+
promise: Promise<FAQListResponse>;
|
|
43
43
|
} | {
|
|
44
44
|
faqs: import("..").FAQ[];
|
|
45
45
|
total: number;
|
|
46
46
|
categories: readonly string[];
|
|
47
|
-
data:
|
|
47
|
+
data: FAQListResponse;
|
|
48
48
|
error: null;
|
|
49
49
|
isError: false;
|
|
50
50
|
isPending: false;
|
|
@@ -67,9 +67,9 @@ export declare function useFaqList(options?: UseFaqListOptions): {
|
|
|
67
67
|
isRefetching: boolean;
|
|
68
68
|
isStale: boolean;
|
|
69
69
|
isEnabled: boolean;
|
|
70
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
70
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
|
|
71
71
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
72
|
-
promise: Promise<
|
|
72
|
+
promise: Promise<FAQListResponse>;
|
|
73
73
|
} | {
|
|
74
74
|
faqs: import("..").FAQ[];
|
|
75
75
|
total: number;
|
|
@@ -97,9 +97,9 @@ export declare function useFaqList(options?: UseFaqListOptions): {
|
|
|
97
97
|
isRefetching: boolean;
|
|
98
98
|
isStale: boolean;
|
|
99
99
|
isEnabled: boolean;
|
|
100
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
100
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
|
|
101
101
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
102
|
-
promise: Promise<
|
|
102
|
+
promise: Promise<FAQListResponse>;
|
|
103
103
|
} | {
|
|
104
104
|
faqs: import("..").FAQ[];
|
|
105
105
|
total: number;
|
|
@@ -127,9 +127,9 @@ export declare function useFaqList(options?: UseFaqListOptions): {
|
|
|
127
127
|
isRefetching: boolean;
|
|
128
128
|
isStale: boolean;
|
|
129
129
|
isEnabled: boolean;
|
|
130
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
130
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
|
|
131
131
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
132
|
-
promise: Promise<
|
|
132
|
+
promise: Promise<FAQListResponse>;
|
|
133
133
|
} | {
|
|
134
134
|
faqs: import("..").FAQ[];
|
|
135
135
|
total: number;
|
|
@@ -157,14 +157,14 @@ export declare function useFaqList(options?: UseFaqListOptions): {
|
|
|
157
157
|
isRefetching: boolean;
|
|
158
158
|
isStale: boolean;
|
|
159
159
|
isEnabled: boolean;
|
|
160
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
160
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
|
|
161
161
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
162
|
-
promise: Promise<
|
|
162
|
+
promise: Promise<FAQListResponse>;
|
|
163
163
|
} | {
|
|
164
164
|
faqs: import("..").FAQ[];
|
|
165
165
|
total: number;
|
|
166
166
|
categories: readonly string[];
|
|
167
|
-
data:
|
|
167
|
+
data: FAQListResponse;
|
|
168
168
|
isError: false;
|
|
169
169
|
error: null;
|
|
170
170
|
isPending: false;
|
|
@@ -187,8 +187,8 @@ export declare function useFaqList(options?: UseFaqListOptions): {
|
|
|
187
187
|
isRefetching: boolean;
|
|
188
188
|
isStale: boolean;
|
|
189
189
|
isEnabled: boolean;
|
|
190
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
190
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
|
|
191
191
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
192
|
-
promise: Promise<
|
|
192
|
+
promise: Promise<FAQListResponse>;
|
|
193
193
|
};
|
|
194
194
|
export {};
|
|
@@ -18,5 +18,7 @@ export function Slider({ value: controlledValue, defaultValue = 0, min = 0, max
|
|
|
18
18
|
onChange?.(newVal);
|
|
19
19
|
};
|
|
20
20
|
const displayValue = formatValue ? formatValue(value) : String(value);
|
|
21
|
-
return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { size: "sm", weight: "semibold", className: "tabular-nums text-zinc-900 dark:text-zinc-100", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Div, { className: "absolute inset-y-0 flex items-center w-full", children: _jsx(Div, { className: "w-full h-1.5 rounded-full bg-zinc-200 dark:bg-slate-700", children: _jsx(Div, { className: "h-full rounded-full bg-primary-500 dark:bg-secondary-500 transition-all",
|
|
21
|
+
return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { size: "sm", weight: "semibold", className: "tabular-nums text-zinc-900 dark:text-zinc-100", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Div, { className: "absolute inset-y-0 flex items-center w-full", children: _jsx(Div, { className: "w-full h-1.5 rounded-full bg-zinc-200 dark:bg-slate-700", children: _jsx(Div, { className: "h-full rounded-full bg-primary-500 dark:bg-secondary-500 transition-all",
|
|
22
|
+
// audit-inline-style-ok: computed percentage
|
|
23
|
+
style: { width: `${pct}%` } }) }) }), _jsx("input", { type: "range", id: sliderId, min: min, max: max, step: step, value: value, disabled: disabled, onChange: handleChange, className: cn("relative w-full appearance-none bg-transparent cursor-pointer", "focus:outline-none", "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4", "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white", "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-500 dark:[&::-webkit-slider-thumb]:border-secondary-500", "[&::-webkit-slider-thumb]:shadow-sm", "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4", "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white", "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary-500 dark:[&::-moz-range-thumb]:border-secondary-500", disabled && "opacity-50 cursor-not-allowed") })] }), _jsxs(Row, { justify: "between", className: "text-xs text-zinc-400 dark:text-zinc-400", children: [_jsx(Span, { children: formatValue ? formatValue(min) : min }), _jsx(Span, { children: formatValue ? formatValue(max) : max })] }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error }))] }));
|
|
22
24
|
}
|
|
@@ -69,6 +69,7 @@ export function useHistory(userId) {
|
|
|
69
69
|
const [items, setItems] = useState([]);
|
|
70
70
|
const trackTimers = useRef(new Map());
|
|
71
71
|
const loadItems = useCallback(async () => {
|
|
72
|
+
// toast-intentionally-silent — silent fallback to empty list on error
|
|
72
73
|
try {
|
|
73
74
|
if (isAuth) {
|
|
74
75
|
setItems(await fetchAuthHistory());
|
|
@@ -20,11 +20,15 @@ function AdsenseAd({ config }) {
|
|
|
20
20
|
// AdSense not loaded yet — no-op
|
|
21
21
|
}
|
|
22
22
|
}, []);
|
|
23
|
-
return (_jsx(Div, { ref: ref, children: _jsx("ins", { className: "adsbygoogle",
|
|
23
|
+
return (_jsx(Div, { ref: ref, children: _jsx("ins", { className: "adsbygoogle",
|
|
24
|
+
// audit-inline-style-ok: dynamic CSS
|
|
25
|
+
style: { display: "block" }, "data-ad-client": config.adsenseClient ?? "", "data-ad-slot": config.adsenseSlot ?? "", "data-ad-format": config.adsenseFormat ?? "auto", "data-full-width-responsive": "true" }) }));
|
|
24
26
|
}
|
|
25
27
|
function ThirdPartyAd({ config }) {
|
|
26
28
|
if (config.thirdPartyUrl) {
|
|
27
|
-
return (_jsx("iframe", { src: config.thirdPartyUrl, width: config.thirdPartyWidth ?? "100%", height: config.thirdPartyHeight ?? "90", scrolling: "no", frameBorder: "0", title: "Advertisement",
|
|
29
|
+
return (_jsx("iframe", { src: config.thirdPartyUrl, width: config.thirdPartyWidth ?? "100%", height: config.thirdPartyHeight ?? "90", scrolling: "no", frameBorder: "0", title: "Advertisement",
|
|
30
|
+
// audit-inline-style-ok: dynamic CSS
|
|
31
|
+
style: { border: 0, overflow: "hidden" }, loading: "lazy" }));
|
|
28
32
|
}
|
|
29
33
|
return null;
|
|
30
34
|
}
|
|
@@ -30,5 +30,7 @@ export function AdvertisementBanner({ title, subtitle, ctaLabel = "Shop now", on
|
|
|
30
30
|
compact
|
|
31
31
|
? "h-[clamp(112px,16vh,160px)]"
|
|
32
32
|
: "min-h-[clamp(240px,34vh,360px)]",
|
|
33
|
-
].join(" "),
|
|
33
|
+
].join(" "),
|
|
34
|
+
// audit-inline-style-ok: optional inline color
|
|
35
|
+
style: backgroundColor ? { backgroundColor } : undefined, children: [!backgroundColor && (_jsx(Div, { className: CLS_GRADIENT_BG, "aria-hidden": true })), _jsxs(Div, { className: `absolute inset-0 ${__O.hidden}`, "aria-hidden": true, children: [_jsx(Div, { className: "absolute -top-16 -left-16 w-64 h-64 rounded-full bg-primary/20 blur-3xl animate-pulse" }), _jsx(Div, { className: "absolute -bottom-16 right-0 w-80 h-80 rounded-full bg-cobalt/20 blur-3xl animate-pulse" })] }), compact ? (_jsxs(Row, { justify: "between", className: "relative z-10 w-full px-6 py-4 gap-4 flex-wrap", children: [_jsxs(Span, { className: "inline-flex items-center gap-2", children: [_jsx(Sparkles, { className: "w-4 h-4 text-white/80" }), _jsx(Span, { size: "sm", weight: "semibold", className: "text-white", children: title })] }), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "sm", onClick: onCtaClick, className: CLS_CTA_BTN_SM, children: [ctaLabel, _jsx(ArrowRight, { className: "w-3.5 h-3.5" })] }))] })) : (_jsxs(Div, { className: "relative z-10 w-full max-w-4xl mx-auto px-6 py-12 md:py-16 text-center", children: [tagLabel && (_jsxs(Span, { size: "xs", weight: "semibold", className: "inline-flex items-center gap-1.5 bg-white/15 text-white/90 uppercase tracking-widest px-4 py-1.5 rounded-full mb-5 backdrop-blur-sm shadow-sm", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { level: 2, variant: "none", className: "text-3xl md:text-5xl lg:text-6xl font-extrabold text-white mb-4 drop-shadow-lg leading-tight", children: title }), subtitle && (_jsx(Text, { variant: "none", className: "text-white text-base md:text-xl mb-10 max-w-2xl mx-auto", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "lg", onClick: onCtaClick, className: CLS_CTA_BTN_LG, children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] }))] }) }) }));
|
|
34
36
|
}
|
|
@@ -55,5 +55,9 @@ export function BeforeAfterCard({ item, beforeLabel = "Before", afterLabel = "Af
|
|
|
55
55
|
setPosition((p) => Math.max(0, p - 2));
|
|
56
56
|
if (e.key === "ArrowRight")
|
|
57
57
|
setPosition((p) => Math.min(100, p + 2));
|
|
58
|
-
}, children: [_jsx(Image, { src: item.afterImage, alt: afterLabel, fill: true, sizes: "(max-width: 640px) 100vw, 50vw", className: "object-cover" }), _jsx(Div, { className: "absolute inset-0 overflow-hidden",
|
|
58
|
+
}, children: [_jsx(Image, { src: item.afterImage, alt: afterLabel, fill: true, sizes: "(max-width: 640px) 100vw, 50vw", className: "object-cover" }), _jsx(Div, { className: "absolute inset-0 overflow-hidden",
|
|
59
|
+
// audit-inline-style-ok: computed percentage
|
|
60
|
+
style: { width: `${position}%` }, children: _jsx(Image, { src: item.beforeImage, alt: beforeLabel, fill: true, sizes: "(max-width: 640px) 100vw, 50vw", className: "object-cover" }) }), _jsx(Div, { className: "absolute top-0 bottom-0 z-10 w-0.5 bg-card shadow-md",
|
|
61
|
+
// audit-inline-style-ok: computed percentage
|
|
62
|
+
style: { left: `${position}%` }, children: _jsx(Div, { className: "absolute top-1/2 left-1/2 flex h-8 w-8 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full bg-card shadow-lg", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 8L1 5M4 8L1 11M4 8H12M12 8L15 5M12 8L15 11", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }) }), _jsx(Span, { size: "xs", weight: "medium", className: "absolute top-3 left-3 z-10 rounded-full bg-black/50 px-2.5 py-0.5 text-white", children: beforeLabel }), _jsx(Span, { size: "xs", weight: "medium", className: "absolute top-3 right-3 z-10 rounded-full bg-black/50 px-2.5 py-0.5 text-white", children: afterLabel })] }), _jsx(Div, { className: `${__P.p4}`, children: _jsx(Text, { className: "text-foreground text-sm font-medium", children: item.caption }) })] }));
|
|
59
63
|
}
|
|
@@ -47,7 +47,11 @@ function CardItem({ card }) {
|
|
|
47
47
|
cardStyle.backgroundColor = card.backgroundColor;
|
|
48
48
|
if (card.textColor)
|
|
49
49
|
cardStyle.color = card.textColor;
|
|
50
|
-
return (_jsxs(Div, { className: `flex flex-col overflow-hidden ${radiusClass} ${shadowClass} bg-[var(--appkit-color-surface)]`,
|
|
50
|
+
return (_jsxs(Div, { className: `flex flex-col overflow-hidden ${radiusClass} ${shadowClass} bg-[var(--appkit-color-surface)]`,
|
|
51
|
+
// audit-inline-style-ok: pass-through style prop
|
|
52
|
+
style: cardStyle, children: [card.image && (_jsx(Div, { className: `relative w-full aspect-video ${__O.hidden}`, children: _jsx(MediaImage, { src: card.image, alt: card.imageAlt ?? "", size: "card" }) })), _jsxs(Div, { className: `flex flex-col gap-2 ${__P.p4} flex-1`, children: [card.eyebrow && (_jsx(Text, { className: "text-xs font-semibold uppercase tracking-widest opacity-70", children: card.eyebrow })), card.title && (_jsx(Text, { className: "text-base font-bold leading-snug", children: card.title })), card.body && (_jsx(Text, { className: "text-sm opacity-80 leading-relaxed flex-1", children: card.body })), card.buttons && card.buttons.length > 0 && (_jsx(Div, { className: "flex flex-wrap gap-2 mt-2", children: card.buttons.map((btn, i) => (_jsx("a", { href: btn.href, target: btn.target ?? "_self", rel: btn.target === "_blank" ? "noopener noreferrer" : undefined, className: VARIANT_CLASS[btn.variant] ?? VARIANT_CLASS.primary, children: btn.label }, i))) })), card.formEmbed && (_jsx("iframe", { src: card.formEmbed, sandbox: "allow-forms allow-scripts", loading: "lazy", className: "w-full mt-3 border-0 rounded-md",
|
|
53
|
+
// audit-inline-style-ok: dynamic CSS
|
|
54
|
+
style: { minHeight: "200px" }, title: "Embedded form" }))] })] }));
|
|
51
55
|
}
|
|
52
56
|
// --- Section Header ----------------------------------------------------------
|
|
53
57
|
function SectionHeader({ title }) {
|
|
@@ -14,7 +14,9 @@ function StepCard({ step, visible, delay, }) {
|
|
|
14
14
|
"shadow-md group hover:-translate-y-2 hover:shadow-xl",
|
|
15
15
|
"transition-all duration-300",
|
|
16
16
|
visible ? CLS_VISIBLE : "opacity-0 translate-y-8",
|
|
17
|
-
].join(" "),
|
|
17
|
+
].join(" "),
|
|
18
|
+
// audit-inline-style-ok: computed timing
|
|
19
|
+
style: { transitionDelay: `${delay}ms` }, "data-section": "howitworkssection-div-340", children: [_jsx(Div, { className: "absolute top-4 right-5 font-display text-7xl bg-gradient-to-br from-primary to-cobalt opacity-10 bg-clip-text text-transparent select-none pointer-events-none leading-none", "aria-hidden": "true", children: step.number }), _jsx(Div, { className: `relative z-10 w-10 h-10 rounded-full ${badgeBg} text-white font-bold text-sm flex items-center justify-center mb-5 shadow-md`, children: step.number }), step.renderIcon && (_jsx(Div, { className: `relative z-10 w-14 h-14 rounded-2xl ${iconBg} flex items-center justify-center mb-4 border border-white/80 dark:border-slate-700/50`, children: _jsx("span", { className: `${iconColor}`, "aria-hidden": "true", children: step.renderIcon({ className: "w-6 h-6" }) }) })), _jsx(Heading, { level: 3, className: `relative z-10 text-base font-semibold ${THEME_CONSTANTS.themed.textPrimary} mb-2`, children: step.title }), _jsx(Text, { className: `relative z-10 text-sm ${THEME_CONSTANTS.themed.textSecondary} leading-relaxed`, children: step.desc })] }));
|
|
18
20
|
}
|
|
19
21
|
// --- Section -----------------------------------------------------------------
|
|
20
22
|
export function HowItWorksSection({ title, subtitle, pillLabel, ctaLabel, onCtaClick, steps, className = "", }) {
|