@mohasinac/appkit 4.3.1 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/maintenance/views/AnalysisRunnerView.js +1 -1
- package/dist/_internal/client/features/maintenance/views/CloudLogsListView.js +1 -1
- package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +1 -1
- package/dist/_internal/client/features/maintenance/views/ServerErrorDetailView.js +1 -1
- package/dist/_internal/client/features/maintenance/views/ServerErrorsListView.js +1 -1
- package/dist/_internal/server/jobs/core/assignSpinPrize.d.ts +14 -3
- package/dist/_internal/server/jobs/core/assignSpinPrize.js +95 -56
- package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +8 -2
- package/dist/_internal/shared/actions/action-registry.js +15 -0
- package/dist/_internal/shared/features/brands/schema.d.ts +4 -4
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +4 -4
- package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
- package/dist/_internal/shared/features/reviews/schema.d.ts +2 -2
- package/dist/client.d.ts +36 -0
- package/dist/client.js +30 -0
- package/dist/constants/api-endpoints.d.ts +6 -0
- package/dist/constants/api-endpoints.js +2 -0
- package/dist/constants/field-names.d.ts +3 -0
- package/dist/constants/field-names.js +4 -0
- package/dist/features/about/components/DeveloperView.d.ts +16 -0
- package/dist/features/about/components/DeveloperView.js +29 -0
- package/dist/features/about/index.d.ts +2 -0
- package/dist/features/about/index.js +1 -0
- package/dist/features/account/schemas/index.d.ts +16 -16
- package/dist/features/addresses/schemas/index.d.ts +8 -8
- package/dist/features/admin/components/AdminAddressesView.js +1 -1
- package/dist/features/admin/components/AdminAllEventEntriesView.js +2 -2
- package/dist/features/admin/components/AdminArtView.js +1 -1
- package/dist/features/admin/components/AdminBidsView.js +2 -2
- package/dist/features/admin/components/AdminBlogView.js +2 -2
- package/dist/features/admin/components/AdminBrandsView.js +2 -2
- package/dist/features/admin/components/AdminBundlesView.js +2 -2
- package/dist/features/admin/components/AdminCartsView.js +2 -2
- package/dist/features/admin/components/AdminCategoriesView.js +2 -2
- package/dist/features/admin/components/AdminClassifiedView.js +1 -1
- package/dist/features/admin/components/AdminContactView.js +2 -2
- package/dist/features/admin/components/AdminCouponsView.js +2 -2
- package/dist/features/admin/components/AdminDigitalCodesView.js +1 -1
- package/dist/features/admin/components/AdminFaqsView.js +2 -2
- package/dist/features/admin/components/AdminFeaturesView.js +1 -1
- package/dist/features/admin/components/AdminGroupedListingsView.js +1 -1
- package/dist/features/admin/components/AdminHistoryView.js +1 -1
- package/dist/features/admin/components/AdminLiveView.js +1 -1
- package/dist/features/admin/components/AdminNewsletterView.js +2 -2
- package/dist/features/admin/components/AdminNotificationsView.js +2 -2
- package/dist/features/admin/components/AdminOrdersView.js +2 -2
- package/dist/features/admin/components/AdminPaymentMethodsView.js +1 -1
- package/dist/features/admin/components/AdminPayoutsView.js +2 -2
- package/dist/features/admin/components/AdminPrizeDrawsView.js +2 -2
- package/dist/features/admin/components/AdminProductsView.js +2 -2
- package/dist/features/admin/components/AdminReturnRequestsView.js +1 -1
- package/dist/features/admin/components/AdminReviewsView.js +2 -2
- package/dist/features/admin/components/AdminScammersView.js +2 -2
- package/dist/features/admin/components/AdminSessionsView.js +2 -2
- package/dist/features/admin/components/AdminStickersView.js +1 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +1 -1
- package/dist/features/admin/components/AdminStoresView.js +2 -2
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +1 -1
- package/dist/features/admin/components/AdminSupportTicketsView.js +2 -2
- package/dist/features/admin/components/AdminTeamView.js +2 -2
- package/dist/features/admin/components/AdminTesterChecklistView.js +2 -2
- package/dist/features/admin/components/AdminUsersView.js +2 -2
- package/dist/features/admin/components/AdminWishlistsView.js +1 -1
- package/dist/features/admin/hooks/useAdminListing.d.ts +1 -1
- package/dist/features/auth/hooks/useAuth.d.ts +1 -1
- package/dist/features/blog/actions/blog-actions.d.ts +14 -14
- package/dist/features/blog/schemas/index.d.ts +14 -14
- package/dist/features/cart/hooks/useAddToCart.d.ts +6 -2
- package/dist/features/cart/hooks/useAddToCart.js +20 -3
- package/dist/features/cart/schemas/index.d.ts +3 -3
- package/dist/features/cart/utils/pending-ops.d.ts +20 -0
- package/dist/features/cart/utils/pending-ops.js +22 -0
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +1 -1
- package/dist/features/categories/components/CategoryBundlesListing.js +1 -1
- package/dist/features/categories/components/CategoryFilters.js +1 -1
- package/dist/features/categories/components/CategoryTree.js +1 -1
- package/dist/features/categories/schemas/index.d.ts +16 -16
- package/dist/features/events/actions/event-actions.d.ts +21 -1
- package/dist/features/events/actions/event-actions.js +85 -3
- package/dist/features/events/components/AdminEventEditorView.js +11 -2
- package/dist/features/events/components/AdminEventEntriesView.js +37 -4
- package/dist/features/events/components/AdminEventsView.js +2 -2
- package/dist/features/events/components/EventLeaderboard.d.ts +12 -2
- package/dist/features/events/components/EventLeaderboard.js +4 -1
- package/dist/features/events/components/EventRafflesSection.js +2 -2
- package/dist/features/events/repository/event-entry.repository.d.ts +39 -0
- package/dist/features/events/repository/event-entry.repository.js +153 -0
- package/dist/features/events/schemas/firestore.d.ts +28 -1
- package/dist/features/events/schemas/firestore.js +9 -0
- package/dist/features/events/schemas/index.d.ts +13 -13
- package/dist/features/events/types/index.d.ts +26 -0
- package/dist/features/faq/actions/faq-actions.d.ts +8 -8
- package/dist/features/faq/schemas/index.d.ts +22 -22
- package/dist/features/grouped/schemas/index.d.ts +2 -2
- package/dist/features/homepage/components/AnnouncementBar.d.ts +9 -1
- package/dist/features/homepage/components/AnnouncementBar.js +6 -3
- package/dist/features/homepage/components/MarketplaceHomepageView.js +2 -2
- package/dist/features/homepage/components/SectionCarousel.js +5 -1
- package/dist/features/homepage/components/WelcomeSection.js +2 -2
- package/dist/features/homepage/schemas/index.d.ts +2 -2
- package/dist/features/layout/BottomNavbar.js +8 -6
- package/dist/features/lottery/schemas/zod.d.ts +10 -10
- package/dist/features/media/MediaVideo.js +11 -3
- package/dist/features/orders/schemas/index.d.ts +52 -52
- package/dist/features/products/components/CompareOverlay.d.ts +9 -0
- package/dist/features/products/components/CompareOverlay.js +28 -3
- package/dist/features/products/components/InteractiveProductCard.js +9 -3
- package/dist/features/products/components/MakeOfferForm.js +1 -1
- package/dist/features/products/components/PlaceBidForm.js +1 -1
- package/dist/features/products/components/PrizeDrawCollage.js +1 -1
- package/dist/features/products/components/PrizeDrawsSection.js +2 -2
- package/dist/features/products/components/ProductDetailActions.js +3 -1
- package/dist/features/products/components/ProductGrid.js +1 -1
- package/dist/features/products/components/ProductInfo.js +1 -1
- package/dist/features/products/components/ProductsIndexListing.js +12 -2
- package/dist/features/products/hooks/useRelatedProducts.js +1 -1
- package/dist/features/products/schemas/index.d.ts +10 -10
- package/dist/features/promotions/schemas/index.d.ts +8 -8
- package/dist/features/reviews/schemas/index.d.ts +12 -12
- package/dist/features/scams/schemas/index.d.ts +6 -6
- package/dist/features/seller/components/CouponInlineSelect.js +1 -1
- package/dist/features/seller/components/SellerArtView.js +2 -2
- package/dist/features/seller/components/SellerAuctionsView.js +2 -2
- package/dist/features/seller/components/SellerBidsView.js +2 -2
- package/dist/features/seller/components/SellerBundlesView.js +1 -1
- package/dist/features/seller/components/SellerClassifiedView.js +2 -2
- package/dist/features/seller/components/SellerCouponsView.js +2 -2
- package/dist/features/seller/components/SellerDigitalCodesView.js +2 -2
- package/dist/features/seller/components/SellerGroupedListingsView.js +1 -1
- package/dist/features/seller/components/SellerLiveView.js +2 -2
- package/dist/features/seller/components/SellerOffersView.js +2 -2
- package/dist/features/seller/components/SellerOrdersView.js +2 -2
- package/dist/features/seller/components/SellerPayoutMethodsView.js +2 -2
- package/dist/features/seller/components/SellerPayoutsView.js +2 -2
- package/dist/features/seller/components/SellerPreOrdersView.js +2 -2
- package/dist/features/seller/components/SellerPrizeDrawsView.js +2 -2
- package/dist/features/seller/components/SellerProductsView.js +2 -2
- package/dist/features/seller/components/SellerShippingConfigsView.js +2 -2
- package/dist/features/seller/components/SellerStickersView.js +2 -2
- package/dist/features/seller/components/SellerStoreCategoriesView.js +1 -1
- package/dist/features/seller/components/SublistingInlineSelect.js +1 -1
- package/dist/features/seller/hooks/useSellerListingData.d.ts +1 -1
- package/dist/features/seller/schemas/index.d.ts +16 -16
- package/dist/features/server-errors/schemas/index.d.ts +4 -4
- package/dist/features/shell/StepForm.d.ts +1 -1
- package/dist/features/shipments/components/AdminShipmentsView.js +2 -2
- package/dist/features/stores/components/StoreProductsView.js +1 -1
- package/dist/features/stores/components/StoresIndexListing.js +1 -1
- package/dist/features/stores/schemas/index.d.ts +30 -30
- package/dist/features/support/schemas/index.d.ts +2 -2
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +68 -1
- package/dist/features/whatsapp-bot/helpers/payment-proof-message.d.ts +14 -0
- package/dist/features/whatsapp-bot/helpers/payment-proof-message.js +17 -0
- package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +2 -8
- package/dist/features/whatsapp-bot/helpers/whatsapp.js +4 -11
- package/dist/features/wishlist/repository/user-wishlist.repository.d.ts +11 -0
- package/dist/features/wishlist/repository/user-wishlist.repository.js +33 -0
- package/dist/index.d.ts +7 -12
- package/dist/index.js +16 -28
- package/dist/next/components/ErrorView.js +1 -1
- package/dist/next/components/NotFoundView.js +1 -1
- package/dist/next/components/UnauthorizedView.js +1 -1
- package/dist/next/routing/route-map.d.ts +4 -0
- package/dist/next/routing/route-map.js +2 -0
- package/dist/react/contexts/SessionContext.d.ts +1 -1
- package/dist/react/hooks/use-action-dispatch.d.ts +1 -1
- package/dist/react/hooks/useFormStatePreservation.d.ts +1 -1
- package/dist/schemas/registry.d.ts +236 -236
- package/dist/schemas/webhooks/razorpay.d.ts +100 -100
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/rate-limit.d.ts +10 -0
- package/dist/security/rate-limit.js +13 -1
- package/dist/seed/events-seed-data.js +52 -1
- package/dist/server.d.ts +6 -0
- package/dist/server.js +8 -0
- package/dist/styles.css +301 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/HorizontalScroller.d.ts +7 -1
- package/dist/ui/components/HorizontalScroller.js +2 -2
- package/dist/ui/components/HorizontalScroller.style.css +24 -0
- package/dist/validation/schemas.d.ts +12 -12
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { normalizeError } from "../../../../../errors/normalize";
|
|
4
4
|
import * as React from "react";
|
|
5
|
-
import { Button, Div, Heading, Input, Li, Section, Span, Table, Tbody, Td, Text, Th, Thead, Tr, Ul } from "@mohasinac/appkit";
|
|
5
|
+
import { Button, Div, Heading, Input, Li, Section, Span, Table, Tbody, Td, Text, Th, Thead, Tr, Ul } from "@mohasinac/appkit/client";
|
|
6
6
|
import { Select } from "@mohasinac/appkit/ui";
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../../../constants/api-endpoints";
|
|
8
8
|
export function AnalysisRunnerView() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import { Button, Div, Heading, Span, Table, Tbody, Td, Text, Th, Thead, Tr } from "@mohasinac/appkit";
|
|
4
|
+
import { Button, Div, Heading, Span, Table, Tbody, Td, Text, Th, Thead, Tr } from "@mohasinac/appkit/client";
|
|
5
5
|
import { ADMIN_ENDPOINTS } from "../../../../../constants/api-endpoints";
|
|
6
6
|
import { normalizeError } from "../../../../../errors/normalize";
|
|
7
7
|
const BORDER_STYLE = "1px solid var(--appkit-color-border)";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Anchor, Div, Heading, Li, Nav, Section, Span, Text, Ul } from "@mohasinac/appkit";
|
|
2
|
+
import { Anchor, Div, Heading, Li, Nav, Section, Span, Text, Ul } from "@mohasinac/appkit/client";
|
|
3
3
|
const card = {
|
|
4
4
|
padding: "1rem 1.25rem",
|
|
5
5
|
border: "1px solid var(--appkit-color-border)",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Anchor, Div, Heading, Li, Pre, Section, Text, Ul } from "@mohasinac/appkit";
|
|
2
|
+
import { Anchor, Div, Heading, Li, Pre, Section, Text, Ul } from "@mohasinac/appkit/client";
|
|
3
3
|
function fmt(t) {
|
|
4
4
|
return new Date(t).toISOString().replace("T", " ").slice(0, 19);
|
|
5
5
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import { Anchor, Div, Heading, Input, Label, Span, Table, Tbody, Td, Text, Th, Thead, Tr } from "@mohasinac/appkit";
|
|
4
|
+
import { Anchor, Div, Heading, Input, Label, Span, Table, Tbody, Td, Text, Th, Thead, Tr } from "@mohasinac/appkit/client";
|
|
5
5
|
const BORDER_STYLE = "1px solid var(--appkit-color-border)";
|
|
6
6
|
const COLUMNS = [
|
|
7
7
|
{ key: "occurredAtFmt", label: "When", width: "180px" },
|
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core: weighted random selection from an event's `spinPrizes` config using
|
|
3
|
-
* `crypto.randomInt`. Enforces
|
|
3
|
+
* `crypto.randomInt`. Enforces `spinMaxPerUser` (per identity — user or
|
|
4
|
+
* guest) and the optional `spinWindowStart`/`spinWindowEnd` window.
|
|
5
|
+
*
|
|
6
|
+
* Find-or-create is intentional: the spin UI never calls `enterEvent()`
|
|
7
|
+
* first (unlike poll/survey/raffle), so this function owns creating the
|
|
8
|
+
* backing `eventEntries` doc the first time an identity spins. The whole
|
|
9
|
+
* find/create/assign/mark-used sequence runs inside a single Firestore
|
|
10
|
+
* transaction so two rapid spins from the same identity can't both win a
|
|
11
|
+
* prize (the old read-then-`ref.update()` version had this race).
|
|
4
12
|
*/
|
|
5
13
|
import type { JobContext } from "../runtime/types";
|
|
6
14
|
export interface AssignSpinPrizeInput {
|
|
7
15
|
eventId: string;
|
|
8
|
-
userId
|
|
16
|
+
/** Logged-in identity. Exactly one of userId/guestIpHash must be set. */
|
|
17
|
+
userId?: string;
|
|
18
|
+
/** Hashed guest identity (see `hashGuestIdentity` in security/rate-limit.ts) — never a raw IP. */
|
|
19
|
+
guestIpHash?: string;
|
|
9
20
|
}
|
|
10
21
|
export interface AssignSpinPrizeResult {
|
|
11
22
|
eventId: string;
|
|
12
|
-
userId
|
|
23
|
+
userId?: string;
|
|
13
24
|
spinPrizeId?: string;
|
|
14
25
|
spinPrizeTitle?: string;
|
|
15
26
|
spinPrizeCouponCode?: string;
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core: weighted random selection from an event's `spinPrizes` config using
|
|
3
|
-
* `crypto.randomInt`. Enforces
|
|
3
|
+
* `crypto.randomInt`. Enforces `spinMaxPerUser` (per identity — user or
|
|
4
|
+
* guest) and the optional `spinWindowStart`/`spinWindowEnd` window.
|
|
5
|
+
*
|
|
6
|
+
* Find-or-create is intentional: the spin UI never calls `enterEvent()`
|
|
7
|
+
* first (unlike poll/survey/raffle), so this function owns creating the
|
|
8
|
+
* backing `eventEntries` doc the first time an identity spins. The whole
|
|
9
|
+
* find/create/assign/mark-used sequence runs inside a single Firestore
|
|
10
|
+
* transaction so two rapid spins from the same identity can't both win a
|
|
11
|
+
* prize (the old read-then-`ref.update()` version had this race).
|
|
4
12
|
*/
|
|
5
13
|
import crypto from "node:crypto";
|
|
6
14
|
import { EVENT_ENTRY_FIELDS, COMMON_FIELDS } from "../../../../constants/field-names";
|
|
15
|
+
import { resolveDate } from "../../../../utils";
|
|
7
16
|
const EVENTS_COLLECTION = "events";
|
|
8
17
|
const EVENT_ENTRIES_COLLECTION = "eventEntries";
|
|
9
18
|
const COUPONS_COLLECTION = "coupons";
|
|
@@ -12,75 +21,105 @@ export async function runAssignSpinPrize(input, ctx) {
|
|
|
12
21
|
ctx.logger.info("FEATURE_PRIZE_DRAWS disabled — skipping spin prize assignment");
|
|
13
22
|
return { eventId: input.eventId, userId: input.userId, reason: "feature_disabled" };
|
|
14
23
|
}
|
|
15
|
-
const { eventId, userId } = input;
|
|
24
|
+
const { eventId, userId, guestIpHash } = input;
|
|
25
|
+
if (!userId && !guestIpHash) {
|
|
26
|
+
return { eventId, userId, reason: "identity_required" };
|
|
27
|
+
}
|
|
16
28
|
const eventSnap = await ctx.db.collection(EVENTS_COLLECTION).doc(eventId).get();
|
|
17
29
|
if (!eventSnap.exists) {
|
|
18
30
|
return { eventId, userId, reason: "event_not_found" };
|
|
19
31
|
}
|
|
20
32
|
const event = eventSnap.data();
|
|
33
|
+
if (!userId && !event.allowGuestParticipation) {
|
|
34
|
+
return { eventId, userId, reason: "login_required" };
|
|
35
|
+
}
|
|
21
36
|
const prizes = Array.isArray(event.spinPrizes) ? event.spinPrizes : [];
|
|
22
37
|
const totalWeight = prizes.reduce((s, p) => s + (p.weight ?? 0), 0);
|
|
23
38
|
if (totalWeight <= 0) {
|
|
24
39
|
return { eventId, userId, reason: "no_prizes_configured" };
|
|
25
40
|
}
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
.limit(1)
|
|
31
|
-
.get();
|
|
32
|
-
if (entriesSnap.empty) {
|
|
33
|
-
return { eventId, userId, reason: "entry_not_found" };
|
|
41
|
+
const windowStart = resolveDate(event.spinWindowStart);
|
|
42
|
+
const windowEnd = resolveDate(event.spinWindowEnd);
|
|
43
|
+
if ((windowStart && ctx.now < windowStart) || (windowEnd && ctx.now > windowEnd)) {
|
|
44
|
+
return { eventId, userId, reason: "outside_spin_window" };
|
|
34
45
|
}
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
const maxPerUser = typeof event.spinMaxPerUser === "number" && event.spinMaxPerUser > 0
|
|
47
|
+
? event.spinMaxPerUser
|
|
48
|
+
: 1;
|
|
49
|
+
const identityField = userId ? EVENT_ENTRY_FIELDS.USER_ID : EVENT_ENTRY_FIELDS.GUEST_IP_HASH;
|
|
50
|
+
const identityValue = (userId ?? guestIpHash);
|
|
51
|
+
return ctx.db.runTransaction(async (tx) => {
|
|
52
|
+
const entriesQuery = ctx.db
|
|
53
|
+
.collection(EVENT_ENTRIES_COLLECTION)
|
|
54
|
+
.where(EVENT_ENTRY_FIELDS.EVENT_ID, "==", eventId)
|
|
55
|
+
.where(identityField, "==", identityValue)
|
|
56
|
+
.limit(1);
|
|
57
|
+
const entriesSnap = await tx.get(entriesQuery);
|
|
58
|
+
const existingDoc = entriesSnap.empty ? null : entriesSnap.docs[0];
|
|
59
|
+
const existingData = existingDoc?.data();
|
|
60
|
+
const priorSpinCount = existingData?.spinCount ?? (existingData?.spinUsed ? 1 : 0);
|
|
61
|
+
if (priorSpinCount >= maxPerUser) {
|
|
62
|
+
return {
|
|
63
|
+
eventId,
|
|
64
|
+
userId,
|
|
65
|
+
spinPrizeId: existingData?.spinPrizeId,
|
|
66
|
+
alreadyUsed: true,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const roll = crypto.randomInt(0, totalWeight);
|
|
70
|
+
let cumulative = 0;
|
|
71
|
+
let pick;
|
|
72
|
+
for (const p of prizes) {
|
|
73
|
+
cumulative += p.weight ?? 0;
|
|
74
|
+
if (roll < cumulative) {
|
|
75
|
+
pick = p;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (!pick)
|
|
80
|
+
pick = prizes[prizes.length - 1];
|
|
81
|
+
let spinPrizeCouponCode;
|
|
82
|
+
if (pick.couponId) {
|
|
83
|
+
const coupSnap = await tx.get(ctx.db.collection(COUPONS_COLLECTION).doc(pick.couponId));
|
|
84
|
+
if (coupSnap.exists) {
|
|
85
|
+
spinPrizeCouponCode = coupSnap.data().code;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const nextSpinCount = priorSpinCount + 1;
|
|
89
|
+
const spinFields = {
|
|
90
|
+
[EVENT_ENTRY_FIELDS.SPIN_USED]: true,
|
|
91
|
+
[EVENT_ENTRY_FIELDS.SPIN_COUNT]: nextSpinCount,
|
|
92
|
+
[EVENT_ENTRY_FIELDS.SPIN_PRIZE_ID]: pick.id,
|
|
93
|
+
[EVENT_ENTRY_FIELDS.SPIN_WON_AT]: ctx.now,
|
|
94
|
+
[EVENT_ENTRY_FIELDS.SPIN_PRIZE_COUPON_CODE]: spinPrizeCouponCode ?? null,
|
|
95
|
+
[COMMON_FIELDS.UPDATED_AT]: ctx.now,
|
|
96
|
+
};
|
|
97
|
+
if (existingDoc) {
|
|
98
|
+
tx.update(existingDoc.ref, spinFields);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
const newRef = ctx.db.collection(EVENT_ENTRIES_COLLECTION).doc();
|
|
102
|
+
tx.set(newRef, {
|
|
103
|
+
[EVENT_ENTRY_FIELDS.EVENT_ID]: eventId,
|
|
104
|
+
...(userId
|
|
105
|
+
? { [EVENT_ENTRY_FIELDS.USER_ID]: userId }
|
|
106
|
+
: { [EVENT_ENTRY_FIELDS.GUEST_IP_HASH]: guestIpHash }),
|
|
107
|
+
reviewStatus: "approved",
|
|
108
|
+
submittedAt: ctx.now,
|
|
109
|
+
...spinFields,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
ctx.logger.info("Spin prize assigned", {
|
|
113
|
+
eventId,
|
|
114
|
+
userId: userId ?? "guest",
|
|
115
|
+
spinPrizeId: pick.id,
|
|
116
|
+
});
|
|
38
117
|
return {
|
|
39
118
|
eventId,
|
|
40
119
|
userId,
|
|
41
|
-
spinPrizeId:
|
|
42
|
-
|
|
120
|
+
spinPrizeId: pick.id,
|
|
121
|
+
spinPrizeTitle: pick.label,
|
|
122
|
+
spinPrizeCouponCode,
|
|
43
123
|
};
|
|
44
|
-
}
|
|
45
|
-
const roll = crypto.randomInt(0, totalWeight);
|
|
46
|
-
let cumulative = 0;
|
|
47
|
-
let pick;
|
|
48
|
-
for (const p of prizes) {
|
|
49
|
-
cumulative += p.weight ?? 0;
|
|
50
|
-
if (roll < cumulative) {
|
|
51
|
-
pick = p;
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (!pick)
|
|
56
|
-
pick = prizes[prizes.length - 1];
|
|
57
|
-
let spinPrizeCouponCode;
|
|
58
|
-
if (pick.couponId) {
|
|
59
|
-
const coupSnap = await ctx.db
|
|
60
|
-
.collection(COUPONS_COLLECTION)
|
|
61
|
-
.doc(pick.couponId)
|
|
62
|
-
.get();
|
|
63
|
-
if (coupSnap.exists) {
|
|
64
|
-
spinPrizeCouponCode = coupSnap.data().code;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
await entryDoc.ref.update({
|
|
68
|
-
[EVENT_ENTRY_FIELDS.SPIN_USED]: true,
|
|
69
|
-
[EVENT_ENTRY_FIELDS.SPIN_PRIZE_ID]: pick.id,
|
|
70
|
-
[EVENT_ENTRY_FIELDS.SPIN_WON_AT]: ctx.now,
|
|
71
|
-
[EVENT_ENTRY_FIELDS.SPIN_PRIZE_COUPON_CODE]: spinPrizeCouponCode ?? null,
|
|
72
|
-
[COMMON_FIELDS.UPDATED_AT]: ctx.now,
|
|
73
|
-
});
|
|
74
|
-
ctx.logger.info("Spin prize assigned", {
|
|
75
|
-
eventId,
|
|
76
|
-
userId,
|
|
77
|
-
spinPrizeId: pick.id,
|
|
78
124
|
});
|
|
79
|
-
return {
|
|
80
|
-
eventId,
|
|
81
|
-
userId,
|
|
82
|
-
spinPrizeId: pick.id,
|
|
83
|
-
spinPrizeTitle: pick.title,
|
|
84
|
-
spinPrizeCouponCode,
|
|
85
|
-
};
|
|
86
125
|
}
|
|
@@ -9,8 +9,14 @@ export const assignSpinPrizeHandler = async (input, ctx) => {
|
|
|
9
9
|
if (result.reason === "event_not_found") {
|
|
10
10
|
throw httpError("Event not found", 404);
|
|
11
11
|
}
|
|
12
|
-
if (result.reason === "
|
|
13
|
-
throw httpError("No
|
|
12
|
+
if (result.reason === "identity_required") {
|
|
13
|
+
throw httpError("No user or guest identity provided", 400);
|
|
14
|
+
}
|
|
15
|
+
if (result.reason === "login_required") {
|
|
16
|
+
throw httpError("You must be logged in to spin this wheel", 401);
|
|
17
|
+
}
|
|
18
|
+
if (result.reason === "outside_spin_window") {
|
|
19
|
+
throw httpError("This spin wheel is not open right now", 403);
|
|
14
20
|
}
|
|
15
21
|
if (result.reason === "no_prizes_configured") {
|
|
16
22
|
throw httpError("No spin prizes configured for this event", 422);
|
|
@@ -94,6 +94,13 @@ export const ACTIONS = {
|
|
|
94
94
|
description: "Remove this listing from the buyer's wishlist.",
|
|
95
95
|
kind: "ghost",
|
|
96
96
|
},
|
|
97
|
+
"sync-wishlist-item": {
|
|
98
|
+
id: "product.sync-wishlist-item",
|
|
99
|
+
label: "Sync",
|
|
100
|
+
ariaLabel: "Sync this wishlist item with the latest product data",
|
|
101
|
+
description: "Refreshes the wishlist entry's stored price/title/image against the live listing, removing it if the listing is no longer available.",
|
|
102
|
+
kind: "ghost",
|
|
103
|
+
},
|
|
97
104
|
"share": {
|
|
98
105
|
id: "product.share",
|
|
99
106
|
label: "Share",
|
|
@@ -1324,6 +1331,14 @@ export const ACTIONS = {
|
|
|
1324
1331
|
kind: "ghost",
|
|
1325
1332
|
permissions: ["admin"],
|
|
1326
1333
|
},
|
|
1334
|
+
"export-event-entries": {
|
|
1335
|
+
id: "admin.export-event-entries",
|
|
1336
|
+
label: "Download Report",
|
|
1337
|
+
ariaLabel: "Download this event's entries as a Markdown report",
|
|
1338
|
+
description: "Download an event's entries as a Markdown file — a per-option vote tally for polls, or individual entries (submitter, status, points, responses) for every other event type.",
|
|
1339
|
+
kind: "ghost",
|
|
1340
|
+
permissions: ["admin"],
|
|
1341
|
+
},
|
|
1327
1342
|
"create-checklist-item": {
|
|
1328
1343
|
id: "admin.create-checklist-item",
|
|
1329
1344
|
label: "Add Test Case",
|
|
@@ -17,9 +17,9 @@ export declare const brandInputSchema: z.ZodObject<{
|
|
|
17
17
|
displayOrder: number;
|
|
18
18
|
country?: string | undefined;
|
|
19
19
|
description?: string | undefined;
|
|
20
|
-
website?: string | undefined;
|
|
21
20
|
logoURL?: string | undefined;
|
|
22
21
|
bannerURL?: string | undefined;
|
|
22
|
+
website?: string | undefined;
|
|
23
23
|
founded?: number | undefined;
|
|
24
24
|
}, {
|
|
25
25
|
name: string;
|
|
@@ -27,10 +27,10 @@ export declare const brandInputSchema: z.ZodObject<{
|
|
|
27
27
|
country?: string | undefined;
|
|
28
28
|
description?: string | undefined;
|
|
29
29
|
isActive?: boolean | undefined;
|
|
30
|
-
website?: string | undefined;
|
|
31
30
|
displayOrder?: number | undefined;
|
|
32
31
|
logoURL?: string | undefined;
|
|
33
32
|
bannerURL?: string | undefined;
|
|
33
|
+
website?: string | undefined;
|
|
34
34
|
founded?: number | undefined;
|
|
35
35
|
}>;
|
|
36
36
|
export declare const brandUpdateSchema: z.ZodObject<Omit<{
|
|
@@ -49,20 +49,20 @@ export declare const brandUpdateSchema: z.ZodObject<Omit<{
|
|
|
49
49
|
name?: string | undefined;
|
|
50
50
|
description?: string | undefined;
|
|
51
51
|
isActive?: boolean | undefined;
|
|
52
|
-
website?: string | undefined;
|
|
53
52
|
displayOrder?: number | undefined;
|
|
54
53
|
logoURL?: string | undefined;
|
|
55
54
|
bannerURL?: string | undefined;
|
|
55
|
+
website?: string | undefined;
|
|
56
56
|
founded?: number | undefined;
|
|
57
57
|
}, {
|
|
58
58
|
country?: string | undefined;
|
|
59
59
|
name?: string | undefined;
|
|
60
60
|
description?: string | undefined;
|
|
61
61
|
isActive?: boolean | undefined;
|
|
62
|
-
website?: string | undefined;
|
|
63
62
|
displayOrder?: number | undefined;
|
|
64
63
|
logoURL?: string | undefined;
|
|
65
64
|
bannerURL?: string | undefined;
|
|
65
|
+
website?: string | undefined;
|
|
66
66
|
founded?: number | undefined;
|
|
67
67
|
}>;
|
|
68
68
|
export type BrandInput = z.infer<typeof brandInputSchema>;
|
|
@@ -161,8 +161,8 @@ export declare const bundleCreateSchema: z.ZodObject<{
|
|
|
161
161
|
isActive: z.ZodOptional<z.ZodBoolean>;
|
|
162
162
|
}, "strip", z.ZodTypeAny, {
|
|
163
163
|
name: string;
|
|
164
|
-
bundleProductIds: string[];
|
|
165
164
|
bundleKind: "brand" | "special";
|
|
165
|
+
bundleProductIds: string[];
|
|
166
166
|
bundlePrice: number;
|
|
167
167
|
bundleQueryRule: {
|
|
168
168
|
type: "static";
|
|
@@ -192,8 +192,8 @@ export declare const bundleCreateSchema: z.ZodObject<{
|
|
|
192
192
|
}[] | undefined;
|
|
193
193
|
}, {
|
|
194
194
|
name: string;
|
|
195
|
-
bundleProductIds: string[];
|
|
196
195
|
bundleKind: "brand" | "special";
|
|
196
|
+
bundleProductIds: string[];
|
|
197
197
|
bundlePrice: number;
|
|
198
198
|
bundleQueryRule: {
|
|
199
199
|
type: "static";
|
|
@@ -312,8 +312,8 @@ export declare const bundleUpdateSchema: z.ZodObject<{
|
|
|
312
312
|
name?: string | undefined;
|
|
313
313
|
description?: string | undefined;
|
|
314
314
|
isActive?: boolean | undefined;
|
|
315
|
-
bundleProductIds?: string[] | undefined;
|
|
316
315
|
bundleKind?: "brand" | "special" | undefined;
|
|
316
|
+
bundleProductIds?: string[] | undefined;
|
|
317
317
|
bundleItemDetails?: {
|
|
318
318
|
productId: string;
|
|
319
319
|
drawCount?: number | undefined;
|
|
@@ -342,8 +342,8 @@ export declare const bundleUpdateSchema: z.ZodObject<{
|
|
|
342
342
|
name?: string | undefined;
|
|
343
343
|
description?: string | undefined;
|
|
344
344
|
isActive?: boolean | undefined;
|
|
345
|
-
bundleProductIds?: string[] | undefined;
|
|
346
345
|
bundleKind?: "brand" | "special" | undefined;
|
|
346
|
+
bundleProductIds?: string[] | undefined;
|
|
347
347
|
bundleItemDetails?: {
|
|
348
348
|
productId: string;
|
|
349
349
|
drawCount?: number | undefined;
|
|
@@ -25,18 +25,18 @@ export declare const createOrderSchema: z.ZodObject<{
|
|
|
25
25
|
}, "strip", z.ZodTypeAny, {
|
|
26
26
|
country: string;
|
|
27
27
|
phone: string;
|
|
28
|
-
state: string;
|
|
29
28
|
city: string;
|
|
30
|
-
|
|
29
|
+
state: string;
|
|
31
30
|
fullName: string;
|
|
31
|
+
addressLine1: string;
|
|
32
32
|
pincode: string;
|
|
33
33
|
addressLine2?: string | undefined;
|
|
34
34
|
}, {
|
|
35
35
|
phone: string;
|
|
36
|
-
state: string;
|
|
37
36
|
city: string;
|
|
38
|
-
|
|
37
|
+
state: string;
|
|
39
38
|
fullName: string;
|
|
39
|
+
addressLine1: string;
|
|
40
40
|
pincode: string;
|
|
41
41
|
country?: string | undefined;
|
|
42
42
|
addressLine2?: string | undefined;
|
|
@@ -53,10 +53,10 @@ export declare const createOrderSchema: z.ZodObject<{
|
|
|
53
53
|
shippingAddress: {
|
|
54
54
|
country: string;
|
|
55
55
|
phone: string;
|
|
56
|
-
state: string;
|
|
57
56
|
city: string;
|
|
58
|
-
|
|
57
|
+
state: string;
|
|
59
58
|
fullName: string;
|
|
59
|
+
addressLine1: string;
|
|
60
60
|
pincode: string;
|
|
61
61
|
addressLine2?: string | undefined;
|
|
62
62
|
};
|
|
@@ -70,10 +70,10 @@ export declare const createOrderSchema: z.ZodObject<{
|
|
|
70
70
|
}[];
|
|
71
71
|
shippingAddress: {
|
|
72
72
|
phone: string;
|
|
73
|
-
state: string;
|
|
74
73
|
city: string;
|
|
75
|
-
|
|
74
|
+
state: string;
|
|
76
75
|
fullName: string;
|
|
76
|
+
addressLine1: string;
|
|
77
77
|
pincode: string;
|
|
78
78
|
country?: string | undefined;
|
|
79
79
|
addressLine2?: string | undefined;
|
|
@@ -12,15 +12,15 @@ export declare const createReviewSchema: z.ZodObject<{
|
|
|
12
12
|
body: string;
|
|
13
13
|
storeId: string;
|
|
14
14
|
images: string[];
|
|
15
|
-
productId: string;
|
|
16
15
|
rating: number;
|
|
16
|
+
productId: string;
|
|
17
17
|
orderId?: string | undefined;
|
|
18
18
|
}, {
|
|
19
19
|
title: string;
|
|
20
20
|
body: string;
|
|
21
21
|
storeId: string;
|
|
22
|
-
productId: string;
|
|
23
22
|
rating: number;
|
|
23
|
+
productId: string;
|
|
24
24
|
orderId?: string | undefined;
|
|
25
25
|
images?: string[] | undefined;
|
|
26
26
|
}>;
|
package/dist/client.d.ts
CHANGED
|
@@ -147,6 +147,8 @@ export { Heading } from "./ui/components/Typography";
|
|
|
147
147
|
export { Label, Text, Span, Caption } from "./ui/components/Typography";
|
|
148
148
|
export { TextLink } from "./ui/components/TextLink";
|
|
149
149
|
export type { TextLinkProps } from "./ui/components/TextLink";
|
|
150
|
+
export { Anchor } from "./ui/components/Anchor";
|
|
151
|
+
export { IconButton } from "./ui/index";
|
|
150
152
|
export { Textarea } from "./ui/components/Textarea";
|
|
151
153
|
export { GlobalError } from "./next/components/GlobalError";
|
|
152
154
|
export { AppLayoutShell, LocaleSwitcher, useDashboardNav, BottomActionsProvider, useBottomActions, DashboardNavProvider, LayoutClient } from "./features/layout/index";
|
|
@@ -358,3 +360,37 @@ export { SCHEMAS, lookupApiSchema, lookupFirestoreSchema, } from "./schemas/inde
|
|
|
358
360
|
export type { ApiRouteKey, ApiRouteSchema, FirestoreDocument, FirestoreValue, FormFieldValue, FormValues, HttpVerb, JsonArray, JsonObject, JsonObjectWithUndefined, JsonPrimitive, JsonValue, JsonValueWithUndefined, RegisteredApiRouteKey, RegisteredFirestoreCollection, RegisteredFormId, RegisteredRtdbChannel, RegisteredSieveCollection, RegisteredStorageOp, RegisteredWebhookProvider, RegistryEntry, SchemaRegistry, SchemasShape, WebhookSchemaBucket, } from "./schemas/index";
|
|
359
361
|
export { normalizeError, getErrorMessage, isApiNormalized, isAppNormalized, isFirebaseAuthNormalized, isFirebaseFirestoreNormalized, isFirebaseStorageNormalized, isNativeNormalized, isNetworkNormalized, isUnknownNormalized, isZodNormalized, } from "./errors/normalize";
|
|
360
362
|
export type { NormalizedError, NormalizedApiError, NormalizedAppError, NormalizedFirebaseAuthError, NormalizedFirebaseFirestoreError, NormalizedFirebaseStorageError, NormalizedNativeError, NormalizedNetworkError, NormalizedUnknownThrownValue, NormalizedZodError, } from "./errors/normalize";
|
|
363
|
+
export { buildPaymentProofReviewMessage } from "./features/whatsapp-bot/helpers/payment-proof-message";
|
|
364
|
+
export type { PaymentProofReviewMessageInput } from "./features/whatsapp-bot/types";
|
|
365
|
+
export type { AdminNotificationDocument, ItemRequestDocument, ModerationQueueDocument, ReportDocument, CustomRoleDocument, AnalyticsCardDocument, ListingTemplateDocument, } from "./features/store-extensions/index";
|
|
366
|
+
export { CommandPalette, useCommandPaletteHotkey } from "./features/shell/index";
|
|
367
|
+
export type { CommandPaletteGroup } from "./features/shell/index";
|
|
368
|
+
export { AdminBlogEditorView, AdminBundleEditorView, AdminCarouselEditorView, AdminCategoryEditorView, AdminCouponEditorView, AdminFaqEditorView, AdminOrderEditorView, AdminProductEditorView, AdminScammerEditorView, AdminSublistingCategoryEditorView, AdminSupportTicketDetailView, } from "./features/admin/index";
|
|
369
|
+
export { ADMIN_CHECKOUT_BYPASS_FLAG_KEY } from "./features/admin/schemas/firestore";
|
|
370
|
+
export { SpinWheelView, EventRaffleEntryForm } from "./features/events/index";
|
|
371
|
+
export { Card, CardBody } from "./ui/index";
|
|
372
|
+
export { SellerCouponsView, SellerCreateProductView, SellerEditProductView, useBecomeSeller, } from "./features/seller/index";
|
|
373
|
+
export type { BecomeSellerResult, SellerCreateProductViewProps, SellerEditProductViewProps, } from "./features/seller/index";
|
|
374
|
+
export { BecomeSellerView } from "./features/account/index";
|
|
375
|
+
export type { BidDocument } from "./features/auctions/index";
|
|
376
|
+
export type { ClaimedCouponDocument } from "./features/promotions/schemas";
|
|
377
|
+
export { groupOrderItemsByBundle } from "./features/orders/index";
|
|
378
|
+
export type { BundleOrderGroup, OutOfStockPolicy } from "./features/orders/index";
|
|
379
|
+
export { MediaUploadField } from "./features/media/index";
|
|
380
|
+
export { PrizeRevealModal } from "./features/products/components/PrizeRevealModal";
|
|
381
|
+
export { useProduct } from "./features/products/index";
|
|
382
|
+
export type { ProductDocument } from "./features/products/index";
|
|
383
|
+
export { BUNDLE_COPY } from "./_internal/shared/features/categories/bundle-copy";
|
|
384
|
+
export { useSiteSettings } from "./core/index";
|
|
385
|
+
export { checkEmiEligibility, computeEmiSchedule, } from "./_internal/shared/features/emi/schedule";
|
|
386
|
+
export type { EmiSettings } from "./_internal/shared/features/emi/schedule";
|
|
387
|
+
export { computeCodHandlingFee } from "./_internal/shared/fees/calculator";
|
|
388
|
+
export type { CodHandlingFeeRates, WhatsAppNotifyFeeRates, GiftWrapFeeRates, ShipmentProtectionFeeRates, } from "./_internal/shared/fees/calculator";
|
|
389
|
+
export { FAQPageContent } from "./features/faq/index";
|
|
390
|
+
export type { FAQCategory, FAQCategoryItem, FAQSortOption } from "./features/faq/index";
|
|
391
|
+
export { CategoryInlineSelect } from "./features/seller/components/CategoryInlineSelect";
|
|
392
|
+
export { BrandInlineSelect } from "./features/seller/components/BrandInlineSelect";
|
|
393
|
+
export { API_ENDPOINTS } from "./constants/index";
|
|
394
|
+
export { SELLER_LISTING_TABS, type SellerListingTabId, } from "./features/products/constants/listing-tabs";
|
|
395
|
+
export { ALL_TAB, EMPTY_TAB, ADMIN_PRODUCT_STATUS_TABS, ADMIN_PRODUCT_LISTING_TYPE_TABS, ADMIN_BLOG_STATUS_TABS, ADMIN_USER_STATUS_TABS, ADMIN_USER_ROLE_TABS, ADMIN_STORE_STATUS_TABS, ADMIN_PAYOUT_STATUS_TABS, ADMIN_ORDER_STATUS_TABS, ADMIN_REVIEW_STATUS_TABS, ADMIN_REVIEW_RATING_TABS, ADMIN_BID_STATUS_TABS, ADMIN_CONTACT_STATUS_TABS, ADMIN_NEWSLETTER_STATUS_TABS, ADMIN_EVENT_ENTRY_STATUS_TABS, ADMIN_EVENT_STATUS_TABS, ADMIN_CART_OWNERSHIP_TABS, ADMIN_COUPON_TYPE_TABS, SELLER_PRODUCT_STATUS_TABS, SELLER_AUCTION_STATUS_TABS, SELLER_ORDER_STATUS_TABS, SELLER_OFFER_STATUS_TABS, SELLER_BID_STATUS_TABS, } from "./features/admin/constants/filter-tabs";
|
|
396
|
+
export { PRODUCT_FIELDS, PRODUCT_STATUS_TRANSITIONS, ORDER_FIELDS, REVIEW_FIELDS, BID_FIELDS, AD_FIELDS, EVENT_FIELDS, EVENT_ENTRY_FIELDS, PAYOUT_FIELDS, STORE_FIELDS, CATEGORY_FIELDS, BLOG_FIELDS, USER_FIELDS, ADDRESS_FIELDS, BRAND_FIELDS, CART_FIELDS, WISHLIST_FIELDS, HISTORY_FIELDS, NOTIFICATION_FIELDS, SESSION_FIELDS, COUPON_USAGE_FIELDS, CONVERSATION_FIELDS, SCAMMER_FIELDS, SUPPORT_TICKET_FIELDS, CAROUSEL_FIELDS, COUPON_FIELDS, FAQ_FIELDS, HOMEPAGE_SECTION_FIELDS, SITE_SETTINGS_FIELDS, COMMON_FIELDS, OAUTH_STATE_VALUES, SCHEMA_DEFAULTS, } from "./constants/field-names";
|
package/dist/client.js
CHANGED
|
@@ -194,6 +194,8 @@ export { Select } from "./ui/components/Select";
|
|
|
194
194
|
export { Heading } from "./ui/components/Typography";
|
|
195
195
|
export { Label, Text, Span, Caption } from "./ui/components/Typography";
|
|
196
196
|
export { TextLink } from "./ui/components/TextLink";
|
|
197
|
+
export { Anchor } from "./ui/components/Anchor";
|
|
198
|
+
export { IconButton } from "./ui/index";
|
|
197
199
|
export { Textarea } from "./ui/components/Textarea";
|
|
198
200
|
export { GlobalError } from "./next/components/GlobalError";
|
|
199
201
|
export { AppLayoutShell, LocaleSwitcher, useDashboardNav, BottomActionsProvider, useBottomActions, DashboardNavProvider, LayoutClient } from "./features/layout/index";
|
|
@@ -345,3 +347,31 @@ export { SellerLiveView } from "./features/seller/components/SellerLiveView";
|
|
|
345
347
|
export { SCHEMAS, lookupApiSchema, lookupFirestoreSchema, } from "./schemas/index";
|
|
346
348
|
// ── W3 catch-clause normalizer ──────────────────────────────────────────────
|
|
347
349
|
export { normalizeError, getErrorMessage, isApiNormalized, isAppNormalized, isFirebaseAuthNormalized, isFirebaseFirestoreNormalized, isFirebaseStorageNormalized, isNativeNormalized, isNetworkNormalized, isUnknownNormalized, isZodNormalized, } from "./errors/normalize";
|
|
350
|
+
// [CLIENT-SAFE] Pure wa.me share-link message builder — imported directly
|
|
351
|
+
// from its isolated file (not ./whatsapp-bot/server) so this barrel's graph
|
|
352
|
+
// never touches the sibling crypto-importing helpers.
|
|
353
|
+
export { buildPaymentProofReviewMessage } from "./features/whatsapp-bot/helpers/payment-proof-message";
|
|
354
|
+
export { CommandPalette, useCommandPaletteHotkey } from "./features/shell/index";
|
|
355
|
+
export { AdminBlogEditorView, AdminBundleEditorView, AdminCarouselEditorView, AdminCategoryEditorView, AdminCouponEditorView, AdminFaqEditorView, AdminOrderEditorView, AdminProductEditorView, AdminScammerEditorView, AdminSublistingCategoryEditorView, AdminSupportTicketDetailView, } from "./features/admin/index";
|
|
356
|
+
export { ADMIN_CHECKOUT_BYPASS_FLAG_KEY } from "./features/admin/schemas/firestore";
|
|
357
|
+
export { SpinWheelView, EventRaffleEntryForm } from "./features/events/index";
|
|
358
|
+
export { Card, CardBody } from "./ui/index";
|
|
359
|
+
export { SellerCouponsView, SellerCreateProductView, SellerEditProductView, useBecomeSeller, } from "./features/seller/index";
|
|
360
|
+
export { BecomeSellerView } from "./features/account/index";
|
|
361
|
+
export { groupOrderItemsByBundle } from "./features/orders/index";
|
|
362
|
+
export { MediaUploadField } from "./features/media/index";
|
|
363
|
+
export { PrizeRevealModal } from "./features/products/components/PrizeRevealModal";
|
|
364
|
+
export { useProduct } from "./features/products/index";
|
|
365
|
+
export { BUNDLE_COPY } from "./_internal/shared/features/categories/bundle-copy";
|
|
366
|
+
export { useSiteSettings } from "./core/index";
|
|
367
|
+
export { checkEmiEligibility, computeEmiSchedule, } from "./_internal/shared/features/emi/schedule";
|
|
368
|
+
export { computeCodHandlingFee } from "./_internal/shared/fees/calculator"; // reexport-from-internal-ok: pure fee-calc utility consumed directly by public checkout UI (CheckoutRouteClient.tsx), same category as the sibling computeEmiSchedule/checkEmiEligibility re-export two lines above
|
|
369
|
+
export { FAQPageContent } from "./features/faq/index";
|
|
370
|
+
export { CategoryInlineSelect } from "./features/seller/components/CategoryInlineSelect";
|
|
371
|
+
export { BrandInlineSelect } from "./features/seller/components/BrandInlineSelect";
|
|
372
|
+
export { API_ENDPOINTS } from "./constants/index";
|
|
373
|
+
// [CLIENT-SAFE] Pure, zero-import constant files — dashboard filter-tab
|
|
374
|
+
// sets and Firestore field-name maps. No server dependency of any kind.
|
|
375
|
+
export { SELLER_LISTING_TABS, } from "./features/products/constants/listing-tabs";
|
|
376
|
+
export { ALL_TAB, EMPTY_TAB, ADMIN_PRODUCT_STATUS_TABS, ADMIN_PRODUCT_LISTING_TYPE_TABS, ADMIN_BLOG_STATUS_TABS, ADMIN_USER_STATUS_TABS, ADMIN_USER_ROLE_TABS, ADMIN_STORE_STATUS_TABS, ADMIN_PAYOUT_STATUS_TABS, ADMIN_ORDER_STATUS_TABS, ADMIN_REVIEW_STATUS_TABS, ADMIN_REVIEW_RATING_TABS, ADMIN_BID_STATUS_TABS, ADMIN_CONTACT_STATUS_TABS, ADMIN_NEWSLETTER_STATUS_TABS, ADMIN_EVENT_ENTRY_STATUS_TABS, ADMIN_EVENT_STATUS_TABS, ADMIN_CART_OWNERSHIP_TABS, ADMIN_COUPON_TYPE_TABS, SELLER_PRODUCT_STATUS_TABS, SELLER_AUCTION_STATUS_TABS, SELLER_ORDER_STATUS_TABS, SELLER_OFFER_STATUS_TABS, SELLER_BID_STATUS_TABS, } from "./features/admin/constants/filter-tabs";
|
|
377
|
+
export { PRODUCT_FIELDS, PRODUCT_STATUS_TRANSITIONS, ORDER_FIELDS, REVIEW_FIELDS, BID_FIELDS, AD_FIELDS, EVENT_FIELDS, EVENT_ENTRY_FIELDS, PAYOUT_FIELDS, STORE_FIELDS, CATEGORY_FIELDS, BLOG_FIELDS, USER_FIELDS, ADDRESS_FIELDS, BRAND_FIELDS, CART_FIELDS, WISHLIST_FIELDS, HISTORY_FIELDS, NOTIFICATION_FIELDS, SESSION_FIELDS, COUPON_USAGE_FIELDS, CONVERSATION_FIELDS, SCAMMER_FIELDS, SUPPORT_TICKET_FIELDS, CAROUSEL_FIELDS, COUPON_FIELDS, FAQ_FIELDS, HOMEPAGE_SECTION_FIELDS, SITE_SETTINGS_FIELDS, COMMON_FIELDS, OAUTH_STATE_VALUES, SCHEMA_DEFAULTS, } from "./constants/field-names";
|
|
@@ -45,6 +45,7 @@ export declare const ACCOUNT_ENDPOINTS: {
|
|
|
45
45
|
readonly ORDER_BY_ID: (orderId: string) => string;
|
|
46
46
|
readonly WISHLIST: "/api/user/wishlist";
|
|
47
47
|
readonly WISHLIST_ITEM_BY_ID: (itemId: string) => string;
|
|
48
|
+
readonly WISHLIST_ITEM_SYNC: (itemId: string) => string;
|
|
48
49
|
readonly WISHLIST_VALIDATE: "/api/user/wishlist/validate";
|
|
49
50
|
readonly HISTORY: "/api/user/history";
|
|
50
51
|
readonly HISTORY_ITEM: (productId: string) => string;
|
|
@@ -147,6 +148,7 @@ export declare const ADMIN_ENDPOINTS: {
|
|
|
147
148
|
readonly EVENT_STATUS: (id: string) => string;
|
|
148
149
|
readonly EVENT_STATS: (id: string) => string;
|
|
149
150
|
readonly EVENT_ENTRIES: (id: string) => string;
|
|
151
|
+
readonly EVENT_ENTRIES_EXPORT: (id: string) => string;
|
|
150
152
|
readonly EVENT_ENTRY_BY_ID: (eventId: string, entryId: string) => string;
|
|
151
153
|
readonly EVENT_TRIGGER_RAFFLE: (id: string) => string;
|
|
152
154
|
readonly COUPONS: "/api/admin/coupons";
|
|
@@ -492,6 +494,7 @@ export declare const API_ENDPOINTS: {
|
|
|
492
494
|
readonly ORDER_BY_ID: (orderId: string) => string;
|
|
493
495
|
readonly WISHLIST: "/api/user/wishlist";
|
|
494
496
|
readonly WISHLIST_ITEM_BY_ID: (itemId: string) => string;
|
|
497
|
+
readonly WISHLIST_ITEM_SYNC: (itemId: string) => string;
|
|
495
498
|
readonly WISHLIST_VALIDATE: "/api/user/wishlist/validate";
|
|
496
499
|
readonly HISTORY: "/api/user/history";
|
|
497
500
|
readonly HISTORY_ITEM: (productId: string) => string;
|
|
@@ -594,6 +597,7 @@ export declare const API_ENDPOINTS: {
|
|
|
594
597
|
readonly EVENT_STATUS: (id: string) => string;
|
|
595
598
|
readonly EVENT_STATS: (id: string) => string;
|
|
596
599
|
readonly EVENT_ENTRIES: (id: string) => string;
|
|
600
|
+
readonly EVENT_ENTRIES_EXPORT: (id: string) => string;
|
|
597
601
|
readonly EVENT_ENTRY_BY_ID: (eventId: string, entryId: string) => string;
|
|
598
602
|
readonly EVENT_TRIGGER_RAFFLE: (id: string) => string;
|
|
599
603
|
readonly COUPONS: "/api/admin/coupons";
|
|
@@ -941,6 +945,7 @@ export declare const API_ROUTES: {
|
|
|
941
945
|
readonly ORDER_BY_ID: (orderId: string) => string;
|
|
942
946
|
readonly WISHLIST: "/api/user/wishlist";
|
|
943
947
|
readonly WISHLIST_ITEM_BY_ID: (itemId: string) => string;
|
|
948
|
+
readonly WISHLIST_ITEM_SYNC: (itemId: string) => string;
|
|
944
949
|
readonly WISHLIST_VALIDATE: "/api/user/wishlist/validate";
|
|
945
950
|
readonly HISTORY: "/api/user/history";
|
|
946
951
|
readonly HISTORY_ITEM: (productId: string) => string;
|
|
@@ -1043,6 +1048,7 @@ export declare const API_ROUTES: {
|
|
|
1043
1048
|
readonly EVENT_STATUS: (id: string) => string;
|
|
1044
1049
|
readonly EVENT_STATS: (id: string) => string;
|
|
1045
1050
|
readonly EVENT_ENTRIES: (id: string) => string;
|
|
1051
|
+
readonly EVENT_ENTRIES_EXPORT: (id: string) => string;
|
|
1046
1052
|
readonly EVENT_ENTRY_BY_ID: (eventId: string, entryId: string) => string;
|
|
1047
1053
|
readonly EVENT_TRIGGER_RAFFLE: (id: string) => string;
|
|
1048
1054
|
readonly COUPONS: "/api/admin/coupons";
|
|
@@ -60,6 +60,7 @@ export const ACCOUNT_ENDPOINTS = {
|
|
|
60
60
|
ORDER_BY_ID: (orderId) => `/api/user/orders/${orderId}`,
|
|
61
61
|
WISHLIST: "/api/user/wishlist",
|
|
62
62
|
WISHLIST_ITEM_BY_ID: (itemId) => `/api/user/wishlist/${encodeURIComponent(itemId)}`,
|
|
63
|
+
WISHLIST_ITEM_SYNC: (itemId) => `/api/user/wishlist/${encodeURIComponent(itemId)}/sync`,
|
|
63
64
|
WISHLIST_VALIDATE: "/api/user/wishlist/validate",
|
|
64
65
|
HISTORY: "/api/user/history",
|
|
65
66
|
HISTORY_ITEM: (productId) => `/api/user/history/${encodeURIComponent(productId)}`,
|
|
@@ -174,6 +175,7 @@ export const ADMIN_ENDPOINTS = {
|
|
|
174
175
|
EVENT_STATUS: (id) => `/api/admin/events/${id}/status`,
|
|
175
176
|
EVENT_STATS: (id) => `/api/admin/events/${id}/stats`,
|
|
176
177
|
EVENT_ENTRIES: (id) => `/api/admin/events/${id}/entries`,
|
|
178
|
+
EVENT_ENTRIES_EXPORT: (id) => `/api/admin/events/${id}/entries/export`,
|
|
177
179
|
EVENT_ENTRY_BY_ID: (eventId, entryId) => `/api/admin/events/${eventId}/entries/${entryId}`,
|
|
178
180
|
// SB9-D — admin manual raffle trigger
|
|
179
181
|
EVENT_TRIGGER_RAFFLE: (id) => `/api/admin/events/${id}/trigger-raffle`,
|
|
@@ -318,6 +318,7 @@ export declare const EVENT_FIELDS: {
|
|
|
318
318
|
readonly SPIN_MAX_PER_USER: "spinMaxPerUser";
|
|
319
319
|
readonly SPIN_WINDOW_START: "spinWindowStart";
|
|
320
320
|
readonly SPIN_WINDOW_END: "spinWindowEnd";
|
|
321
|
+
readonly ALLOW_GUEST_PARTICIPATION: "allowGuestParticipation";
|
|
321
322
|
readonly CREATED_AT: "createdAt";
|
|
322
323
|
readonly UPDATED_AT: "updatedAt";
|
|
323
324
|
readonly STATUS_VALUES: {
|
|
@@ -353,9 +354,11 @@ export declare const EVENT_ENTRY_FIELDS: {
|
|
|
353
354
|
readonly STATUS: "status";
|
|
354
355
|
readonly RAFFLE_ELIGIBLE: "raffleEligible";
|
|
355
356
|
readonly SPIN_USED: "spinUsed";
|
|
357
|
+
readonly SPIN_COUNT: "spinCount";
|
|
356
358
|
readonly SPIN_PRIZE_ID: "spinPrizeId";
|
|
357
359
|
readonly SPIN_PRIZE_COUPON_CODE: "spinPrizeCouponCode";
|
|
358
360
|
readonly SPIN_WON_AT: "spinWonAt";
|
|
361
|
+
readonly GUEST_IP_HASH: "guestIpHash";
|
|
359
362
|
readonly CREATED_AT: "createdAt";
|
|
360
363
|
readonly STATUS_VALUES: {
|
|
361
364
|
readonly CONFIRMED: "CONFIRMED";
|