@mohasinac/appkit 3.0.4 → 3.0.6
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/server/features/auctions/data.d.ts +2 -4
- package/dist/_internal/server/features/auctions/data.js +3 -9
- package/dist/_internal/server/features/classified/adapters.d.ts +2 -15
- package/dist/_internal/server/features/classified/adapters.js +2 -17
- package/dist/_internal/server/features/classified/data.d.ts +1 -6
- package/dist/_internal/server/features/classified/data.js +2 -10
- package/dist/_internal/server/features/digital-code/adapters.d.ts +2 -15
- package/dist/_internal/server/features/digital-code/adapters.js +2 -17
- package/dist/_internal/server/features/digital-code/data.d.ts +1 -6
- package/dist/_internal/server/features/digital-code/data.js +2 -10
- package/dist/_internal/server/features/live/adapters.d.ts +2 -15
- package/dist/_internal/server/features/live/adapters.js +2 -17
- package/dist/_internal/server/features/live/data.d.ts +1 -6
- package/dist/_internal/server/features/live/data.js +2 -10
- package/dist/_internal/server/features/pre-orders/data.d.ts +2 -4
- package/dist/_internal/server/features/pre-orders/data.js +3 -9
- package/dist/_internal/server/features/prize-draws/actions.d.ts +2 -0
- package/dist/_internal/server/features/prize-draws/actions.js +22 -0
- package/dist/_internal/server/features/prize-draws/data.d.ts +1 -17
- package/dist/_internal/server/features/prize-draws/data.js +2 -20
- package/dist/_internal/server/features/prize-draws/index.d.ts +3 -1
- package/dist/_internal/server/features/prize-draws/index.js +2 -0
- package/dist/_internal/server/features/prize-draws/service.d.ts +3 -0
- package/dist/_internal/server/features/prize-draws/service.js +19 -0
- package/dist/_internal/server/features/shared/listing-adapters.d.ts +19 -0
- package/dist/_internal/server/features/shared/listing-adapters.js +20 -0
- package/dist/_internal/server/features/shared/listing-data-factory.d.ts +9 -0
- package/dist/_internal/server/features/shared/listing-data-factory.js +33 -0
- package/dist/_internal/server/features/stores/data.d.ts +3 -14
- package/dist/_internal/server/features/stores/data.js +6 -44
- package/dist/_internal/shared/features/cart/schema.d.ts +8 -8
- package/dist/_internal/shared/features/cart/schema.js +3 -0
- package/dist/_internal/shared/listing-types/_registry.js +2 -0
- package/dist/_internal/shared/listing-types/auction/schema.d.ts +3 -1
- package/dist/_internal/shared/listing-types/auction/schema.js +7 -1
- package/dist/_internal/shared/listing-types/classified/schema.d.ts +2 -1
- package/dist/_internal/shared/listing-types/classified/schema.js +3 -1
- package/dist/_internal/shared/listing-types/digital-code/schema.d.ts +3 -1
- package/dist/_internal/shared/listing-types/digital-code/schema.js +7 -1
- package/dist/_internal/shared/listing-types/live/schema.d.ts +2 -1
- package/dist/_internal/shared/listing-types/live/schema.js +3 -1
- package/dist/_internal/shared/listing-types/pre-order/schema.d.ts +3 -1
- package/dist/_internal/shared/listing-types/pre-order/schema.js +7 -1
- package/dist/_internal/shared/listing-types/prize-draw/schema.d.ts +3 -1
- package/dist/_internal/shared/listing-types/prize-draw/schema.js +13 -1
- package/dist/_internal/shared/listing-types/standard/schema.d.ts +2 -1
- package/dist/_internal/shared/listing-types/standard/schema.js +4 -1
- package/dist/_internal/shared/types/base-document.d.ts +15 -0
- package/dist/_internal/shared/types/base-document.js +1 -0
- package/dist/_internal/shared/types/index.d.ts +2 -0
- package/dist/_internal/shared/types/index.js +1 -0
- package/dist/client.d.ts +4 -4
- package/dist/client.js +2 -2
- package/dist/constants/api-endpoints.d.ts +12 -0
- package/dist/constants/api-endpoints.js +4 -0
- package/dist/features/addresses/schemas/firestore.d.ts +2 -4
- package/dist/features/admin/components/AdminFulfillmentView.d.ts +6 -0
- package/dist/features/admin/components/AdminFulfillmentView.js +107 -0
- package/dist/features/admin/components/AdminProductEditorView.js +21 -9
- package/dist/features/admin/components/AdminProductsView.js +3 -0
- package/dist/features/admin/components/DataListingView.d.ts +1 -0
- package/dist/features/admin/components/index.d.ts +2 -0
- package/dist/features/admin/components/index.js +1 -0
- package/dist/features/admin/schemas/firestore.d.ts +3 -8
- package/dist/features/auctions/schemas/firestore.d.ts +2 -4
- package/dist/features/auctions/schemas/index.d.ts +2 -2
- package/dist/features/before-after/schemas/index.d.ts +2 -2
- package/dist/features/blog/schemas/firestore.d.ts +2 -4
- package/dist/features/blog/schemas/index.d.ts +4 -4
- package/dist/features/cart/schemas/firestore.d.ts +2 -4
- package/dist/features/categories/schemas/firestore.d.ts +2 -4
- package/dist/features/categories/schemas/index.d.ts +4 -4
- package/dist/features/events/schemas/firestore.d.ts +2 -4
- package/dist/features/events/schemas/index.d.ts +2 -2
- package/dist/features/faq/schemas/firestore.d.ts +2 -4
- package/dist/features/faq/schemas/index.d.ts +2 -2
- package/dist/features/grouped/schemas/index.d.ts +2 -2
- package/dist/features/homepage/schemas/firestore.d.ts +4 -12
- package/dist/features/homepage/schemas/index.d.ts +2 -2
- package/dist/features/messages/schemas/firestore.d.ts +2 -4
- package/dist/features/messages/schemas/index.d.ts +2 -2
- package/dist/features/orders/repository/orders.repository.d.ts +5 -0
- package/dist/features/orders/repository/orders.repository.js +26 -0
- package/dist/features/orders/schemas/firestore.d.ts +9 -5
- package/dist/features/orders/schemas/firestore.js +3 -0
- package/dist/features/payments/schemas/firestore.d.ts +2 -4
- package/dist/features/pre-orders/schemas/index.d.ts +2 -2
- package/dist/features/products/constants/action-defs.d.ts +16 -0
- package/dist/features/products/constants/action-defs.js +16 -0
- package/dist/features/products/constants/listing-tabs.d.ts +48 -0
- package/dist/features/products/constants/listing-tabs.js +12 -0
- package/dist/features/products/repository/products.repository.d.ts +37 -0
- package/dist/features/products/repository/products.repository.js +28 -1
- package/dist/features/products/schemas/firestore.d.ts +8 -6
- package/dist/features/products/schemas/firestore.js +2 -0
- package/dist/features/products/schemas/index.d.ts +6 -6
- package/dist/features/products/types/index.d.ts +2 -0
- package/dist/features/promotions/schemas/firestore.d.ts +2 -4
- package/dist/features/promotions/schemas/index.d.ts +4 -4
- package/dist/features/reviews/schemas/firestore.d.ts +2 -4
- package/dist/features/reviews/schemas/index.d.ts +2 -2
- package/dist/features/scams/schemas/firestore.d.ts +2 -4
- package/dist/features/scams/schemas/index.d.ts +4 -4
- package/dist/features/search/schemas/index.d.ts +2 -2
- package/dist/features/seller/components/BarcodeField.d.ts +17 -0
- package/dist/features/seller/components/BarcodeField.js +30 -0
- package/dist/features/seller/components/FulfillmentView.d.ts +5 -0
- package/dist/features/seller/components/FulfillmentView.js +120 -0
- package/dist/features/seller/components/PrintCenterView.d.ts +3 -1
- package/dist/features/seller/components/PrintCenterView.js +52 -4
- package/dist/features/seller/components/SellerProductShell.d.ts +2 -0
- package/dist/features/seller/components/SellerProductShell.js +2 -1
- package/dist/features/seller/components/index.d.ts +4 -0
- package/dist/features/seller/components/index.js +2 -0
- package/dist/features/seller/schemas/index.d.ts +2 -2
- package/dist/features/store-extensions/schemas/firestore.d.ts +12 -44
- package/dist/features/stores/components/StoreClassifiedsListing.d.ts +5 -0
- package/dist/features/stores/components/StoreClassifiedsListing.js +48 -0
- package/dist/features/stores/components/StoreClassifiedsPageView.d.ts +4 -0
- package/dist/features/stores/components/StoreClassifiedsPageView.js +20 -0
- package/dist/features/stores/components/StoreDetailLayoutView.js +23 -2
- package/dist/features/stores/components/StoreDigitalCodesListing.d.ts +5 -0
- package/dist/features/stores/components/StoreDigitalCodesListing.js +48 -0
- package/dist/features/stores/components/StoreDigitalCodesPageView.d.ts +4 -0
- package/dist/features/stores/components/StoreDigitalCodesPageView.js +20 -0
- package/dist/features/stores/components/StoreLiveItemsListing.d.ts +5 -0
- package/dist/features/stores/components/StoreLiveItemsListing.js +48 -0
- package/dist/features/stores/components/StoreLiveItemsPageView.d.ts +4 -0
- package/dist/features/stores/components/StoreLiveItemsPageView.js +20 -0
- package/dist/features/stores/components/index.d.ts +9 -0
- package/dist/features/stores/components/index.js +3 -0
- package/dist/features/stores/schemas/firestore.d.ts +2 -4
- package/dist/features/stores/schemas/index.d.ts +4 -4
- package/dist/features/support/schemas/firestore.d.ts +2 -4
- package/dist/features/support/schemas/index.d.ts +2 -2
- package/dist/next/routing/route-map.d.ts +11 -0
- package/dist/next/routing/route-map.js +5 -0
- package/dist/schemas/registry.d.ts +24 -24
- package/dist/seed/grouped-listings-seed-data.d.ts +2 -1
- package/dist/seed/products-preorders-seed-data.d.ts +2 -1
- package/dist/seed/products-standard-seed-data.js +8 -0
- package/dist/server-entry.d.ts +3 -0
- package/dist/server-entry.js +3 -0
- package/dist/server.d.ts +4 -4
- package/dist/styles.css +1 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/utils/id-generators.d.ts +8 -0
- package/dist/utils/id-generators.js +14 -0
- package/package.json +2 -1
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export declare const getAuctionForDetail: (slugOrId: string) => Promise<ProductDocument | null>;
|
|
4
|
-
export declare const getProductFeaturesForAuction: (storeId: string | null) => Promise<ProductFeatureDocument[]>;
|
|
1
|
+
export declare const getAuctionForDetail: (slugOrId: string) => Promise<import("../../../..").ProductDocument | null>;
|
|
2
|
+
export declare const getProductFeaturesForAuction: (storeId: string | null) => Promise<import("../../../..").ProductFeatureDocument[]>;
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const getAuctionForDetail = cache(async (slugOrId) => {
|
|
5
|
-
return (await productRepository.findByIdOrSlug(slugOrId).catch(() => undefined)) ?? null;
|
|
6
|
-
});
|
|
7
|
-
export const getProductFeaturesForAuction = cache(async (storeId) => {
|
|
8
|
-
return loadProductFeaturesForStore(storeId).catch(() => []);
|
|
9
|
-
});
|
|
1
|
+
import { makeGetListingForDetail, getProductFeaturesForStore } from "../shared/listing-data-factory";
|
|
2
|
+
export const getAuctionForDetail = makeGetListingForDetail("auction");
|
|
3
|
+
export const getProductFeaturesForAuction = getProductFeaturesForStore;
|
|
@@ -1,21 +1,8 @@
|
|
|
1
1
|
import type { ProductDocument, ProductClassifiedMeta } from "../../../../features/products/schemas/firestore";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
title: string;
|
|
5
|
-
description: string;
|
|
6
|
-
price: number;
|
|
7
|
-
priceLabel: string;
|
|
8
|
-
currency: string;
|
|
9
|
-
mainImage: string | null;
|
|
10
|
-
images: string[];
|
|
11
|
-
storeId: string;
|
|
12
|
-
storeName: string | null;
|
|
13
|
-
category: string;
|
|
2
|
+
import { type BaseListingClientShape } from "../shared/listing-adapters";
|
|
3
|
+
export interface ClassifiedClientShape extends BaseListingClientShape {
|
|
14
4
|
condition: ProductDocument["condition"] | null;
|
|
15
|
-
tags: string[];
|
|
16
5
|
classified: ProductClassifiedMeta | null;
|
|
17
|
-
status: ProductDocument["status"];
|
|
18
|
-
createdAt: string;
|
|
19
6
|
}
|
|
20
7
|
/** Maps a raw `ProductDocument` to the client-safe classified shape. */
|
|
21
8
|
export declare function toClientClassified(doc: ProductDocument): ClassifiedClientShape;
|
|
@@ -1,24 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mapBaseListingFields } from "../shared/listing-adapters";
|
|
2
2
|
/** Maps a raw `ProductDocument` to the client-safe classified shape. */
|
|
3
3
|
export function toClientClassified(doc) {
|
|
4
4
|
return {
|
|
5
|
-
|
|
6
|
-
title: doc.title,
|
|
7
|
-
description: doc.description,
|
|
8
|
-
price: doc.price,
|
|
9
|
-
priceLabel: formatCurrency(doc.price, doc.currency ?? "INR"),
|
|
10
|
-
currency: doc.currency ?? "INR",
|
|
11
|
-
mainImage: doc.mainImage || doc.images?.[0] || null,
|
|
12
|
-
images: doc.images ?? [],
|
|
13
|
-
storeId: doc.storeId,
|
|
14
|
-
storeName: doc.storeName ?? null,
|
|
15
|
-
category: doc.categorySlugs?.[0] ?? doc.category ?? "",
|
|
5
|
+
...mapBaseListingFields(doc),
|
|
16
6
|
condition: doc.condition ?? null,
|
|
17
|
-
tags: doc.tags ?? [],
|
|
18
7
|
classified: doc.classified ?? null,
|
|
19
|
-
status: doc.status,
|
|
20
|
-
createdAt: doc.createdAt instanceof Date
|
|
21
|
-
? doc.createdAt.toISOString()
|
|
22
|
-
: String(doc.createdAt),
|
|
23
8
|
};
|
|
24
9
|
}
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export interface ClassifiedDataOptions {
|
|
3
|
-
_reserved?: never;
|
|
4
|
-
}
|
|
5
|
-
/** Fetch a single classified listing by slug, deduped per RSC render. */
|
|
6
|
-
export declare const getClassifiedForDetail: (slug: string, _opts?: ClassifiedDataOptions) => Promise<ProductDocument | null>;
|
|
1
|
+
export declare const getClassifiedForDetail: (slugOrId: string) => Promise<import("../../../..").ProductDocument | null>;
|
|
@@ -1,10 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/** Fetch a single classified listing by slug, deduped per RSC render. */
|
|
4
|
-
export const getClassifiedForDetail = cache(async (slug, _opts) => {
|
|
5
|
-
void _opts;
|
|
6
|
-
const product = await productRepository.findByIdOrSlug(slug).catch(() => undefined);
|
|
7
|
-
if (!product || product.listingType !== "classified")
|
|
8
|
-
return null;
|
|
9
|
-
return product;
|
|
10
|
-
});
|
|
1
|
+
import { makeGetListingForDetail } from "../shared/listing-data-factory";
|
|
2
|
+
export const getClassifiedForDetail = makeGetListingForDetail("classified");
|
|
@@ -1,21 +1,8 @@
|
|
|
1
1
|
import type { ProductDocument, ProductDigitalCodeMeta } from "../../../../features/products/schemas/firestore";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
title: string;
|
|
5
|
-
description: string;
|
|
6
|
-
price: number;
|
|
7
|
-
priceLabel: string;
|
|
8
|
-
currency: string;
|
|
9
|
-
mainImage: string | null;
|
|
10
|
-
images: string[];
|
|
11
|
-
storeId: string;
|
|
12
|
-
storeName: string | null;
|
|
13
|
-
category: string;
|
|
14
|
-
tags: string[];
|
|
2
|
+
import { type BaseListingClientShape } from "../shared/listing-adapters";
|
|
3
|
+
export interface DigitalCodeClientShape extends BaseListingClientShape {
|
|
15
4
|
/** Delivery method and redemption instructions — codesAvailable intentionally omitted (operational). */
|
|
16
5
|
digitalCode: Pick<ProductDigitalCodeMeta, "codeDeliveryMethod" | "redemptionInstructions"> | null;
|
|
17
|
-
status: ProductDocument["status"];
|
|
18
|
-
createdAt: string;
|
|
19
6
|
}
|
|
20
7
|
/** Maps a raw `ProductDocument` to the client-safe digital-code shape. Strips codesAvailable/codePoolSize (operational counters). */
|
|
21
8
|
export declare function toClientDigitalCode(doc: ProductDocument): DigitalCodeClientShape;
|
|
@@ -1,29 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mapBaseListingFields } from "../shared/listing-adapters";
|
|
2
2
|
/** Maps a raw `ProductDocument` to the client-safe digital-code shape. Strips codesAvailable/codePoolSize (operational counters). */
|
|
3
3
|
export function toClientDigitalCode(doc) {
|
|
4
4
|
const dc = doc.digitalCode ?? null;
|
|
5
5
|
return {
|
|
6
|
-
|
|
7
|
-
title: doc.title,
|
|
8
|
-
description: doc.description,
|
|
9
|
-
price: doc.price,
|
|
10
|
-
priceLabel: formatCurrency(doc.price, doc.currency ?? "INR"),
|
|
11
|
-
currency: doc.currency ?? "INR",
|
|
12
|
-
mainImage: doc.mainImage || doc.images?.[0] || null,
|
|
13
|
-
images: doc.images ?? [],
|
|
14
|
-
storeId: doc.storeId,
|
|
15
|
-
storeName: doc.storeName ?? null,
|
|
16
|
-
category: doc.categorySlugs?.[0] ?? doc.category ?? "",
|
|
17
|
-
tags: doc.tags ?? [],
|
|
6
|
+
...mapBaseListingFields(doc),
|
|
18
7
|
digitalCode: dc
|
|
19
8
|
? {
|
|
20
9
|
codeDeliveryMethod: dc.codeDeliveryMethod,
|
|
21
10
|
redemptionInstructions: dc.redemptionInstructions,
|
|
22
11
|
}
|
|
23
12
|
: null,
|
|
24
|
-
status: doc.status,
|
|
25
|
-
createdAt: doc.createdAt instanceof Date
|
|
26
|
-
? doc.createdAt.toISOString()
|
|
27
|
-
: String(doc.createdAt),
|
|
28
13
|
};
|
|
29
14
|
}
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export interface DigitalCodeDataOptions {
|
|
3
|
-
_reserved?: never;
|
|
4
|
-
}
|
|
5
|
-
/** Fetch a single digital-code listing by slug, deduped per RSC render. */
|
|
6
|
-
export declare const getDigitalCodeForDetail: (slug: string, _opts?: DigitalCodeDataOptions) => Promise<ProductDocument | null>;
|
|
1
|
+
export declare const getDigitalCodeForDetail: (slugOrId: string) => Promise<import("../../../..").ProductDocument | null>;
|
|
@@ -1,10 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/** Fetch a single digital-code listing by slug, deduped per RSC render. */
|
|
4
|
-
export const getDigitalCodeForDetail = cache(async (slug, _opts) => {
|
|
5
|
-
void _opts;
|
|
6
|
-
const product = await productRepository.findByIdOrSlug(slug).catch(() => undefined);
|
|
7
|
-
if (!product || product.listingType !== "digital-code")
|
|
8
|
-
return null;
|
|
9
|
-
return product;
|
|
10
|
-
});
|
|
1
|
+
import { makeGetListingForDetail } from "../shared/listing-data-factory";
|
|
2
|
+
export const getDigitalCodeForDetail = makeGetListingForDetail("digital-code");
|
|
@@ -1,21 +1,8 @@
|
|
|
1
1
|
import type { ProductDocument, ProductLiveItemMeta } from "../../../../features/products/schemas/firestore";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
title: string;
|
|
5
|
-
description: string;
|
|
6
|
-
price: number;
|
|
7
|
-
priceLabel: string;
|
|
8
|
-
currency: string;
|
|
9
|
-
mainImage: string | null;
|
|
10
|
-
images: string[];
|
|
11
|
-
storeId: string;
|
|
12
|
-
storeName: string | null;
|
|
13
|
-
category: string;
|
|
14
|
-
tags: string[];
|
|
2
|
+
import { type BaseListingClientShape } from "../shared/listing-adapters";
|
|
3
|
+
export interface LiveItemClientShape extends BaseListingClientShape {
|
|
15
4
|
/** Live-item meta — vendorVerified is intentionally omitted (admin-only). */
|
|
16
5
|
liveItem: Omit<ProductLiveItemMeta, "vendorVerified"> | null;
|
|
17
|
-
status: ProductDocument["status"];
|
|
18
|
-
createdAt: string;
|
|
19
6
|
}
|
|
20
7
|
/** Maps a raw `ProductDocument` to the client-safe live-item shape. Strips vendorVerified (admin-only). */
|
|
21
8
|
export declare function toClientLiveItem(doc: ProductDocument): LiveItemClientShape;
|
|
@@ -1,20 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mapBaseListingFields } from "../shared/listing-adapters";
|
|
2
2
|
/** Maps a raw `ProductDocument` to the client-safe live-item shape. Strips vendorVerified (admin-only). */
|
|
3
3
|
export function toClientLiveItem(doc) {
|
|
4
4
|
const li = doc.liveItem ?? null;
|
|
5
5
|
return {
|
|
6
|
-
|
|
7
|
-
title: doc.title,
|
|
8
|
-
description: doc.description,
|
|
9
|
-
price: doc.price,
|
|
10
|
-
priceLabel: formatCurrency(doc.price, doc.currency ?? "INR"),
|
|
11
|
-
currency: doc.currency ?? "INR",
|
|
12
|
-
mainImage: doc.mainImage || doc.images?.[0] || null,
|
|
13
|
-
images: doc.images ?? [],
|
|
14
|
-
storeId: doc.storeId,
|
|
15
|
-
storeName: doc.storeName ?? null,
|
|
16
|
-
category: doc.categorySlugs?.[0] ?? doc.category ?? "",
|
|
17
|
-
tags: doc.tags ?? [],
|
|
6
|
+
...mapBaseListingFields(doc),
|
|
18
7
|
liveItem: li
|
|
19
8
|
? {
|
|
20
9
|
species: li.species,
|
|
@@ -26,9 +15,5 @@ export function toClientLiveItem(doc) {
|
|
|
26
15
|
cites: li.cites,
|
|
27
16
|
}
|
|
28
17
|
: null,
|
|
29
|
-
status: doc.status,
|
|
30
|
-
createdAt: doc.createdAt instanceof Date
|
|
31
|
-
? doc.createdAt.toISOString()
|
|
32
|
-
: String(doc.createdAt),
|
|
33
18
|
};
|
|
34
19
|
}
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export interface LiveDataOptions {
|
|
3
|
-
_reserved?: never;
|
|
4
|
-
}
|
|
5
|
-
/** Fetch a single live-item listing by slug, deduped per RSC render. */
|
|
6
|
-
export declare const getLiveItemForDetail: (slug: string, _opts?: LiveDataOptions) => Promise<ProductDocument | null>;
|
|
1
|
+
export declare const getLiveItemForDetail: (slugOrId: string) => Promise<import("../../../..").ProductDocument | null>;
|
|
@@ -1,10 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/** Fetch a single live-item listing by slug, deduped per RSC render. */
|
|
4
|
-
export const getLiveItemForDetail = cache(async (slug, _opts) => {
|
|
5
|
-
void _opts;
|
|
6
|
-
const product = await productRepository.findByIdOrSlug(slug).catch(() => undefined);
|
|
7
|
-
if (!product || product.listingType !== "live")
|
|
8
|
-
return null;
|
|
9
|
-
return product;
|
|
10
|
-
});
|
|
1
|
+
import { makeGetListingForDetail } from "../shared/listing-data-factory";
|
|
2
|
+
export const getLiveItemForDetail = makeGetListingForDetail("live");
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export declare const getPreOrderForDetail: (slugOrId: string) => Promise<ProductDocument | null>;
|
|
4
|
-
export declare const getProductFeaturesForPreOrder: (storeId: string | null) => Promise<ProductFeatureDocument[]>;
|
|
1
|
+
export declare const getPreOrderForDetail: (slugOrId: string) => Promise<import("../../../..").ProductDocument | null>;
|
|
2
|
+
export declare const getProductFeaturesForPreOrder: (storeId: string | null) => Promise<import("../../../..").ProductFeatureDocument[]>;
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const getPreOrderForDetail = cache(async (slugOrId) => {
|
|
5
|
-
return (await productRepository.findByIdOrSlug(slugOrId).catch(() => undefined)) ?? null;
|
|
6
|
-
});
|
|
7
|
-
export const getProductFeaturesForPreOrder = cache(async (storeId) => {
|
|
8
|
-
return loadProductFeaturesForStore(storeId).catch(() => []);
|
|
9
|
-
});
|
|
1
|
+
import { makeGetListingForDetail, getProductFeaturesForStore } from "../shared/listing-data-factory";
|
|
2
|
+
export const getPreOrderForDetail = makeGetListingForDetail("pre-order");
|
|
3
|
+
export const getProductFeaturesForPreOrder = getProductFeaturesForStore;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
import { wrapAction } from "@mohasinac/appkit/server";
|
|
3
|
+
import { productRepository } from "../../../../repositories";
|
|
4
|
+
import { requireRoleUser } from "../../../../providers/auth-firebase/helpers";
|
|
5
|
+
import { assertPrizeDrawOpen } from "./service";
|
|
6
|
+
export async function enterPrizeDrawAction(input) {
|
|
7
|
+
return wrapAction(async () => {
|
|
8
|
+
const user = await requireRoleUser(["user", "buyer", "seller", "admin"]);
|
|
9
|
+
const { prizeDrawId } = input;
|
|
10
|
+
if (!prizeDrawId)
|
|
11
|
+
throw new Error("prizeDrawId is required.");
|
|
12
|
+
const product = await productRepository.findByIdOrSlug(prizeDrawId).catch(() => null);
|
|
13
|
+
if (!product)
|
|
14
|
+
throw new Error("Prize draw not found.");
|
|
15
|
+
assertPrizeDrawOpen(product);
|
|
16
|
+
// Increment the entry count — server-side only, not exposed to the client adapter.
|
|
17
|
+
await productRepository.update(prizeDrawId, {
|
|
18
|
+
prizeCurrentEntries: (product.prizeCurrentEntries ?? 0) + 1,
|
|
19
|
+
});
|
|
20
|
+
return { entryRecorded: true, userId: user.uid };
|
|
21
|
+
});
|
|
22
|
+
}
|
|
@@ -1,17 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Prize Draw data layer — OG-coverage-followup 2026-05-23.
|
|
3
|
-
*
|
|
4
|
-
* Prize draws live as products with `listingType:"prize-draw"`. This file
|
|
5
|
-
* wraps the repo call in `React.cache` so the OG renderer and any future
|
|
6
|
-
* page/generateMetadata pair share one Firestore read per request.
|
|
7
|
-
*/
|
|
8
|
-
import type { ProductDocument } from "../../../../features/products/schemas/firestore";
|
|
9
|
-
export interface PrizeDrawDataOptions {
|
|
10
|
-
_reserved?: never;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Fetch a single prize-draw product by slug or id. Returns null when the
|
|
14
|
-
* slug is empty or no matching product exists. The caller is responsible
|
|
15
|
-
* for asserting `listingType === "prize-draw"` if a strict gate is required.
|
|
16
|
-
*/
|
|
17
|
-
export declare const getPrizeDrawForDetail: (slugOrId: string, _opts?: PrizeDrawDataOptions) => Promise<ProductDocument | null>;
|
|
1
|
+
export declare const getPrizeDrawForDetail: (slugOrId: string) => Promise<import("../../../..").ProductDocument | null>;
|
|
@@ -1,20 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Prize draws live as products with `listingType:"prize-draw"`. This file
|
|
5
|
-
* wraps the repo call in `React.cache` so the OG renderer and any future
|
|
6
|
-
* page/generateMetadata pair share one Firestore read per request.
|
|
7
|
-
*/
|
|
8
|
-
import { cache } from "react";
|
|
9
|
-
import { productRepository } from "../../../../repositories";
|
|
10
|
-
/**
|
|
11
|
-
* Fetch a single prize-draw product by slug or id. Returns null when the
|
|
12
|
-
* slug is empty or no matching product exists. The caller is responsible
|
|
13
|
-
* for asserting `listingType === "prize-draw"` if a strict gate is required.
|
|
14
|
-
*/
|
|
15
|
-
export const getPrizeDrawForDetail = cache(async (slugOrId, _opts) => {
|
|
16
|
-
void _opts;
|
|
17
|
-
if (!slugOrId)
|
|
18
|
-
return null;
|
|
19
|
-
return (await productRepository.findByIdOrSlug(slugOrId).catch(() => null)) ?? null;
|
|
20
|
-
});
|
|
1
|
+
import { makeGetListingForDetail } from "../shared/listing-data-factory";
|
|
2
|
+
export const getPrizeDrawForDetail = makeGetListingForDetail("prize-draw");
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
export { getPrizeDrawForDetail
|
|
1
|
+
export { getPrizeDrawForDetail } from "./data";
|
|
2
|
+
export { enterPrizeDrawAction } from "./actions";
|
|
3
|
+
export { assertPrizeDrawOpen } from "./service";
|
|
2
4
|
export { renderPrizeDrawOg, renderPrizeDrawOgImage, type PrizeDrawOgData, } from "./og";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ValidationError, CapacityError, ExpiredError } from "../../../shared/errors/index";
|
|
2
|
+
/** Assert the prize draw is accepting entries (published, reveal not started, slots not exhausted). */
|
|
3
|
+
export function assertPrizeDrawOpen(product) {
|
|
4
|
+
if (product.listingType !== "prize-draw") {
|
|
5
|
+
throw new ValidationError("Not a prize draw listing.");
|
|
6
|
+
}
|
|
7
|
+
if (product.status !== "published") {
|
|
8
|
+
throw new ValidationError("Prize draw is not active.");
|
|
9
|
+
}
|
|
10
|
+
const max = product.prizeMaxEntries ?? null;
|
|
11
|
+
const current = product.prizeCurrentEntries ?? 0;
|
|
12
|
+
if (typeof max === "number" && current >= max) {
|
|
13
|
+
throw new CapacityError("Prize draw is fully subscribed.");
|
|
14
|
+
}
|
|
15
|
+
const reveal = product.prizeRevealWindowStart;
|
|
16
|
+
if (reveal && new Date(reveal) <= new Date()) {
|
|
17
|
+
throw new ExpiredError("Prize draw entry window");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ProductDocument } from "../../../../features/products/schemas/firestore";
|
|
2
|
+
export interface BaseListingClientShape {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
description: string;
|
|
6
|
+
price: number;
|
|
7
|
+
priceLabel: string;
|
|
8
|
+
currency: string;
|
|
9
|
+
mainImage: string | null;
|
|
10
|
+
images: string[];
|
|
11
|
+
storeId: string;
|
|
12
|
+
storeName: string | null;
|
|
13
|
+
category: string;
|
|
14
|
+
tags: string[];
|
|
15
|
+
status: ProductDocument["status"];
|
|
16
|
+
createdAt: string;
|
|
17
|
+
}
|
|
18
|
+
/** Maps the 11 shared fields from a raw Firestore ProductDocument. */
|
|
19
|
+
export declare function mapBaseListingFields(doc: ProductDocument): BaseListingClientShape;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { formatCurrency } from "../../../../utils/number.formatter";
|
|
2
|
+
/** Maps the 11 shared fields from a raw Firestore ProductDocument. */
|
|
3
|
+
export function mapBaseListingFields(doc) {
|
|
4
|
+
return {
|
|
5
|
+
id: doc.id,
|
|
6
|
+
title: doc.title,
|
|
7
|
+
description: doc.description,
|
|
8
|
+
price: doc.price,
|
|
9
|
+
priceLabel: formatCurrency(doc.price, doc.currency ?? "INR"),
|
|
10
|
+
currency: doc.currency ?? "INR",
|
|
11
|
+
mainImage: doc.mainImage || doc.images?.[0] || null,
|
|
12
|
+
images: doc.images ?? [],
|
|
13
|
+
storeId: doc.storeId,
|
|
14
|
+
storeName: doc.storeName ?? null,
|
|
15
|
+
category: doc.categorySlugs?.[0] ?? doc.category ?? "",
|
|
16
|
+
tags: doc.tags ?? [],
|
|
17
|
+
status: doc.status,
|
|
18
|
+
createdAt: doc.createdAt instanceof Date ? doc.createdAt.toISOString() : String(doc.createdAt),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ListingType } from "../../../../features/products/types";
|
|
2
|
+
import type { ProductDocument } from "../../../../features/products/schemas/firestore";
|
|
3
|
+
import type { ProductFeatureDocument } from "../../../../features/products/schemas/product-features";
|
|
4
|
+
export declare function makeGetListingForDetail(type: ListingType): (slugOrId: string) => Promise<ProductDocument | null>;
|
|
5
|
+
export declare const getProductFeaturesForStore: (storeId: string | null) => Promise<ProductFeatureDocument[]>;
|
|
6
|
+
export declare function makeGetStoreListingsInitial(type: ListingType, pageSize: number): (storeId: string, page?: number) => Promise<{
|
|
7
|
+
items: ProductDocument[];
|
|
8
|
+
total: number;
|
|
9
|
+
}>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { cache } from "react";
|
|
2
|
+
import { productRepository } from "../../../../repositories";
|
|
3
|
+
import { loadProductFeaturesForStore } from "../../../../features/products/repository/loadProductFeatures";
|
|
4
|
+
// Returns a React.cache()-wrapped fetch gated on one listing type.
|
|
5
|
+
// The guard prevents cross-type URL collisions (e.g. /auctions/classified-slug returning wrong product).
|
|
6
|
+
export function makeGetListingForDetail(type) {
|
|
7
|
+
return cache(async (slugOrId) => {
|
|
8
|
+
if (!slugOrId)
|
|
9
|
+
return null;
|
|
10
|
+
const product = await productRepository.findByIdOrSlug(slugOrId).catch(() => undefined);
|
|
11
|
+
if (!product || product.listingType !== type)
|
|
12
|
+
return null;
|
|
13
|
+
return product;
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
// Product-feature badges are keyed by store, not listing type.
|
|
17
|
+
// Per-type data.ts files re-export this under a type-specific name.
|
|
18
|
+
export const getProductFeaturesForStore = cache(async (storeId) => loadProductFeaturesForStore(storeId).catch(() => []));
|
|
19
|
+
// Returns a React.cache()-wrapped function for store SSR first-page data.
|
|
20
|
+
// Export names in stores/data.ts stay identical so consumers need no changes.
|
|
21
|
+
export function makeGetStoreListingsInitial(type, pageSize) {
|
|
22
|
+
return cache(async (storeId, page = 1) => {
|
|
23
|
+
const result = await productRepository
|
|
24
|
+
.list({
|
|
25
|
+
filters: `storeId==${storeId},status==published,listingType==${type}`,
|
|
26
|
+
sorts: "-createdAt",
|
|
27
|
+
page,
|
|
28
|
+
pageSize,
|
|
29
|
+
})
|
|
30
|
+
.catch(() => null);
|
|
31
|
+
return { items: result?.items ?? [], total: result?.total ?? 0 };
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -1,27 +1,16 @@
|
|
|
1
1
|
import type { StoreDocument } from "../../../../features/stores/schemas/firestore";
|
|
2
|
-
import type { ProductDocument } from "../../../../features/products/schemas/firestore";
|
|
3
2
|
/** Full store document by slug — deduped per request via React.cache(). */
|
|
4
3
|
export declare const getStoreForDetail: (slug: string) => Promise<StoreDocument | null>;
|
|
5
|
-
/**
|
|
6
|
-
* Published products for a store detail page.
|
|
7
|
-
* Returns the first page used for SSR initial data.
|
|
8
|
-
*/
|
|
9
4
|
export declare const listStoreProductsInitial: (storeId: string, page?: number) => Promise<{
|
|
10
|
-
items: ProductDocument[];
|
|
5
|
+
items: import("../../../..").ProductDocument[];
|
|
11
6
|
total: number;
|
|
12
7
|
}>;
|
|
13
|
-
/**
|
|
14
|
-
* Published auctions for a store detail page.
|
|
15
|
-
*/
|
|
16
8
|
export declare const listStoreAuctionsInitial: (storeId: string, page?: number) => Promise<{
|
|
17
|
-
items: ProductDocument[];
|
|
9
|
+
items: import("../../../..").ProductDocument[];
|
|
18
10
|
total: number;
|
|
19
11
|
}>;
|
|
20
|
-
/**
|
|
21
|
-
* Published pre-orders for a store detail page.
|
|
22
|
-
*/
|
|
23
12
|
export declare const listStorePreOrdersInitial: (storeId: string, page?: number) => Promise<{
|
|
24
|
-
items: ProductDocument[];
|
|
13
|
+
items: import("../../../..").ProductDocument[];
|
|
25
14
|
total: number;
|
|
26
15
|
}>;
|
|
27
16
|
/** Stores for sitemap generation. */
|
|
@@ -1,54 +1,16 @@
|
|
|
1
1
|
"use server";
|
|
2
2
|
import { cache } from "react";
|
|
3
|
-
import { storeRepository
|
|
3
|
+
import { storeRepository } from "../../../../repositories";
|
|
4
4
|
import { STORES_PRODUCTS_PAGE_SIZE, STORES_SITEMAP_LIMIT, } from "../../../shared/features/stores/config";
|
|
5
|
+
import { makeGetStoreListingsInitial } from "../shared/listing-data-factory";
|
|
5
6
|
/** Full store document by slug — deduped per request via React.cache(). */
|
|
6
7
|
export const getStoreForDetail = cache(async (slug) => {
|
|
7
8
|
return (await storeRepository.findBySlug(slug).catch(() => undefined)) ?? null;
|
|
8
9
|
});
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export const listStoreProductsInitial = cache(async (storeId, page = 1) => {
|
|
14
|
-
const result = await productRepository
|
|
15
|
-
.list({
|
|
16
|
-
filters: `storeId==${storeId},status==published,listingType==standard`,
|
|
17
|
-
sorts: "-createdAt",
|
|
18
|
-
page,
|
|
19
|
-
pageSize: STORES_PRODUCTS_PAGE_SIZE,
|
|
20
|
-
})
|
|
21
|
-
.catch(() => null);
|
|
22
|
-
return { items: result?.items ?? [], total: result?.total ?? 0 };
|
|
23
|
-
});
|
|
24
|
-
/**
|
|
25
|
-
* Published auctions for a store detail page.
|
|
26
|
-
*/
|
|
27
|
-
export const listStoreAuctionsInitial = cache(async (storeId, page = 1) => {
|
|
28
|
-
const result = await productRepository
|
|
29
|
-
.list({
|
|
30
|
-
filters: `storeId==${storeId},status==published,listingType==auction`,
|
|
31
|
-
sorts: "-createdAt",
|
|
32
|
-
page,
|
|
33
|
-
pageSize: STORES_PRODUCTS_PAGE_SIZE,
|
|
34
|
-
})
|
|
35
|
-
.catch(() => null);
|
|
36
|
-
return { items: result?.items ?? [], total: result?.total ?? 0 };
|
|
37
|
-
});
|
|
38
|
-
/**
|
|
39
|
-
* Published pre-orders for a store detail page.
|
|
40
|
-
*/
|
|
41
|
-
export const listStorePreOrdersInitial = cache(async (storeId, page = 1) => {
|
|
42
|
-
const result = await productRepository
|
|
43
|
-
.list({
|
|
44
|
-
filters: `storeId==${storeId},status==published,listingType==pre-order`,
|
|
45
|
-
sorts: "-createdAt",
|
|
46
|
-
page,
|
|
47
|
-
pageSize: STORES_PRODUCTS_PAGE_SIZE,
|
|
48
|
-
})
|
|
49
|
-
.catch(() => null);
|
|
50
|
-
return { items: result?.items ?? [], total: result?.total ?? 0 };
|
|
51
|
-
});
|
|
10
|
+
// Collapse of three near-identical 14-line functions via factory — export names unchanged.
|
|
11
|
+
export const listStoreProductsInitial = makeGetStoreListingsInitial("standard", STORES_PRODUCTS_PAGE_SIZE);
|
|
12
|
+
export const listStoreAuctionsInitial = makeGetStoreListingsInitial("auction", STORES_PRODUCTS_PAGE_SIZE);
|
|
13
|
+
export const listStorePreOrdersInitial = makeGetStoreListingsInitial("pre-order", STORES_PRODUCTS_PAGE_SIZE);
|
|
52
14
|
/** Stores for sitemap generation. */
|
|
53
15
|
export const listSitemapStores = cache(async () => {
|
|
54
16
|
const result = await storeRepository
|