@mohasinac/appkit 3.0.2 → 3.0.4
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/filters/filter-load-options.js +11 -1
- package/dist/_internal/client/features/layout/filterNavItems.js +0 -1
- package/dist/_internal/client/features/layout/index.js +0 -1
- package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +0 -1
- package/dist/_internal/client/features/maintenance/views/ServerErrorDetailView.js +0 -1
- package/dist/_internal/server/features/checkout/actions.js +9 -9
- package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +1 -1
- package/dist/_internal/shared/listing-types/action-tracker.js +1 -1
- package/dist/client/api/ApiError.d.ts +10 -4
- package/dist/client/api/surface-error.js +0 -1
- package/dist/client.d.ts +4 -0
- package/dist/client.js +2 -0
- package/dist/core/hooks/useSyncManager.js +4 -4
- package/dist/features/_guide-cls.d.ts +1 -1
- package/dist/features/_guide-cls.js +1 -1
- package/dist/features/about/components/AboutView.js +1 -4
- package/dist/features/about/components/FAQPageView.js +1 -1
- package/dist/features/about/components/FeesView.js +1 -1
- package/dist/features/about/components/HelpPageView.js +1 -1
- package/dist/features/about/components/HowOrdersWorkView.js +1 -1
- package/dist/features/about/components/PublicProfileView.js +6 -6
- package/dist/features/about/components/TrackOrderView.js +1 -1
- package/dist/features/account/components/AddressBook.js +1 -1
- package/dist/features/account/components/AddressForm.js +10 -2
- package/dist/features/account/components/AddressesIndexListing.js +1 -1
- package/dist/features/account/components/BuyerAccountGuideView.js +1 -1
- package/dist/features/account/components/BuyerAuctionsGuideView.js +1 -1
- package/dist/features/account/components/BuyerOrdersGuideView.js +1 -1
- package/dist/features/account/components/BuyerShoppingGuideView.js +1 -1
- package/dist/features/account/components/ChatWindow.js +1 -1
- package/dist/features/account/components/MessagesView.js +1 -1
- package/dist/features/account/components/NotificationBell.js +25 -10
- package/dist/features/account/components/NotificationPreferencesPanel.js +2 -2
- package/dist/features/account/components/UserOffersPanel.js +1 -0
- package/dist/features/account/components/UserSidebar.js +1 -6
- package/dist/features/account/components/UserSupportView.js +1 -1
- package/dist/features/admin/components/AdminAnalyticsGuideView.js +2 -2
- package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
- package/dist/features/admin/components/AdminBundlesView.js +1 -1
- package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
- package/dist/features/admin/components/AdminCatalogGuideView.js +2 -2
- package/dist/features/admin/components/AdminContentGuideView.js +2 -2
- package/dist/features/admin/components/AdminEmployeeEditorView.js +2 -2
- package/dist/features/admin/components/AdminGuideHubView.js +1 -5
- package/dist/features/admin/components/AdminMediaView.js +1 -1
- package/dist/features/admin/components/AdminNavigationView.js +1 -1
- package/dist/features/admin/components/AdminOrdersGuideView.js +3 -3
- package/dist/features/admin/components/AdminPayoutsView.js +1 -4
- package/dist/features/admin/components/AdminSidebar.js +1 -6
- package/dist/features/admin/components/AdminSiteConfigGuideView.js +1 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +9 -1
- package/dist/features/admin/components/AdminStoreEditorView.js +1 -1
- package/dist/features/admin/components/AdminStoresGuideView.js +2 -2
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +7 -7
- package/dist/features/admin/components/AdminTeamGuideView.js +2 -2
- package/dist/features/admin/components/AdminTrustGuideView.js +3 -3
- package/dist/features/admin/components/AdminUsersGuideView.js +3 -3
- package/dist/features/admin/components/DashboardStats.js +6 -5
- package/dist/features/admin/components/DataTable.js +2 -2
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +4 -6
- package/dist/features/admin/components/analytics/AdminStatCard.js +4 -3
- package/dist/features/admin/components/analytics/AdminTopProductsTable.js +1 -1
- package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +1 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -3
- package/dist/features/auth/components/ForgotPasswordView.js +19 -8
- package/dist/features/auth/components/LoginForm.js +10 -2
- package/dist/features/auth/components/RegisterForm.js +10 -2
- package/dist/features/auth/components/ResetPasswordView.js +19 -8
- package/dist/features/auth/components/SocialAuthButtons.js +1 -1
- package/dist/features/before-after/components/BeforeAfterSlider.js +1 -1
- package/dist/features/blog/api/[slug]/route.js +1 -1
- package/dist/features/blog/components/BlogFeaturedCard.js +1 -1
- package/dist/features/blog/components/BlogListView.js +1 -1
- package/dist/features/blog/components/BlogPostView.js +1 -1
- package/dist/features/blog/schemas/index.d.ts +2 -2
- package/dist/features/cart/components/CartDrawer.js +2 -2
- package/dist/features/cart/components/CartView.js +1 -1
- package/dist/features/cart/components/CheckoutView.js +1 -1
- package/dist/features/categories/components/BrandDetailPageView.js +2 -1
- package/dist/features/categories/components/BundleDetailView.js +1 -1
- package/dist/features/categories/components/BundleItemsPicker.js +1 -1
- package/dist/features/categories/components/CategoryBundlesListing.js +3 -1
- package/dist/features/categories/components/CategoryDetailPageView.js +1 -1
- package/dist/features/categories/components/CategoryGrid.js +2 -1
- package/dist/features/categories/components/CategoryTableColumns.js +5 -2
- package/dist/features/categories/components/CategoryTree.js +3 -2
- package/dist/features/categories/components/ConcernCard.js +1 -1
- package/dist/features/categories/schemas/index.d.ts +2 -2
- package/dist/features/checkout/components/CheckoutStepper.js +1 -1
- package/dist/features/collections/components/CollectionCard.js +1 -1
- package/dist/features/contact/components/ContactPageView.js +27 -27
- package/dist/features/contact/email.d.ts +1 -0
- package/dist/features/contact/email.js +17 -5
- package/dist/features/copilot/components/AdminCopilotView.js +3 -3
- package/dist/features/email/primitives.d.ts +4 -0
- package/dist/features/email/primitives.js +4 -0
- package/dist/features/events/components/EventCard.js +2 -2
- package/dist/features/events/components/EventOfferCard.js +1 -1
- package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
- package/dist/features/events/components/EventRaffleWinnerView.js +2 -2
- package/dist/features/events/components/EventSaleBanner.js +0 -1
- package/dist/features/events/schemas/index.d.ts +2 -2
- package/dist/features/faq/components/ContactCTA.js +1 -1
- package/dist/features/faq/components/FAQAccordion.js +2 -2
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +2 -2
- package/dist/features/faq/components/RelatedFAQs.js +1 -1
- package/dist/features/faq/schemas/index.d.ts +2 -2
- package/dist/features/filters/AsyncFacetSection.js +3 -3
- package/dist/features/filters/FilterFacetSection.js +6 -6
- package/dist/features/filters/RangeFilter.js +2 -2
- package/dist/features/filters/SwitchFilter.js +1 -1
- package/dist/features/forms/Checkbox.js +1 -1
- package/dist/features/forms/Slider.js +7 -2
- package/dist/features/forms/utils.d.ts +2 -2
- package/dist/features/forms/utils.js +2 -2
- package/dist/features/history/hooks/useHistory.js +1 -1
- package/dist/features/homepage/components/AdSlot.js +3 -3
- package/dist/features/homepage/components/AdvertisementBanner.js +5 -4
- package/dist/features/homepage/components/BeforeAfterCard.js +9 -1
- package/dist/features/homepage/components/CharacterHotspot.js +42 -49
- package/dist/features/homepage/components/CharacterHotspotForm.js +18 -20
- package/dist/features/homepage/components/CollectionCardsSection.js +2 -2
- package/dist/features/homepage/components/CustomCardsSection.js +3 -6
- package/dist/features/homepage/components/CustomerReviewsSection.js +1 -1
- package/dist/features/homepage/components/FAQSection.js +2 -2
- package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
- package/dist/features/homepage/components/GoogleReviewsSection.js +4 -4
- package/dist/features/homepage/components/HeroBanner.js +12 -63
- package/dist/features/homepage/components/HeroCarousel.js +6 -6
- package/dist/features/homepage/components/HeroSection.js +1 -1
- package/dist/features/homepage/components/HowItWorksInfoView.js +1 -1
- package/dist/features/homepage/components/HowItWorksSection.js +5 -3
- package/dist/features/homepage/components/NewsletterBanner.js +3 -7
- package/dist/features/homepage/components/PromoGrid.js +2 -26
- package/dist/features/homepage/components/SectionCarousel.js +1 -1
- package/dist/features/homepage/components/SecurityHighlightsSection.js +6 -3
- package/dist/features/homepage/components/ShopByCategorySection.js +3 -3
- package/dist/features/homepage/components/SiteFeaturesSection.js +1 -1
- package/dist/features/homepage/components/SocialPostCard.js +2 -3
- package/dist/features/homepage/components/StatsCounterSection.js +6 -3
- package/dist/features/homepage/components/TestimonialsCarousel.js +2 -25
- package/dist/features/homepage/components/TrustBadges.js +1 -9
- package/dist/features/homepage/components/TrustFeaturesSection.js +6 -3
- package/dist/features/homepage/components/TrustIndicatorsSection.js +1 -1
- package/dist/features/homepage/components/WelcomeSection.js +2 -2
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +1 -1
- package/dist/features/homepage/lib/franchise-colors.d.ts +7 -0
- package/dist/features/homepage/lib/franchise-colors.js +7 -0
- package/dist/features/homepage/lib/live-stats.js +5 -5
- package/dist/features/layout/AppLayoutShell.js +7 -9
- package/dist/features/layout/BottomNavbar.js +1 -2
- package/dist/features/messages/hooks/useConversation.js +2 -1
- package/dist/features/messages/hooks/useConversations.js +1 -0
- package/dist/features/orders/components/OrdersList.js +1 -1
- package/dist/features/orders/components/RefundHistoryTable.d.ts +6 -0
- package/dist/features/orders/components/RefundHistoryTable.js +3 -2
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +2 -2
- package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -1
- package/dist/features/products/components/CompareOverlay.js +11 -8
- package/dist/features/products/components/CustomSectionTabContent.js +1 -1
- package/dist/features/products/components/FeatureBadge.js +11 -1
- package/dist/features/products/components/GroupSettingsPanel.js +2 -2
- package/dist/features/products/components/MarketplaceBundleCard.js +1 -1
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -2
- package/dist/features/products/components/PrizeDrawItemsEditor.js +1 -1
- package/dist/features/products/components/PrizeDrawsIndexListing.js +1 -1
- package/dist/features/products/components/ProductCardMetadataSection.js +0 -1
- package/dist/features/products/components/ProductDetailPageView.js +1 -1
- package/dist/features/products/components/ProductFeatureBadges.js +1 -1
- package/dist/features/products/components/ProductGalleryClient.js +1 -1
- package/dist/features/products/components/ProductGrid.js +7 -7
- package/dist/features/products/components/ShareButton.js +1 -1
- package/dist/features/products/components/ShowGroupSection.js +7 -5
- package/dist/features/products/components/SublistingCarouselSection.js +2 -2
- package/dist/features/products/schemas/index.d.ts +2 -2
- package/dist/features/promotions/components/CouponCard.js +2 -2
- package/dist/features/promotions/schemas/index.d.ts +2 -2
- package/dist/features/reviews/components/ReviewDetailShell.js +3 -3
- package/dist/features/reviews/components/ReviewModal.js +2 -4
- package/dist/features/reviews/components/ReviewSummary.js +3 -2
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/scams/actions/scam-actions.js +1 -1
- package/dist/features/scams/components/ScamProfileView.js +1 -1
- package/dist/features/search/components/Search.js +2 -2
- package/dist/features/search/components/SearchFiltersRow.js +1 -1
- package/dist/features/search/schemas/index.d.ts +1 -1
- package/dist/features/seller/components/PhysicalLocationModal.js +2 -3
- package/dist/features/seller/components/SellerAddressesView.js +2 -1
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +1 -1
- package/dist/features/seller/components/SellerBidsView.js +1 -1
- package/dist/features/seller/components/SellerCouponEditorView.js +1 -1
- package/dist/features/seller/components/SellerGoogleReviewsView.js +1 -1
- package/dist/features/seller/components/SellerLiveView.js +1 -1
- package/dist/features/seller/components/SellerOffersPanel.js +1 -0
- package/dist/features/seller/components/SellerOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPayoutMethodsView.js +8 -2
- package/dist/features/seller/components/SellerPayoutRequestView.js +1 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +1 -1
- package/dist/features/seller/components/SellerProductShell.js +2 -2
- package/dist/features/seller/components/SellerProductsCards.js +1 -1
- package/dist/features/seller/components/SellerProductsView.js +1 -1
- package/dist/features/seller/components/SellerReviewsView.js +2 -1
- package/dist/features/seller/components/SellerShippingConfigsView.js +9 -3
- package/dist/features/seller/components/SellerShippingView.js +1 -1
- package/dist/features/seller/components/SellerSidebar.js +3 -8
- package/dist/features/seller/components/SellerStoreCategoriesView.js +11 -3
- package/dist/features/seller/components/SellerTemplatesView.js +8 -2
- package/dist/features/seller/components/analytics/SellerRevenueChart.js +1 -1
- package/dist/features/seller/components/analytics/SellerTopProducts.js +1 -1
- package/dist/features/seller/schemas/index.d.ts +2 -2
- package/dist/features/shell/FormShell.js +2 -2
- package/dist/features/shell/QuickFormDrawer.js +1 -1
- package/dist/features/site-settings/components/NavPermissionsManager.js +1 -1
- package/dist/features/stores/components/StoreCapabilitiesGuideView.js +1 -1
- package/dist/features/stores/components/StoreGuideHubView.js +2 -9
- package/dist/features/stores/components/StoreHeader.js +1 -1
- package/dist/features/stores/components/StoreListingsGuideView.js +4 -4
- package/dist/features/stores/components/StoreOrdersGuideView.js +2 -2
- package/dist/features/stores/components/StoresIndexListing.js +1 -1
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +2 -2
- package/dist/features/wishlist/components/WishlistPage.js +1 -1
- package/dist/features/wishlist/components/WishlistToggleButton.js +3 -3
- package/dist/features/wishlist/hooks/useWishlistCount.js +1 -1
- package/dist/http/ApiClient.d.ts +1 -0
- package/dist/http/ApiClient.js +20 -0
- package/dist/monitoring/error-tracking.d.ts +0 -3
- package/dist/monitoring/error-tracking.js +1 -1
- package/dist/monitoring/server-logger.js +3 -3
- package/dist/next/components/GlobalError.js +1 -1
- package/dist/react/ErrorBoundary.js +1 -1
- package/dist/styles.css +45 -7
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/themes/default-light.js +3 -0
- package/dist/tokens/tokens.css +43 -6
- package/dist/ui/components/Anchor.d.ts +8 -1
- package/dist/ui/components/Anchor.js +16 -2
- package/dist/ui/components/Button.d.ts +5 -2
- package/dist/ui/components/Button.js +5 -2
- package/dist/ui/components/Details.d.ts +33 -2
- package/dist/ui/components/Details.js +73 -4
- package/dist/ui/components/Div.d.ts +3 -0
- package/dist/ui/components/Div.js +12 -1
- package/dist/ui/components/DynamicBgDiv.d.ts +13 -0
- package/dist/ui/components/DynamicBgDiv.js +18 -0
- package/dist/ui/components/Form.d.ts +3 -19
- package/dist/ui/components/Form.js +8 -1
- package/dist/ui/components/Layout.d.ts +12 -1
- package/dist/ui/components/Layout.js +9 -1
- package/dist/ui/components/Progress.d.ts +1 -1
- package/dist/ui/components/Progress.js +1 -0
- package/dist/ui/components/Progress.style.css +1 -0
- package/dist/ui/components/ProgressBarFill.d.ts +6 -0
- package/dist/ui/components/ProgressBarFill.js +11 -0
- package/dist/ui/components/Semantic.d.ts +26 -7
- package/dist/ui/components/Semantic.js +33 -8
- package/dist/ui/components/TextLink.d.ts +36 -1
- package/dist/ui/components/TextLink.js +30 -2
- package/dist/ui/components/Typography.d.ts +26 -6
- package/dist/ui/components/Typography.js +37 -13
- package/dist/ui/components/VacationBanner.js +0 -1
- package/dist/ui/components/surface-tokens.d.ts +12 -2
- package/dist/ui/components/surface-tokens.js +19 -1
- package/dist/ui/rich-text/RichText.js +1 -1
- package/dist/validation/schemas.d.ts +1 -1
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import Link from "next/link";
|
|
3
3
|
import { ArrowRight } from "lucide-react";
|
|
4
4
|
import { Div, Row, Span, Stack, Text } from "../../../ui";
|
|
5
|
+
import { DynamicBgDiv } from "../../../ui/components/DynamicBgDiv";
|
|
5
6
|
const __P = {
|
|
6
7
|
p3: "p-3",
|
|
7
8
|
};
|
|
@@ -11,7 +12,7 @@ const __O = {
|
|
|
11
12
|
const CLS_FEATURED_DOT = "absolute left-2 top-2 rounded-full bg-warning-surface p-1 leading-none";
|
|
12
13
|
export function CategoryCard({ category, href, onClick, className = "", }) {
|
|
13
14
|
const productCount = category.metrics?.productCount ?? category.productCount ?? 0;
|
|
14
|
-
const inner = (_jsxs(Stack, { className: "h-full", children: [_jsxs(Div, { surface: "muted", className: `relative aspect-[4/3] w-full ${__O.hidden} flex-shrink-0`, children: [category.display?.coverImage ? (_jsx(
|
|
15
|
+
const inner = (_jsxs(Stack, { className: "h-full", children: [_jsxs(Div, { surface: "muted", className: `relative aspect-[4/3] w-full ${__O.hidden} flex-shrink-0`, children: [category.display?.coverImage ? (_jsx("img", { src: category.display.coverImage, alt: category.name, className: "h-full w-full object-cover transition-transform duration-300 group-hover:scale-105" })) : category.display?.color ? (_jsx(DynamicBgDiv, { color: category.display.color, className: "h-full w-full opacity-80" })) : null, category.display?.icon && (_jsx(Row, { textSize: "4xl", className: "absolute inset-0", align: "center", justify: "center", children: category.display.icon })), category.isFeatured && (_jsx(Span, { size: "xs", className: CLS_FEATURED_DOT, children: "\u2605" }))] }), _jsxs(Stack, { className: `flex-1 ${__P.p3}.5`, children: [_jsx(Text, { color: "inverse", className: `leading-snug text-neutral-900 dark:text-neutral-100 dark:`, truncate: 2, size: "sm", weight: "semibold", children: category.name }), category.description && (_jsx(Text, { className: `mt-1 flex-1`, color: "muted", truncate: 2, size: "xs", children: category.description })), _jsxs(Row, { className: "mt-2", align: "center", justify: "between", gap: "sm", children: [_jsxs(Text, { size: "xs", color: "faint", children: [productCount.toLocaleString(), " ", productCount === 1 ? "item" : "items"] }), _jsxs(Span, { layout: "inline-flex", gap: "xs", size: "xs", weight: "medium", border: "default", className: "group-hover:bg-primary group-hover:border-primary group-hover:text-white transition-colors", rounded: "md", padding: "pill-sm-tall", color: "muted", children: ["Browse ", _jsx(ArrowRight, { className: "h-3 w-3" })] })] })] })] }));
|
|
15
16
|
const cardClass = `group relative flex flex-col overflow-hidden rounded-xl border border-neutral-200 bg-white dark:border-zinc-700 dark:bg-zinc-900 shadow-sm transition hover:shadow-md h-full ${className}`;
|
|
16
17
|
if (href) {
|
|
17
18
|
return (_jsx(Link, { href: href, className: cardClass, children: inner }));
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { Button, Div, Row, Span, StatusBadge } from "../../../ui";
|
|
3
4
|
import { MediaImage } from "../../media";
|
|
5
|
+
import { DynamicBgDiv } from "../../../ui/components/DynamicBgDiv";
|
|
4
6
|
const __O = {
|
|
5
7
|
hidden: "overflow-hidden",
|
|
6
8
|
};
|
|
7
9
|
const CLS_DELETE_BTN = "text-error hover:text-error dark:text-error";
|
|
10
|
+
const TIER_PL = ["pl-0", "pl-5", "pl-10", "pl-[60px]"];
|
|
8
11
|
const DEFAULT_LABELS = {
|
|
9
12
|
colName: "Name",
|
|
10
13
|
colSlug: "Slug",
|
|
@@ -22,13 +25,13 @@ export function getCategoryTableColumns(onEdit, onDelete, labels = {}) {
|
|
|
22
25
|
{
|
|
23
26
|
key: "image",
|
|
24
27
|
header: "",
|
|
25
|
-
render: (cat) => (_jsx(Div, { className: `relative w-9 h-9 ${__O.hidden} flex-shrink-0`, rounded: "default", children: cat.display?.coverImage ? (_jsx(MediaImage, { src: cat.display.coverImage, alt: "", size: "thumbnail", className: "w-full h-full object-cover" })) : (_jsx(
|
|
28
|
+
render: (cat) => (_jsx(Div, { className: `relative w-9 h-9 ${__O.hidden} flex-shrink-0`, rounded: "default", children: cat.display?.coverImage ? (_jsx(MediaImage, { src: cat.display.coverImage, alt: "", size: "thumbnail", className: "w-full h-full object-cover" })) : (_jsx(DynamicBgDiv, { color: cat.display?.color ?? "var(--appkit-color-text-faint)", className: "w-full h-full flex items-center justify-center text-base text-[var(--appkit-color-text-on-primary)]", children: cat.display?.icon ?? "🗂️" })) })),
|
|
26
29
|
},
|
|
27
30
|
{
|
|
28
31
|
key: "name",
|
|
29
32
|
header: L.colName,
|
|
30
33
|
sortable: true,
|
|
31
|
-
render: (cat) => (_jsxs(Div, {
|
|
34
|
+
render: (cat) => (_jsxs(Div, { className: TIER_PL[Math.min(cat.tier, 3)], children: [cat.name, cat.tier > 0 && (_jsxs(Span, { size: "xs", className: "ml-2", color: "faint", children: ["(Tier ", cat.tier, ")"] }))] })),
|
|
32
35
|
},
|
|
33
36
|
{
|
|
34
37
|
key: "slug",
|
|
@@ -7,7 +7,8 @@ function CategoryTreeNode({ item, children = [], activeId, onSelect, depth = 0,
|
|
|
7
7
|
const hasChildren = children.length > 0;
|
|
8
8
|
const isActive = item.id === activeId;
|
|
9
9
|
const [expanded, setExpanded] = useState(true);
|
|
10
|
-
const
|
|
10
|
+
const DEPTH_PL = ["pl-2", "pl-6", "pl-10", "pl-14", "pl-[72px]"];
|
|
11
|
+
const depthPl = DEPTH_PL[Math.min(depth, 4)];
|
|
11
12
|
return (_jsxs(Div, { children: [_jsxs(Row, { textWeight: "semibold", textSize: "sm", role: "treeitem", "aria-expanded": hasChildren ? expanded : undefined, "aria-selected": isActive, tabIndex: 0, onKeyDown: (e) => {
|
|
12
13
|
if (e.key === "Enter" || e.key === " ") {
|
|
13
14
|
if (hasChildren)
|
|
@@ -19,7 +20,7 @@ function CategoryTreeNode({ item, children = [], activeId, onSelect, depth = 0,
|
|
|
19
20
|
if (hasChildren)
|
|
20
21
|
setExpanded((p) => !p);
|
|
21
22
|
onSelect?.(item);
|
|
22
|
-
}, className: `cursor-pointer py-1.5 transition select-none ${isActive ? "bg-primary-50 text-primary-700 dark:bg-primary-900/30 dark:text-primary-400" : "text-neutral-700 hover:bg-neutral-50 dark:text-zinc-300 dark:hover:bg-zinc-800"}`, align: "center", gap: "xs", padding: "x-xs", rounded: "md",
|
|
23
|
+
}, className: `cursor-pointer py-1.5 transition select-none ${depthPl} ${isActive ? "bg-primary-50 text-primary-700 dark:bg-primary-900/30 dark:text-primary-400" : "text-neutral-700 hover:bg-neutral-50 dark:text-zinc-300 dark:hover:bg-zinc-800"}`, align: "center", gap: "xs", padding: "x-xs", rounded: "md", children: [hasChildren && (_jsx(Span, { size: "xs", "aria-hidden": "true", className: `transition-transform duration-150 ${expanded ? "rotate-90" : ""}`, color: "faint", children: "\u25B6" })), !hasChildren && _jsx(Span, { className: "w-3" }), item.display?.icon && (_jsx(Span, { size: "base", "aria-hidden": "true", className: "flex-shrink-0", children: item.display.icon })), _jsx(Text, { className: "flex-1 truncate", children: item.name }), item.metrics && (_jsx(Span, { size: "xs", className: "ml-auto flex-shrink-0 tabular-nums", color: "faint", children: item.metrics.productCount }))] }), hasChildren && expanded && (_jsx(Div, { role: "group", children: children.map((child) => (_jsx(CategoryTreeNode, { item: child, activeId: activeId, onSelect: onSelect, depth: depth + 1 }, child.id))) }))] }));
|
|
23
24
|
}
|
|
24
25
|
/**
|
|
25
26
|
* CategoryTree — hierarchical expandable navigation for categories.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Button, Div, Heading, Text } from "../../../ui";
|
|
3
3
|
export function ConcernCard({ concern, onClick, className = "", }) {
|
|
4
|
-
return (_jsxs(Button, { type: "button", variant: "outline", onClick: () => onClick?.(concern), className: `group flex flex-col items-center gap-3 rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-900 p-4 text-center shadow-sm transition hover:border-primary dark:hover:border-primary-400 hover:shadow-md ${className}`, children: [concern.display?.coverImage && (_jsx(
|
|
4
|
+
return (_jsxs(Button, { type: "button", variant: "outline", onClick: () => onClick?.(concern), className: `group flex flex-col items-center gap-3 rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-900 p-4 text-center shadow-sm transition hover:border-primary dark:hover:border-primary-400 hover:shadow-md ${className}`, children: [concern.display?.coverImage && (_jsx("img", { src: concern.display.coverImage, alt: concern.name, className: "h-16 w-16 object-cover rounded-full" })), _jsxs(Div, { children: [_jsx(Heading, { level: 3, className: "text-neutral-900 dark:text-neutral-100 group-hover:text-primary dark:group-hover:text-primary-400", size: "sm", weight: "semibold", children: concern.name }), concern.description && (_jsx(Text, { className: `mt-1`, color: "muted", truncate: 2, size: "xs", children: concern.description }))] })] }));
|
|
5
5
|
}
|
|
@@ -746,16 +746,16 @@ export declare const categoryListParamsSchema: z.ZodObject<{
|
|
|
746
746
|
}, "strip", z.ZodTypeAny, {
|
|
747
747
|
type?: "category" | "brand" | "collection" | "concern" | undefined;
|
|
748
748
|
featured?: boolean | undefined;
|
|
749
|
-
q?: string | undefined;
|
|
750
749
|
page?: number | undefined;
|
|
750
|
+
q?: string | undefined;
|
|
751
751
|
perPage?: number | undefined;
|
|
752
752
|
parentId?: string | undefined;
|
|
753
753
|
tier?: number | undefined;
|
|
754
754
|
}, {
|
|
755
755
|
type?: "category" | "brand" | "collection" | "concern" | undefined;
|
|
756
756
|
featured?: boolean | undefined;
|
|
757
|
-
q?: string | undefined;
|
|
758
757
|
page?: number | undefined;
|
|
758
|
+
q?: string | undefined;
|
|
759
759
|
perPage?: number | undefined;
|
|
760
760
|
parentId?: string | undefined;
|
|
761
761
|
tier?: number | undefined;
|
|
@@ -6,6 +6,6 @@ export function CheckoutStepper({ steps, current }) {
|
|
|
6
6
|
return (_jsx(Nav, { "aria-label": "Checkout steps", layout: "flex", gap: "xs", children: steps.map((step, idx) => {
|
|
7
7
|
const isDone = idx < currentIdx;
|
|
8
8
|
const isActive = step.id === current;
|
|
9
|
-
return (_jsxs(React.Fragment, { children: [_jsxs(Row, { gap: "2.5", children: [_jsx(Span, { layout: "flex", color: "inverse", className: `h-6 w-6 justify-center ${isDone ? "bg-success " : isActive ? "bg-neutral-900 " : "bg-neutral-200 dark:bg-
|
|
9
|
+
return (_jsxs(React.Fragment, { children: [_jsxs(Row, { gap: "2.5", children: [_jsx(Span, { layout: "flex", color: "inverse", className: `h-6 w-6 justify-[center] ${isDone ? "bg-success " : isActive ? "bg-neutral-900 " : "bg-neutral-200 dark:bg-[var(--appkit-color-surface-elevated)] text-neutral-500 dark:text-[var(--appkit-color-text-faint)]"}`, rounded: "full", size: "xs", weight: "semibold", children: isDone ? "✓" : idx + 1 }), _jsx(Span, { className: `${isActive ? "text-neutral-900 dark:text-[var(--appkit-color-text)]" : isDone ? "text-neutral-500 dark:text-[var(--appkit-color-text-faint)]" : "text-[var(--appkit-color-text-faint)]"}`, size: "sm", weight: "medium", children: step.label })] }), idx < steps.length - 1 && (_jsx(Span, { className: "h-px flex-1 bg-neutral-200" }))] }, step.id));
|
|
10
10
|
}) }));
|
|
11
11
|
}
|
|
@@ -3,7 +3,7 @@ import { Div, Heading, Text, TextLink } from "../../../ui";
|
|
|
3
3
|
import { LAYOUT } from "../../../tokens";
|
|
4
4
|
const CLS_PLACEHOLDER = "w-full";
|
|
5
5
|
export function CollectionCard({ collection, href }) {
|
|
6
|
-
return (_jsxs(TextLink, { rounded: "xl", href: href, className: "group relative block overflow-hidden bg-gray-100 dark:bg-
|
|
6
|
+
return (_jsxs(TextLink, { rounded: "xl", href: href, shadow: "hover-lg", className: "group relative block overflow-hidden bg-gray-100 dark:bg-[var(--appkit-color-surface-elevated)] transition", children: [collection.image ? (_jsx(Div, { className: `${LAYOUT.cardHeight.md} w-full`, overflow: "hidden", children: _jsx("img", { src: collection.image, alt: collection.title, className: "w-full h-full object-cover transition-transform duration-300 group-hover:scale-105" }) })) : (_jsx(Div, { surface: "muted", className: `${LAYOUT.cardHeight.md} ${CLS_PLACEHOLDER}` })), _jsxs(Div, { surface: "default", padding: "sm", children: [_jsx(Heading, { level: 3, className: "text-gray-900", weight: "semibold", children: collection.title }), collection.subtitle && (_jsx(Text, { className: "mt-1 text-gray-500", size: "sm", children: collection.subtitle })), collection.productCount !== undefined && (_jsxs(Text, { className: "mt-2 text-gray-400", size: "xs", children: [collection.productCount, " ", collection.productCount === 1 ? "item" : "items"] }))] })] }));
|
|
7
7
|
}
|
|
8
8
|
export function CollectionGrid({ collections, getHref }) {
|
|
9
9
|
return (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: collections.map((c) => (_jsx(CollectionCard, { collection: c, href: getHref(c.slug) }, c.slug))) }));
|
|
@@ -9,31 +9,31 @@ async function submitContact(data) {
|
|
|
9
9
|
await apiClient.post("/api/contact", data);
|
|
10
10
|
}
|
|
11
11
|
export function ContactPageView() {
|
|
12
|
-
return (_jsx(Main, { children: _jsx(Section, { padding: "y-2xl", children:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
12
|
+
return (_jsx(Main, { children: _jsx(Section, { padding: "y-2xl", children: _jsx(Container, { size: "xl", children: _jsxs(Stack, { gap: "section", children: [_jsxs(Stack, { gap: "3", children: [_jsx(Heading, { level: 1, size: "3xl", weight: "semibold", color: "primary", children: "Contact Us" }), _jsx(Text, { color: "muted", children: "Questions, support requests, or partnership inquiries." })] }), _jsx(AdSlot, { id: "detail-below-gallery", className: "mb-2" }), _jsxs(Div, { layout: "grid", gap: "6", className: "grid-cols-12", children: [_jsx(Div, { className: "col-span-12 lg:col-span-8", children: _jsx(ContactForm, { onSubmit: submitContact, labels: {
|
|
13
|
+
title: "Send us a message",
|
|
14
|
+
nameLabel: "Your Name",
|
|
15
|
+
emailLabel: "Email Address",
|
|
16
|
+
subjectLabel: "Subject",
|
|
17
|
+
messageLabel: "Message",
|
|
18
|
+
submitButton: "Send Message",
|
|
19
|
+
} }) }), _jsx(Div, { className: "col-span-12 lg:col-span-4", children: _jsx(ContactInfoSidebar, { infoItems: [
|
|
20
|
+
{
|
|
21
|
+
icon: "📧",
|
|
22
|
+
label: "Email",
|
|
23
|
+
value: "support@letitrip.in",
|
|
24
|
+
href: "mailto:support@letitrip.in",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
icon: "💬",
|
|
28
|
+
label: "WhatsApp",
|
|
29
|
+
value: "+91 70000 00000",
|
|
30
|
+
href: "https://wa.me/917000000000",
|
|
31
|
+
},
|
|
32
|
+
], labels: {
|
|
33
|
+
title: "Support",
|
|
34
|
+
businessHoursLabel: "Business Hours",
|
|
35
|
+
businessHoursValue: "Mon-Sat · 10:00 AM - 7:00 PM IST",
|
|
36
|
+
responseTimeLabel: "Response Time",
|
|
37
|
+
responseTimeValue: "Usually within 24 hours",
|
|
38
|
+
} }) })] }), _jsx(AdSlot, { id: "detail-below-price" })] }) }) }) }));
|
|
39
39
|
}
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
2
|
+
import "server-only";
|
|
3
|
+
// Lazy-load `renderToStaticMarkup` via `require()` to avoid Next.js's
|
|
4
|
+
// Server-Component static-trace error. Even with the `server-only`
|
|
5
|
+
// directive above, a top-level `import { renderToStaticMarkup } from
|
|
6
|
+
// "react-dom/server"` is flagged by Next.js when any module in the
|
|
7
|
+
// re-export chain is reachable from a Server Component (e.g. layout.tsx
|
|
8
|
+
// → providers.config.ts → @mohasinac/appkit/server → ... → email.tsx).
|
|
9
|
+
// `require()` is opaque to Next's static analyser so the chain stops here.
|
|
10
|
+
function renderToStaticMarkup(el) {
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
12
|
+
const m = require("react-dom/server");
|
|
13
|
+
return m.renderToStaticMarkup(el);
|
|
14
|
+
}
|
|
3
15
|
import { normalizeError } from "../../errors/normalize";
|
|
4
16
|
import { getProviders } from "../../contracts";
|
|
5
17
|
import { serverLogger } from "../../monitoring";
|
|
6
18
|
import { currentYear, formatCurrency, formatDateTime, nowMs, } from "../../utils";
|
|
7
|
-
import { EmailButton, EmailContainer, EmailDivider, EmailDoc, EmailFooter, EmailHeader, EmailLink, EmailRow, } from "../email/primitives";
|
|
19
|
+
import { EmailBold, EmailButton, EmailContainer, EmailDivider, EmailDoc, EmailFooter, EmailHeader, EmailLink, EmailRow, } from "../email/primitives";
|
|
8
20
|
function getSiteName() {
|
|
9
21
|
return process.env.NEXT_PUBLIC_SITE_NAME?.trim() || "App";
|
|
10
22
|
}
|
|
@@ -84,7 +96,7 @@ export async function sendPasswordResetEmailWithLink(email, resetLink) {
|
|
|
84
96
|
}
|
|
85
97
|
function renderOrderItems(items, productTitle, quantity, currency) {
|
|
86
98
|
if (items && items.length > 1) {
|
|
87
|
-
return (_jsxs(_Fragment, { children: [_jsxs("p", { style: { ...PARA_STYLE, fontWeight: 600 }, children: ["Items (", items.length, ")"] }), items.map((item, idx) => (_jsxs("p", { style: PARA_STYLE, children: [item.productTitle, " \u00D7 ", item.quantity, " \u2014", " ", _jsx(
|
|
99
|
+
return (_jsxs(_Fragment, { children: [_jsxs("p", { style: { ...PARA_STYLE, fontWeight: 600 }, children: ["Items (", items.length, ")"] }), items.map((item, idx) => (_jsxs("p", { style: PARA_STYLE, children: [item.productTitle, " \u00D7 ", item.quantity, " \u2014", " ", _jsx(EmailBold, { children: formatCurrency(item.totalPrice, currency) })] }, item.productId ?? idx)))] }));
|
|
88
100
|
}
|
|
89
101
|
return (_jsxs(_Fragment, { children: [_jsxs("p", { style: PARA_STYLE, children: [_jsx("span", { style: LABEL_STYLE, children: "Product:" }), " ", _jsx("span", { style: VALUE_STYLE, children: productTitle })] }), _jsxs("p", { style: PARA_STYLE, children: [_jsx("span", { style: LABEL_STYLE, children: "Quantity:" }), " ", _jsx("span", { style: VALUE_STYLE, children: quantity })] })] }));
|
|
90
102
|
}
|
|
@@ -150,7 +162,7 @@ export async function sendDigitalCodeClaimedEmail(params) {
|
|
|
150
162
|
const siteUrl = getSiteUrl();
|
|
151
163
|
const { to, userName, productTitle, orderId } = params;
|
|
152
164
|
const orderUrl = `${siteUrl}/user/orders/view/${orderId}`;
|
|
153
|
-
const html = `<!DOCTYPE html>${renderToStaticMarkup(_jsx(EmailDoc, { title: "Your digital code is ready", children: _jsxs(EmailContainer, { children: [_jsx(EmailHeader, { brandName: siteName, children: "Your Digital Code Is Ready \uD83D\uDD11" }), _jsxs(EmailRow, { children: [_jsxs("p", { style: PARA_STYLE, children: ["Hi ", userName, ","] }), _jsxs("p", { style: PARA_STYLE, children: ["Your digital code for ", _jsx(
|
|
165
|
+
const html = `<!DOCTYPE html>${renderToStaticMarkup(_jsx(EmailDoc, { title: "Your digital code is ready", children: _jsxs(EmailContainer, { children: [_jsx(EmailHeader, { brandName: siteName, children: "Your Digital Code Is Ready \uD83D\uDD11" }), _jsxs(EmailRow, { children: [_jsxs("p", { style: PARA_STYLE, children: ["Hi ", userName, ","] }), _jsxs("p", { style: PARA_STYLE, children: ["Your digital code for ", _jsx(EmailBold, { children: productTitle }), " has been assigned to your order and is ready to reveal."] }), _jsxs("p", { style: PARA_STYLE, children: [_jsx("span", { style: LABEL_STYLE, children: "Order ID:" }), " ", _jsx("span", { style: VALUE_STYLE, children: orderId })] }), _jsxs("p", { style: PARA_STYLE, children: [_jsx("span", { style: LABEL_STYLE, children: "Product:" }), " ", _jsx("span", { style: VALUE_STYLE, children: productTitle })] }), _jsx(EmailDivider, { spacing: "md" }), _jsx(EmailButton, { href: orderUrl, children: "Reveal your code" }), _jsxs("p", { style: { ...PARA_STYLE, color: "#71717a" }, children: ["For security, the code is only shown inside your ", siteName, " ", "account."] })] }), _jsx(EmailFooter, { copyright: `© ${currentYear()} ${siteName}. All rights reserved.` })] }) }))}`;
|
|
154
166
|
try {
|
|
155
167
|
const { error } = await sendConfiguredEmail({
|
|
156
168
|
to,
|
|
@@ -178,7 +190,7 @@ export async function sendSiteSettingsChangedEmail(params) {
|
|
|
178
190
|
return { success: false };
|
|
179
191
|
const settingsUrl = `${siteUrl}/admin/site-settings`;
|
|
180
192
|
const timestamp = formatDateTime(nowMs());
|
|
181
|
-
const html = `<!DOCTYPE html>${renderToStaticMarkup(_jsx(EmailDoc, { title: "Site settings changed", children: _jsxs(EmailContainer, { children: [_jsx(EmailHeader, { brandName: siteName, children: "Site Settings Changed \u2699\uFE0F" }), _jsxs(EmailRow, { children: [_jsxs("p", { style: PARA_STYLE, children: [_jsx(
|
|
193
|
+
const html = `<!DOCTYPE html>${renderToStaticMarkup(_jsx(EmailDoc, { title: "Site settings changed", children: _jsxs(EmailContainer, { children: [_jsx(EmailHeader, { brandName: siteName, children: "Site Settings Changed \u2699\uFE0F" }), _jsxs(EmailRow, { children: [_jsxs("p", { style: PARA_STYLE, children: [_jsx(EmailBold, { children: changedByEmail }), " has updated the following site settings:"] }), _jsxs("p", { style: PARA_STYLE, children: [_jsx("span", { style: LABEL_STYLE, children: "Changed fields:" }), " ", _jsx("span", { style: VALUE_STYLE, children: changedFields.join(", ") })] }), _jsxs("p", { style: PARA_STYLE, children: [_jsx("span", { style: LABEL_STYLE, children: "Changed by:" }), " ", _jsx("span", { style: VALUE_STYLE, children: changedByEmail })] }), _jsxs("p", { style: PARA_STYLE, children: [_jsx("span", { style: LABEL_STYLE, children: "Timestamp:" }), " ", _jsx("span", { style: VALUE_STYLE, children: timestamp })] }), _jsx(EmailDivider, { spacing: "md" }), _jsx(EmailButton, { href: settingsUrl, children: "View settings" })] }), _jsx(EmailFooter, { copyright: `© ${currentYear()} ${siteName}. Automated notification — do not reply.` })] }) }))}`;
|
|
182
194
|
try {
|
|
183
195
|
const { data, error } = await sendConfiguredEmail({
|
|
184
196
|
to: adminEmails,
|
|
@@ -16,11 +16,11 @@ const LBL_CONVERSATION_ID = "Conversation ID";
|
|
|
16
16
|
const CLS_ERROR_TEXT = "text-center text-sm text-error";
|
|
17
17
|
function MessageBubble({ msg }) {
|
|
18
18
|
const isUser = msg.role === "user";
|
|
19
|
-
return (_jsx(Div, { layout: "flex", justify: isUser ? "end" : "start", children: _jsxs(Div, { textSize: "sm", className: `max-w-[80%] py-
|
|
19
|
+
return (_jsx(Div, { layout: "flex", justify: isUser ? "end" : "start", children: _jsxs(Div, { textSize: "sm", className: `max-w-[80%] py-[0.625rem] ${isUser ? "bg-primary text-white" : "bg-neutral-100 dark:bg-[var(--appkit-color-surface-elevated)] text-neutral-900 dark:text-neutral-100"}`, padding: "x-md", style: { borderRadius: isUser ? "1.5rem 0.125rem 1.5rem 1.5rem" : "0.125rem 1.5rem 1.5rem 1.5rem" }, children: [_jsx(Text, { className: "whitespace-pre-wrap leading-relaxed", size: "sm", children: msg.content }), msg.durationMs ? (_jsxs(Span, { size: "xs", className: "mt-1 block opacity-60", children: [(msg.durationMs / 1000).toFixed(1), "s"] })) : null] }) }));
|
|
20
20
|
}
|
|
21
21
|
function renderCopilotChatPanel(props) {
|
|
22
22
|
const { messages, conversationId, isLoading, error, input, setInput, labels, messagesEndRef, handleSubmit } = props;
|
|
23
|
-
return (_jsxs(Stack, { className: "border border-neutral-200 h-[calc(100vh-300px)]", surface: "default", rounded: "xl", children: [_jsx(Div, { border: "bottom", className: __P.p3, children: _jsxs(Text, { className: "text-neutral-500 dark:text-neutral-400", size: "xs", weight: "medium", children: [labels?.conversationId ?? LBL_CONVERSATION_ID, ": ", conversationId] }) }), _jsxs(Stack, { className: `flex-1 ${__O.yAuto} ${__P.p4}`, gap: "md", children: [messages.length === 0 ? (_jsxs(Stack, { justify: "center", className: "h-full text-center", align: "center", children: [_jsx(Text, { weight: "medium", children: labels?.noMessages ?? "No messages yet" }), _jsx(Text, { variant: "secondary", className: "mt-1", size: "sm", children: labels?.noMessagesDesc ?? "Ask anything to get started" })] })) : null, messages.map((msg) => _jsx(MessageBubble, { msg: msg }, msg.id)), isLoading ? (_jsx(Row, { justify: "start", children: _jsx(Div, { paddingY: "y-xs-tall", surface: "muted", className: "
|
|
23
|
+
return (_jsxs(Stack, { className: "border border-neutral-200 h-[calc(100vh-300px)]", surface: "default", rounded: "xl", children: [_jsx(Div, { border: "bottom", className: __P.p3, children: _jsxs(Text, { className: "text-neutral-500 dark:text-neutral-400", size: "xs", weight: "medium", children: [labels?.conversationId ?? LBL_CONVERSATION_ID, ": ", conversationId] }) }), _jsxs(Stack, { className: `flex-1 ${__O.yAuto} ${__P.p4}`, gap: "md", children: [messages.length === 0 ? (_jsxs(Stack, { justify: "center", className: "h-full text-center", align: "center", children: [_jsx(Text, { weight: "medium", children: labels?.noMessages ?? "No messages yet" }), _jsx(Text, { variant: "secondary", className: "mt-1", size: "sm", children: labels?.noMessagesDesc ?? "Ask anything to get started" })] })) : null, messages.map((msg) => _jsx(MessageBubble, { msg: msg }, msg.id)), isLoading ? (_jsx(Row, { justify: "start", children: _jsx(Div, { paddingY: "y-xs-tall", surface: "muted", className: "", padding: "x-md", style: { borderRadius: "0.125rem 1.5rem 1.5rem 1.5rem" }, children: _jsx(Span, { size: "sm", className: "opacity-60 animate-pulse", children: "Thinking..." }) }) })) : null, error ? _jsx(Text, { className: CLS_ERROR_TEXT, children: labels?.errorLabel ?? "An error occurred. Please try again." }) : null, _jsx(Div, { ref: messagesEndRef })] }), _jsx(Div, { border: "top", className: __P.p3, children: _jsxs("form", { onSubmit: handleSubmit, className: "flex gap-2", children: [_jsx("input", { type: "text", value: input, onChange: (e) => setInput(e.target.value), placeholder: labels?.inputPlaceholder ?? "Ask anything...", disabled: isLoading, className: "flex-1 h-10 rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition disabled:opacity-60" }), _jsx(Button, { type: "submit", variant: "primary", disabled: isLoading || !input.trim(), className: "shrink-0", children: isLoading ? labels?.sendingButton ?? "Sending..." : labels?.sendButton ?? "Send" })] }) })] }));
|
|
24
24
|
}
|
|
25
25
|
function renderCopilotHistoryPanel(props) {
|
|
26
26
|
const { historyQuery, conversationInput, setConversationInput, loadConversation, labels } = props;
|
|
@@ -49,7 +49,7 @@ export function AdminCopilotView({ endpoint, historyEndpoint = "/api/copilot/his
|
|
|
49
49
|
};
|
|
50
50
|
return (_jsx(StackedViewShell, { portal: "admin", title: labels.title ?? "AI Copilot", className: className, sections: [
|
|
51
51
|
renderHeader ? (renderHeader(startNewConversation)) : (_jsxs(Row, { align: "center", justify: "between", gap: "3", children: [_jsx(Heading, { level: 2, children: labels.title ?? "AI Copilot" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: startNewConversation, children: labels.newConversation ?? "New Conversation" })] })),
|
|
52
|
-
_jsxs(Div, { layout: "grid", gap: "4", className: "grid-cols-1 lg:grid-cols-[2fr,1fr]", children: [_jsxs(Stack, { className: "border border-neutral-200 h-[calc(100vh-300px)]", surface: "default", rounded: "xl", children: [_jsx(Div, { border: "bottom", className: __P.p3, children: _jsxs(Text, { className: "text-neutral-500 dark:text-neutral-400", size: "xs", weight: "medium", children: [labels.conversationId ?? LBL_CONVERSATION_ID, ": ", conversationId] }) }), _jsxs(Stack, { className: `flex-1 ${__O.yAuto} ${__P.p4}`, gap: "md", children: [messages.length === 0 ? (_jsxs(Stack, { justify: "center", className: "h-full text-center", align: "center", children: [_jsx(Text, { weight: "medium", children: labels.noMessages ?? "No messages yet" }), _jsx(Text, { variant: "secondary", className: "mt-1", size: "sm", children: labels.noMessagesDesc ?? "Ask anything to get started" })] })) : null, messages.map((msg) => (_jsx(MessageBubble, { msg: msg }, msg.id))), isLoading ? (_jsx(Row, { justify: "start", children: _jsx(Div, { paddingY: "y-xs-tall", surface: "muted", className: "
|
|
52
|
+
_jsxs(Div, { layout: "grid", gap: "4", className: "grid-cols-1 lg:grid-cols-[2fr,1fr]", children: [_jsxs(Stack, { className: "border border-neutral-200 h-[calc(100vh-300px)]", surface: "default", rounded: "xl", children: [_jsx(Div, { border: "bottom", className: __P.p3, children: _jsxs(Text, { className: "text-neutral-500 dark:text-neutral-400", size: "xs", weight: "medium", children: [labels.conversationId ?? LBL_CONVERSATION_ID, ": ", conversationId] }) }), _jsxs(Stack, { className: `flex-1 ${__O.yAuto} ${__P.p4}`, gap: "md", children: [messages.length === 0 ? (_jsxs(Stack, { justify: "center", className: "h-full text-center", align: "center", children: [_jsx(Text, { weight: "medium", children: labels.noMessages ?? "No messages yet" }), _jsx(Text, { variant: "secondary", className: "mt-1", size: "sm", children: labels.noMessagesDesc ?? "Ask anything to get started" })] })) : null, messages.map((msg) => (_jsx(MessageBubble, { msg: msg }, msg.id))), isLoading ? (_jsx(Row, { justify: "start", children: _jsx(Div, { paddingY: "y-xs-tall", surface: "muted", className: "", padding: "x-md", style: { borderRadius: "0.125rem 1.5rem 1.5rem 1.5rem" }, children: _jsx(Span, { size: "sm", className: "opacity-60 animate-pulse", children: "Thinking..." }) }) })) : null, error ? (_jsx(Text, { className: CLS_ERROR_TEXT, children: labels.errorLabel ?? "An error occurred. Please try again." })) : null, _jsx(Div, { ref: messagesEndRef })] }), _jsx(Div, { border: "top", className: __P.p3, children: _jsxs("form", { onSubmit: handleSubmit, className: "flex gap-2", children: [_jsx("input", { type: "text", value: input, onChange: (event) => setInput(event.target.value), placeholder: labels.inputPlaceholder ?? "Ask anything...", disabled: isLoading, className: "flex-1 h-10 rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition disabled:opacity-60" }), _jsx(Button, { type: "submit", variant: "primary", disabled: isLoading || !input.trim(), className: "shrink-0", children: isLoading ? labels.sendingButton ?? "Sending..." : labels.sendButton ?? "Send" })] }) })] }), _jsxs(Stack, { surface: "card", padding: "sm", gap: "3", children: [_jsx(Heading, { level: 3, size: "sm", weight: "semibold", children: labels.historyTitle ?? "Conversation History" }), _jsxs("form", { className: "space-y-2", onSubmit: (event) => {
|
|
53
53
|
event.preventDefault();
|
|
54
54
|
if (!conversationInput.trim())
|
|
55
55
|
return;
|
|
@@ -87,4 +87,8 @@ export interface EmailFooterProps {
|
|
|
87
87
|
contactEmail?: string;
|
|
88
88
|
unsubscribeUrl?: string;
|
|
89
89
|
}
|
|
90
|
+
/** Inline bold span for email bodies — uses inline fontWeight because email clients ignore CSS classes. */
|
|
91
|
+
export declare function EmailBold({ children }: {
|
|
92
|
+
children: React.ReactNode;
|
|
93
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
90
94
|
export declare function EmailFooter({ copyright, contactEmail, unsubscribeUrl, }: EmailFooterProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -112,6 +112,10 @@ export function EmailDivider({ spacing = "md" }) {
|
|
|
112
112
|
margin: 0,
|
|
113
113
|
} }) }) }));
|
|
114
114
|
}
|
|
115
|
+
/** Inline bold span for email bodies — uses inline fontWeight because email clients ignore CSS classes. */
|
|
116
|
+
export function EmailBold({ children }) {
|
|
117
|
+
return _jsx("span", { style: { fontWeight: 700 }, children: children });
|
|
118
|
+
}
|
|
115
119
|
export function EmailFooter({ copyright, contactEmail, unsubscribeUrl, }) {
|
|
116
120
|
return (_jsx("tr", { children: _jsxs("td", { align: "center", style: {
|
|
117
121
|
padding: "16px 32px 24px",
|
|
@@ -31,6 +31,6 @@ 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, { border: "default", className: `group relative
|
|
35
|
-
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, { rounded: "lg", type: "button", onClick: () => onParticipate(event), className: "w-full bg-primary py-2 text-sm font-medium text-white transition-colors hover:bg-primary-600", children: labels.participate ?? "Participate" })) : (_jsxs(TextLink, { rounded: "lg", paddingX: "sm", paddingY: "xs", href: detailHref,
|
|
34
|
+
return (_jsxs(Article, { border: "default", rounded: "xl", shadow: "hover-md", className: `group relative h-full ${LAYOUT.cardHeight.event} overflow-hidden bg-[var(--appkit-color-surface)] ${isSelected ? "border-primary outline outline-2 outline-primary" : " "} ${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("img", { src: event.coverImageUrl, alt: safeTitle, className: "h-full w-full object-cover transition-transform duration-300 group-hover:scale-105" }) })) : (_jsx(Row, { surface: "muted", className: "aspect-video", align: "center", justify: "center", children: _jsx(Span, { className: "opacity-40", size: "5xl", "aria-hidden": "true", children: TYPE_ICONS[event.type] }) })) }), _jsxs(Stack, { className: `flex-1 ${__P.p4}`, children: [_jsxs(Row, { className: "mb-2", align: "start", justify: "between", gap: "sm", 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: "text-gray-900 leading-snug mb-1 group-hover:text-primary transition-colors", size: "base", weight: "semibold", 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 line-clamp-3 text-sm text-zinc-600 dark:text-zinc-400" }), _jsxs(Row, { color: "muted", textSize: "xs", className: "mb-3 mt-auto", align: "center", justify: "between", children: [event.status === EVENT_FIELDS.STATUS_VALUES.ACTIVE &&
|
|
35
|
+
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, { rounded: "lg", type: "button", onClick: () => onParticipate(event), className: "w-full bg-primary py-2 text-sm font-medium text-white transition-colors hover:bg-primary-600", children: labels.participate ?? "Participate" })) : (_jsxs(TextLink, { rounded: "lg", paddingX: "sm", paddingY: "xs", href: detailHref, layout: "inline-flex", align: "center", justify: "center", gap: "xs", className: "w-full border border-[var(--appkit-color-border)] transition-colors hover:bg-[var(--appkit-color-bg)]", color: "primary", size: "sm", weight: "medium", children: [labels.viewDetails ?? "View details", " \u2192"] }))] })] }));
|
|
36
36
|
}
|
|
@@ -28,5 +28,5 @@ export function EventOfferCard({ couponCode, offerDescription, title = "Exclusiv
|
|
|
28
28
|
/* clipboard unavailable — leave button as-is */
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
|
-
return (_jsx(Div, { className: `${__P.p6}`, rounded: "2xl", border: "default", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, weight: "semibold", size: "2xl", children: title }), offerDescription ? (_jsx(Text, { size: "sm", color: "muted", children: offerDescription })) : null] }), _jsxs(Row, { surface: "muted", padding: "inline", align: "center", gap: "3", rounded: "lg", children: [_jsx(Code, { className: "flex-1
|
|
31
|
+
return (_jsx(Div, { className: `${__P.p6}`, rounded: "2xl", border: "default", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, weight: "semibold", size: "2xl", children: title }), offerDescription ? (_jsx(Text, { size: "sm", color: "muted", children: offerDescription })) : null] }), _jsxs(Row, { surface: "muted", padding: "inline", align: "center", gap: "3", rounded: "lg", children: [_jsx(Code, { className: "flex-1", weight: "bold", size: "base", color: "primary", children: couponCode }), _jsx(Button, { type: "button", variant: "outline", onClick: copyCode, children: copied ? "Copied!" : "Copy code" })] }), _jsx(Div, { children: _jsx(Link, { href: href, children: _jsx(Button, { variant: "primary", children: "Apply at checkout" }) }) })] }) }));
|
|
32
32
|
}
|
|
@@ -38,5 +38,5 @@ export function EventRaffleEntryForm({ eventId: _eventId, prizeLabel, raffleType
|
|
|
38
38
|
: raffleType === "top_n_participants"
|
|
39
39
|
? `Earliest ${topN ?? "N"} entries qualify.`
|
|
40
40
|
: "Spin the wheel to claim your prize.";
|
|
41
|
-
return (_jsxs(Stack, { className: `${__P.p6}`, gap: "md", rounded: "2xl", border: "default", children: [prizeLabel ? (_jsxs(Stack, { gap: "xs", children: [_jsx(Badge, { variant: "warning", children: "Prize" }), _jsx(Heading, { level: 2, weight: "bold", size: "2xl", children: prizeLabel })] })) : null, _jsx(Text, { size: "sm", color: "muted", children: eligibilityCopy }), submitted ? (_jsx(Div, { textSize: "sm", color: "success", surface: "success-surface", padding: "inline", rounded: "lg", children: "You're in. Check the leaderboard for results." })) : overLimit ? (_jsxs(Div, { textSize: "sm", color: "warning", surface: "warning-surface", padding: "inline", rounded: "lg", children: ["You've used all ", maxEntriesPerUser, " entry slot", maxEntriesPerUser === 1 ? "" : "s", " for this raffle."] })) : (_jsxs(Form, { onSubmit: handleSubmit, className: "space-y-
|
|
41
|
+
return (_jsxs(Stack, { className: `${__P.p6}`, gap: "md", rounded: "2xl", border: "default", children: [prizeLabel ? (_jsxs(Stack, { gap: "xs", children: [_jsx(Badge, { variant: "warning", children: "Prize" }), _jsx(Heading, { level: 2, weight: "bold", size: "2xl", children: prizeLabel })] })) : null, _jsx(Text, { size: "sm", color: "muted", children: eligibilityCopy }), submitted ? (_jsx(Div, { textSize: "sm", color: "success", surface: "success-surface", padding: "inline", rounded: "lg", children: "You're in. Check the leaderboard for results." })) : overLimit ? (_jsxs(Div, { textSize: "sm", color: "warning", surface: "warning-surface", padding: "inline", rounded: "lg", children: ["You've used all ", maxEntriesPerUser, " entry slot", maxEntriesPerUser === 1 ? "" : "s", " for this raffle."] })) : (_jsxs(Form, { onSubmit: handleSubmit, className: "space-y-[0.75rem]", children: [_jsx(FieldTextarea, { name: "message", label: "Message", hint: "optional \u2014 share why you'd like to win", value: message, onChange: setMessage, rows: 3, maxLength: 500, placeholder: "Share why you'd like to win", disabled: busy }), _jsx(Button, { type: "submit", variant: "primary", disabled: busy, children: busy ? "Submitting…" : "Enter raffle" })] }))] }));
|
|
42
42
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Article, ClaimCouponButton, Div, Heading, Span, Text, TextLink } from "../../../ui";
|
|
2
|
+
import { Article, ClaimCouponButton, Div, Heading, Row, Span, Stack, Text, TextLink } from "../../../ui";
|
|
3
3
|
const __P = {
|
|
4
4
|
p4: "p-4",
|
|
5
5
|
};
|
|
@@ -20,5 +20,5 @@ export function EventRaffleWinnerView({ event, currentUserIsWinner, labels }) {
|
|
|
20
20
|
if (!event.raffleWinnerUserId) {
|
|
21
21
|
return (_jsx(Div, { className: "border-dashed text-center", border: "strong", paddingY: "y-2xl", paddingX: "x-lg", rounded: "xl", children: _jsx(Text, { color: "muted", children: l.notDrawnYet }) }));
|
|
22
22
|
}
|
|
23
|
-
return (
|
|
23
|
+
return (_jsx(Article, { children: _jsxs(Stack, { gap: "lg", children: [_jsxs(Heading, { level: 2, size: "xl", weight: "semibold", color: "primary", children: ["\uD83C\uDF9F\uFE0F ", l.heading] }), _jsxs(Div, { className: CLS_PANEL, children: [_jsxs(Div, { children: [_jsx(Text, { className: CLS_LABEL, children: l.winnerLabel }), _jsx(Text, { className: CLS_WINNER_NAME, children: event.raffleWinnerDisplayName?.trim() || l.anonymous })] }), event.rafflePrize ? (_jsxs(Div, { children: [_jsx(Text, { className: CLS_LABEL, children: l.prizeLabel }), _jsx(Text, { className: "mt-1", color: "primary", size: "base", children: event.rafflePrize })] })) : null, currentUserIsWinner && event.rafflePrizeCouponCode ? (_jsx(Div, { padding: "t-xs", children: _jsx(ClaimCouponButton, { couponCode: event.rafflePrizeCouponCode, source: "raffle", size: "sm" }) })) : null, _jsxs(Row, { wrap: true, textSize: "sm", className: "gap-x-6 gap-y-2", color: "muted", padding: "t-xs", children: [typeof event.raffleEntryCount === "number" ? (_jsxs(Span, { children: [l.poolLabel, ":", " ", _jsx(Span, { weight: "medium", color: "primary", children: event.raffleEntryCount })] })) : null, event.raffleTriggeredAt ? (_jsx(Span, { children: new Date(event.raffleTriggeredAt).toLocaleString() })) : null] })] }), event.raffleGithubFunctionUrl ? (_jsxs(Div, { textSize: "sm", className: `${__P.p4}`, rounded: "lg", border: "default", children: [_jsx(Text, { weight: "medium", color: "primary", children: l.fairnessLabel }), _jsx(TextLink, { href: event.raffleGithubFunctionUrl, className: "mt-1 block break-all text-primary-600 dark:text-primary-400 hover:underline", children: event.raffleGithubFunctionUrl })] })) : null] }) }));
|
|
24
24
|
}
|
|
@@ -414,14 +414,14 @@ export declare const eventListParamsSchema: z.ZodObject<{
|
|
|
414
414
|
status?: "draft" | "ended" | "active" | "paused" | undefined;
|
|
415
415
|
type?: "offer" | "feedback" | "sale" | "poll" | "survey" | undefined;
|
|
416
416
|
sort?: string | undefined;
|
|
417
|
-
q?: string | undefined;
|
|
418
417
|
page?: number | undefined;
|
|
418
|
+
q?: string | undefined;
|
|
419
419
|
perPage?: number | undefined;
|
|
420
420
|
}, {
|
|
421
421
|
status?: "draft" | "ended" | "active" | "paused" | undefined;
|
|
422
422
|
type?: "offer" | "feedback" | "sale" | "poll" | "survey" | undefined;
|
|
423
423
|
sort?: string | undefined;
|
|
424
|
-
q?: string | undefined;
|
|
425
424
|
page?: number | undefined;
|
|
425
|
+
q?: string | undefined;
|
|
426
426
|
perPage?: number | undefined;
|
|
427
427
|
}>;
|
|
@@ -6,5 +6,5 @@ const __P = {
|
|
|
6
6
|
const CLS_CONTACT_CARD = "flex items-center gap-3 rounded-lg border border-zinc-100 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800 px-4 py-3 hover:border-primary/40 transition-colors";
|
|
7
7
|
const CLS_CONTACT_LABEL = "text-xs text-zinc-500 dark:text-zinc-400";
|
|
8
8
|
export function ContactCTA({ email, phone, contactHref, labels, }) {
|
|
9
|
-
return (_jsxs(Card, { variant: "outlined", padding: "lg", className: "text-center
|
|
9
|
+
return (_jsxs(Card, { variant: "outlined", padding: "lg", className: "text-center", children: [_jsx(Row, { className: "mb-6", justify: "center", children: _jsx(Div, { className: `bg-primary/10 ${__P.p8}`, rounded: "full", children: _jsx("svg", { className: "h-12 w-12 text-primary", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" }) }) }) }), _jsx(Heading, { level: 2, className: "mb-3", size: "2xl", weight: "semibold", children: labels?.title ?? "Need More Help?" }), _jsx(Text, { className: "mx-auto mb-6 max-w-2xl", color: "muted", children: labels?.description ?? "Our support team is here to help you." }), _jsxs(Div, { layout: "grid", gap: "4", className: "mb-8 grid-cols-1 md:grid-cols-3", children: [_jsxs(TextLink, { href: `mailto:${email}`, variant: "none", className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.emailUs ?? "Email Us" }), _jsx(Text, { size: "xs", color: "muted", children: email })] }), _jsxs(TextLink, { href: `tel:${phone}`, variant: "none", className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.callUs ?? "Call Us" }), _jsx(Text, { size: "xs", color: "muted", children: phone })] }), _jsxs(TextLink, { href: contactHref, className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.contactForm ?? "Contact Form" }), _jsx(Text, { size: "xs", color: "muted", children: labels?.submitRequest ?? "Submit a request" })] })] }), _jsxs(TextLink, { rounded: "xl", href: contactHref, layout: "inline-flex", align: "center", gap: "sm", className: "bg-primary p-[1.5rem] text-white transition-colors hover:bg-primary/90", weight: "medium", children: [_jsx(Span, { children: labels?.contactTeam ?? "Contact Team" }), _jsx("svg", { className: "h-5 w-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })] })] }));
|
|
10
10
|
}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { Button, Div, RichText, Row, Span, Text } from "../../../ui";
|
|
5
5
|
function FAQAccordionItem({ faq, isOpen, onToggle, renderExpandedFooter, }) {
|
|
6
|
-
return (_jsxs(Div, { className: "border-b border-neutral-200 last:border-0", children: [_jsxs(Button, { variant: "ghost", onClick: onToggle, "aria-expanded": isOpen, className: "w-full justify-between gap-
|
|
6
|
+
return (_jsxs(Div, { className: "border-b border-neutral-200 last:border-0", children: [_jsxs(Button, { variant: "ghost", onClick: onToggle, "aria-expanded": isOpen, className: "w-full justify-[space-between] gap-[1rem] py-[1rem] text-left text-[0.875rem] font-[500] text-neutral-900 dark:text-[var(--appkit-color-text)] transition hover:text-primary", children: [_jsx(Span, { children: faq.question }), _jsx(Span, { className: `flex-shrink-0 transition-transform ${isOpen ? "rotate-180" : ""}`, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }), isOpen && (_jsxs(Div, { textSize: "sm", className: "text-neutral-600 dark:text-neutral-400", padding: "b-md", children: [faq.tags && faq.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-3", children: faq.tags.map((tag) => (_jsx(Span, { className: "bg-neutral-100 dark:bg-neutral-800 py-[0.25rem] text-neutral-600 dark:text-neutral-400", rounded: "md", padding: "x-xs", size: "xs", children: tag }, tag))) })), faq.answer.format === "html" ? (_jsx(RichText, { html: faq.answer.text, className: "prose-sm" })) : (_jsx(Text, { className: "whitespace-pre-line", children: faq.answer.text })), renderExpandedFooter?.(faq)] }))] }));
|
|
7
7
|
}
|
|
8
8
|
export function FAQAccordion({ faqs, className = "", renderExpandedFooter, labels, }) {
|
|
9
9
|
const [openId, setOpenId] = useState(null);
|
|
@@ -13,5 +13,5 @@ export function FAQAccordion({ faqs, className = "", renderExpandedFooter, label
|
|
|
13
13
|
return (_jsx(Div, { surface: "card", className: `divide-y divide-neutral-100 dark:divide-slate-700 ${className}`, padding: "x-md", children: faqs.map((faq) => (_jsx(FAQAccordionItem, { faq: faq, isOpen: openId === faq.id, onToggle: () => setOpenId(openId === faq.id ? null : faq.id), renderExpandedFooter: renderExpandedFooter }, faq.id))) }));
|
|
14
14
|
}
|
|
15
15
|
export function FAQCategoryTabs({ categories, active, onSelect, labels = {}, }) {
|
|
16
|
-
return (_jsxs(Row, { wrap: true, gap: "sm", className: "scrollbar-none", children: [_jsx(Button, { onClick: () => onSelect(null), className: `rounded-
|
|
16
|
+
return (_jsxs(Row, { wrap: true, gap: "sm", className: "scrollbar-none", children: [_jsx(Button, { onClick: () => onSelect(null), className: `rounded-[9999px] px-[1rem] py-[0.375rem] text-[0.875rem] font-[500] transition ${!active ? "bg-neutral-900 text-white" : "bg-neutral-100 dark:bg-slate-800 text-[var(--appkit-color-text-muted)] dark:text-[var(--appkit-color-text-faint)] hover:bg-neutral-200 dark:hover:bg-slate-700"}`, children: labels.all ?? "All" }), categories.map((cat) => (_jsx(Button, { onClick: () => onSelect(cat), className: `whitespace-nowrap rounded-[9999px] px-[1rem] py-[0.375rem] text-[0.875rem] font-[500] capitalize transition ${active === cat ? "bg-neutral-900 text-white" : "bg-neutral-100 dark:bg-slate-800 text-[var(--appkit-color-text-muted)] dark:text-[var(--appkit-color-text-faint)] hover:bg-neutral-200 dark:hover:bg-slate-700"}`, children: labels[cat] ?? cat.replace(/_/g, " ") }, cat)))] }));
|
|
17
17
|
}
|
|
@@ -2,9 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Card, Div, Heading, Row, Span, Text, TextLink } from "../../../ui";
|
|
3
3
|
export function FAQCategorySidebar({ selectedCategory, onCategorySelect, categoryCounts, categories, allFaqsHref = "/faqs", categoryHref, contactHref, labels, }) {
|
|
4
4
|
const totalCount = Object.values(categoryCounts).reduce((sum, count) => sum + count, 0);
|
|
5
|
-
return (_jsxs(Card, { variant: "outlined", padding: "lg",
|
|
5
|
+
return (_jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Heading, { level: 2, className: "mb-6", size: "lg", weight: "semibold", children: labels?.title ?? "Categories" }), _jsx(TextLink, { rounded: "lg", href: allFaqsHref, onClick: () => onCategorySelect?.("all"), className: `mb-3 block w-full p-4 text-left transition-colors ${selectedCategory === "all" ? "bg-primary/10 text-zinc-900 dark:text-zinc-100" : "text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-slate-700"}`, children: _jsxs(Row, { justify: "between", children: [_jsxs(Row, { gap: "3", children: [_jsx(Span, { size: "2xl", children: "FAQ" }), _jsx(Span, { size: "sm", weight: "medium", children: labels?.allFaqs ?? "All FAQs" })] }), _jsx(Span, { size: "xs", color: "muted", children: totalCount })] }) }), _jsx(Div, { border: "default", className: "mt-4 border-t", padding: "t-md", children: categories.map((category) => {
|
|
6
6
|
const isSelected = selectedCategory === category.key;
|
|
7
7
|
const count = categoryCounts[category.key] || 0;
|
|
8
8
|
return (_jsxs(TextLink, { rounded: "lg", href: categoryHref(category.key), onClick: () => onCategorySelect?.(category.key), className: `mb-3 block w-full p-4 text-left transition-colors ${isSelected ? "bg-primary/10 text-zinc-900 dark:text-zinc-100" : "text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-slate-700"}`, children: [_jsxs(Row, { justify: "between", className: "mb-1", children: [_jsxs(Row, { gap: "3", children: [category.icon ? (_jsx(Span, { size: "2xl", children: category.icon })) : null, _jsx(Span, { size: "sm", children: category.label })] }), _jsx(Span, { size: "xs", color: "muted", children: count })] }), isSelected && category.description ? (_jsx(Text, { className: "ml-11", color: "muted", size: "xs", children: category.description })) : null] }, category.key));
|
|
9
|
-
}) }), contactHref ? (_jsxs(Div, { border: "default", className: "border-t", padding: "t-lg", children: [_jsx(Text, { className: "mb-3", color: "muted", size: "sm", children: labels?.stillHaveQuestions ?? "Still have questions?" }), _jsx(TextLink, { rounded: "lg", href: contactHref, className: "block bg-primary p-
|
|
9
|
+
}) }), contactHref ? (_jsxs(Div, { border: "default", className: "border-t", padding: "t-lg", children: [_jsx(Text, { className: "mb-3", color: "muted", size: "sm", children: labels?.stillHaveQuestions ?? "Still have questions?" }), _jsx(TextLink, { rounded: "lg", href: contactHref, className: "block bg-primary p-[1rem] text-center text-white transition-colors hover:bg-primary/90", weight: "medium", children: labels?.contactSupport ?? "Contact Support" })] })) : null] }));
|
|
10
10
|
}
|
|
@@ -41,11 +41,11 @@ export function FAQHelpfulButtons({ faqId, initialHelpful, initialNotHelpful, on
|
|
|
41
41
|
return (_jsxs(Div, { className: `${__P.p6}`, rounded: "lg", surface: "subtle", children: [_jsx(Text, { className: "mb-3", color: "muted", size: "sm", children: userVote
|
|
42
42
|
? (labels?.thanksForFeedback ?? "Thanks for your feedback")
|
|
43
43
|
: (labels?.wasThisHelpful ?? "Was this helpful?") }), _jsxs(Row, { gap: "3", children: [_jsxs(Button, { variant: "ghost", onClick: () => handleVote(true), disabled: isPending || userVote !== null, className: `flex-1 gap-2 rounded-lg p-4 transition-all ${userVote === "helpful"
|
|
44
|
-
? "bg-
|
|
44
|
+
? "bg-success text-white"
|
|
45
45
|
: userVote
|
|
46
46
|
? "cursor-not-allowed bg-zinc-200 text-zinc-500 opacity-50 dark:bg-slate-600 dark:text-zinc-400"
|
|
47
47
|
: "bg-white text-zinc-800 hover:bg-green-50 dark:bg-slate-800 dark:text-zinc-100 dark:hover:bg-green-900/20"}`, children: [_jsx(Span, { size: "sm", children: labels?.yes ?? "Yes" }), _jsxs(Span, { size: "sm", color: "muted", children: ["(", helpful, ")"] })] }), _jsxs(Button, { variant: "ghost", onClick: () => handleVote(false), disabled: isPending || userVote !== null, className: `flex-1 gap-2 rounded-lg p-4 transition-all ${userVote === "not-helpful"
|
|
48
|
-
? "bg-
|
|
48
|
+
? "bg-error text-white"
|
|
49
49
|
: userVote
|
|
50
50
|
? "cursor-not-allowed bg-zinc-200 text-zinc-500 opacity-50 dark:bg-slate-600 dark:text-zinc-400"
|
|
51
51
|
: "bg-white text-zinc-800 hover:bg-red-50 dark:bg-slate-800 dark:text-zinc-100 dark:hover:bg-red-900/20"}`, children: [_jsx(Span, { size: "sm", children: labels?.no ?? "No" }), _jsxs(Span, { size: "sm", color: "muted", children: ["(", notHelpful, ")"] })] })] })] }));
|
|
@@ -4,5 +4,5 @@ export function RelatedFAQs({ relatedFAQs, hrefForFaq, labels, }) {
|
|
|
4
4
|
if (!relatedFAQs || relatedFAQs.length === 0) {
|
|
5
5
|
return null;
|
|
6
6
|
}
|
|
7
|
-
return (_jsxs(Card, { variant: "outlined", padding: "lg",
|
|
7
|
+
return (_jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Heading, { level: 3, className: "mb-4", size: "lg", weight: "semibold", children: labels?.title ?? "Related Questions" }), _jsx(Stack, { gap: "3", children: relatedFAQs.map((faq) => (_jsx(TextLink, { rounded: "lg", href: hrefForFaq ? hrefForFaq(faq) : `/faqs#${faq.id}`, className: "group block bg-[var(--appkit-color-surface-elevated)] p-[1rem] transition-colors hover:bg-[var(--appkit-color-border-subtle)]", children: _jsxs(Row, { align: "start", gap: "3", children: [_jsx("svg", { className: "mt-0.5 h-5 w-5 flex-shrink-0 text-zinc-500 dark:text-zinc-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }), _jsx(Text, { className: "transition-colors group-hover:text-primary", color: "primary", size: "sm", children: faq.question }), _jsx("svg", { className: "ml-auto mt-0.5 h-4 w-4 flex-shrink-0 text-zinc-500 opacity-0 transition-opacity group-hover:opacity-100 dark:text-zinc-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })] }) }, faq.id))) })] }));
|
|
8
8
|
}
|
|
@@ -143,14 +143,14 @@ export declare const faqListParamsSchema: z.ZodObject<{
|
|
|
143
143
|
perPage: z.ZodOptional<z.ZodNumber>;
|
|
144
144
|
}, "strip", z.ZodTypeAny, {
|
|
145
145
|
category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
|
|
146
|
-
q?: string | undefined;
|
|
147
146
|
page?: number | undefined;
|
|
147
|
+
q?: string | undefined;
|
|
148
148
|
perPage?: number | undefined;
|
|
149
149
|
homepage?: boolean | undefined;
|
|
150
150
|
}, {
|
|
151
151
|
category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
|
|
152
|
-
q?: string | undefined;
|
|
153
152
|
page?: number | undefined;
|
|
153
|
+
q?: string | undefined;
|
|
154
154
|
perPage?: number | undefined;
|
|
155
155
|
homepage?: boolean | undefined;
|
|
156
156
|
}>;
|