@mohasinac/appkit 4.55.0 → 4.57.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.
Files changed (86) hide show
  1. package/dist/.build-stamp.json +4 -4
  2. package/dist/_internal/server/features/checkout/actions.d.ts +53 -0
  3. package/dist/_internal/server/features/checkout/actions.js +156 -8
  4. package/dist/_internal/server/features/orders/actions.d.ts +30 -0
  5. package/dist/_internal/server/features/orders/actions.js +103 -0
  6. package/dist/_internal/server/features/orders/adapters.js +7 -0
  7. package/dist/_internal/server/features/shipping/reconcile.d.ts +28 -0
  8. package/dist/_internal/server/features/shipping/reconcile.js +93 -0
  9. package/dist/_internal/shared/actions/action-registry.js +53 -0
  10. package/dist/_internal/shared/config/schema.d.ts +6 -0
  11. package/dist/_internal/shared/listing-types/route-gating.d.ts +56 -0
  12. package/dist/_internal/shared/listing-types/route-gating.js +114 -0
  13. package/dist/_internal/shared/shipping/quote.d.ts +153 -0
  14. package/dist/_internal/shared/shipping/quote.js +123 -0
  15. package/dist/client.d.ts +22 -0
  16. package/dist/client.js +10 -0
  17. package/dist/features/about/components/PublicProfileView.js +2 -1
  18. package/dist/features/account/components/UserOrdersView.js +25 -3
  19. package/dist/features/admin/components/OwnerQuickActions.d.ts +1 -1
  20. package/dist/features/admin/components/OwnerQuickActions.js +53 -6
  21. package/dist/features/auctions/components/AuctionDetailPageView.js +2 -1
  22. package/dist/features/auth/schemas/firestore.d.ts +15 -0
  23. package/dist/features/blog/components/BlogPostView.js +2 -1
  24. package/dist/features/cart/components/CartPriceBreakdown.d.ts +2 -0
  25. package/dist/features/cart/components/CartPriceBreakdown.js +1 -1
  26. package/dist/features/categories/components/FranchiseDetailPageView.js +3 -1
  27. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +2 -1
  28. package/dist/features/faq/components/FAQPageContent.js +17 -4
  29. package/dist/features/faq/constants/help-guides.d.ts +36 -0
  30. package/dist/features/faq/constants/help-guides.js +64 -0
  31. package/dist/features/homepage/components/HeroCarousel.js +7 -3
  32. package/dist/features/homepage/components/MarketplaceHomepageView.js +16 -1
  33. package/dist/features/homepage/components/WelcomeSection.d.ts +16 -3
  34. package/dist/features/homepage/components/WelcomeSection.js +3 -3
  35. package/dist/features/homepage/lib/section-renderer.d.ts +9 -0
  36. package/dist/features/homepage/lib/section-renderer.js +24 -6
  37. package/dist/features/homepage/lib/slide-gating.d.ts +52 -0
  38. package/dist/features/homepage/lib/slide-gating.js +98 -0
  39. package/dist/features/live/components/LiveItemDetailPageView.js +2 -1
  40. package/dist/features/media/MediaAvatar.js +1 -1
  41. package/dist/features/media/MediaImage.d.ts +18 -1
  42. package/dist/features/media/MediaImage.js +1 -1
  43. package/dist/features/orders/components/EmiInstallmentsPanel.d.ts +19 -0
  44. package/dist/features/orders/components/EmiInstallmentsPanel.js +57 -0
  45. package/dist/features/orders/components/index.d.ts +1 -0
  46. package/dist/features/orders/components/index.js +1 -0
  47. package/dist/features/orders/schemas/firestore.d.ts +38 -0
  48. package/dist/features/orders/schemas/index.d.ts +2 -2
  49. package/dist/features/orders/types/index.d.ts +15 -0
  50. package/dist/features/points/repository/points.repository.d.ts +81 -0
  51. package/dist/features/points/repository/points.repository.js +155 -0
  52. package/dist/features/points/schemas/firestore.d.ts +118 -0
  53. package/dist/features/points/schemas/firestore.js +116 -0
  54. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -1
  55. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
  56. package/dist/features/products/components/ProductDetailPageView.js +3 -1
  57. package/dist/features/reviews/components/ReviewDetailPageView.js +3 -2
  58. package/dist/features/seller/actions/seller-actions.d.ts +17 -0
  59. package/dist/features/seller/actions/seller-actions.js +33 -0
  60. package/dist/features/stores/components/StoreHeader.js +3 -1
  61. package/dist/index.d.ts +1 -0
  62. package/dist/index.js +8 -0
  63. package/dist/next/routing/route-map.d.ts +4 -0
  64. package/dist/next/routing/route-map.js +2 -0
  65. package/dist/schemas/registry.d.ts +2 -2
  66. package/dist/seed/_helpers/category-models/chunk0.d.ts +2 -0
  67. package/dist/seed/_helpers/category-models/chunk0.js +2648 -0
  68. package/dist/seed/_helpers/category-models/chunk1.d.ts +2 -0
  69. package/dist/seed/_helpers/category-models/chunk1.js +2318 -0
  70. package/dist/seed/_helpers/category-models/chunk2.d.ts +2 -0
  71. package/dist/seed/_helpers/category-models/chunk2.js +2560 -0
  72. package/dist/seed/_helpers/category-models/chunk3.d.ts +2 -0
  73. package/dist/seed/_helpers/category-models/chunk3.js +2196 -0
  74. package/dist/seed/_helpers/category-models/chunk4.d.ts +2 -0
  75. package/dist/seed/_helpers/category-models/chunk4.js +1732 -0
  76. package/dist/seed/_helpers/category-models.d.ts +9 -2
  77. package/dist/seed/_helpers/category-models.js +19 -1368
  78. package/dist/seed/carousel-slides-seed-data.js +48 -7
  79. package/dist/server.d.ts +3 -1
  80. package/dist/server.js +11 -0
  81. package/dist/styles.css +38 -6
  82. package/dist/tailwind-utilities.css +1 -1
  83. package/dist/ui/components/ImageMosaic.d.ts +17 -1
  84. package/dist/ui/components/ImageMosaic.js +28 -5
  85. package/dist/ui/components/ImageMosaic.style.css +37 -5
  86. package/package.json +1 -1
@@ -10,6 +10,7 @@
10
10
  */
11
11
  import { serverLogger } from "../../../monitoring/index.js";
12
12
  import { normalizeError } from "../../../errors/normalize.js";
13
+ import { reconcileOrderShipping } from "../../../_internal/server/features/shipping/reconcile.js";
13
14
  import { enqueueJob } from "../../jobs/actions/enqueue-job.js";
14
15
  import { isAdminUser, isStrictSellerUser, isTesterUser } from "../../auth/role-predicates.js";
15
16
  import { ApiError, AuthorizationError, NotFoundError, ValidationError, } from "../../../errors/index.js";
@@ -712,6 +713,38 @@ export async function customShipOrder(userId, userRole, orderId, input) {
712
713
  shippingDate: new Date(),
713
714
  payoutStatus: "eligible",
714
715
  });
716
+ /*
717
+ * 🛑 AFTER the order is marked shipped, and never allowed to fail the
718
+ * dispatch.
719
+ *
720
+ * The parcel has physically gone. If reconciliation throws — the points
721
+ * ledger is unreachable, the order read fails — the correct outcome is a
722
+ * shipped order that has not been reconciled yet, which is recoverable by
723
+ * re-running it. Letting it propagate would leave the seller unable to mark
724
+ * a parcel shipped because of an accounting step they have no control over,
725
+ * and they would retry the dispatch, which is the one thing that must not
726
+ * happen twice.
727
+ *
728
+ * `reconcileOrderShipping` is itself idempotent on
729
+ * `order.shippingReconciliation`, so a retry is safe.
730
+ */
731
+ if (typeof input.actualShippingCost === "number") {
732
+ try {
733
+ const outcome = await reconcileOrderShipping(orderId, {
734
+ courierId: input.actualCourierName ?? input.shippingCarrier,
735
+ courierName: input.actualCourierName ?? input.shippingCarrier,
736
+ actualRate: input.actualShippingCost,
737
+ });
738
+ serverLogger.info("shipping reconciled", { orderId, ...outcome });
739
+ }
740
+ catch (err) {
741
+ const normalized = normalizeError(err);
742
+ serverLogger.error("shipping reconciliation failed after dispatch", {
743
+ orderId,
744
+ message: normalized.message,
745
+ });
746
+ }
747
+ }
715
748
  serverLogger.info("customShipOrder", {
716
749
  orderId,
717
750
  userId,
@@ -4,6 +4,8 @@ import { MediaImage } from "../../media/MediaImage.js";
4
4
  import { normalizeRichTextHtml } from "../../../utils/string.formatter.js";
5
5
  import { ShareButton } from "../../products/components/ShareButton.js";
6
6
  import { SellerTrustBadge } from "../../scams/components/SellerTrustBadge.js";
7
+ import { OwnerQuickActions } from "../../admin/components/OwnerQuickActions.js";
8
+ import { ROUTES } from "../../../next/routing/route-map.js";
7
9
  const __O = {
8
10
  hidden: "overflow-hidden",
9
11
  };
@@ -12,7 +14,7 @@ const CLS_STARS = "inline-flex items-center gap-[var(--appkit-space-1)] text-war
12
14
  const CLS_FOLLOW_BTN = "rounded-lg border border-warning px-[var(--appkit-space-4)] py-[var(--appkit-space-2)] text-[length:var(--appkit-text-sm)] font-medium text-warning hover:bg-warning-surface transition-colors";
13
15
  const CLS_WARN_BANNER = "mt-3 rounded-lg bg-warning-surface dark:bg-warning-surface border border-warning dark:border-warning px-[var(--appkit-space-3)] py-[var(--appkit-space-2)] text-[length:var(--appkit-text-sm)] text-warning dark:text-warning";
14
16
  export function StoreHeader({ store, labels = {}, onFollow, className = "", trust, }) {
15
- return (_jsxs(Section, { surface: "default", border: "bottom", className: className, children: [store.storeBannerURL && (_jsx(Div, { className: `relative h-40 md:h-56 ${__O.hidden} bg-[var(--appkit-color-surface)] bg-[var(--appkit-color-surface-elevated)]`, children: _jsx(MediaImage, { src: store.storeBannerURL, alt: `${store.storeName} banner`, size: "banner" }) })), _jsxs(Div, { paddingX: "x-page", className: "max-w-7xl mx-auto", padding: "y-md", children: [_jsxs(Row, { align: "end", gap: "md", children: [store.storeLogoURL ? (_jsx(Div, { className: "relative -mt-8 h-16 w-16 border-2 border-white", rounded: "xl", shadow: "sm", overflow: "hidden", children: _jsx(MediaImage, { src: store.storeLogoURL, alt: store.storeName, size: "avatar" }) })) : (_jsx(Div, { className: CLS_AVATAR, children: store.storeName[0]?.toUpperCase() })), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsxs(Row, { className: "mb-0.5", align: "center", gap: "sm", wrap: true, children: [_jsx(Heading, { level: 1, className: "text-[var(--appkit-color-text)]", size: "xl", weight: "bold", children: store.storeName }), store.averageRating != null && store.averageRating > 0 && (_jsxs(Span, { size: "sm", weight: "medium", className: CLS_STARS, children: ["\u2605 ", store.averageRating.toFixed(1)] })), trust && _jsx(SellerTrustBadge, { trust: trust })] }), _jsxs(Row, { textSize: "xs", className: "text-[var(--appkit-color-text-muted)] mb-0.5", gap: "3", children: [store.category && _jsx(Span, { transform: "capitalize", children: store.category }), store.totalProducts != null && store.totalProducts > 0 && (_jsxs(Span, { children: [store.totalProducts, " ", labels.products ?? "products"] })), store.totalReviews != null && store.totalReviews > 0 && (_jsxs(Span, { children: [store.totalReviews, " ", labels.reviews ?? "reviews"] })), store.itemsSold != null && store.itemsSold > 0 && (_jsxs(Span, { children: [store.itemsSold, " ", labels.sold ?? "sold"] }))] }), store.storeDescription && (_jsx(RichText, { html: normalizeRichTextHtml(store.storeDescription), copyableCode: true, className: "mt-0.5" }))] }), _jsxs(Row, { gap: "sm", align: "center", className: "shrink-0", children: [_jsx(ShareButton, { title: store.storeName }), onFollow && (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onFollow(store.storeSlug), className: CLS_FOLLOW_BTN, children: labels.follow ?? "Follow" }))] })] }), store.isVacationMode && (_jsx(Text, { className: CLS_WARN_BANNER, children: store.vacationMessage ??
17
+ return (_jsxs(Section, { surface: "default", border: "bottom", className: className, children: [store.storeBannerURL && (_jsx(Div, { className: `relative h-40 md:h-56 ${__O.hidden} bg-[var(--appkit-color-surface)] bg-[var(--appkit-color-surface-elevated)]`, children: _jsx(MediaImage, { src: store.storeBannerURL, alt: `${store.storeName} banner`, size: "banner" }) })), _jsxs(Div, { paddingX: "x-page", className: "max-w-7xl mx-auto", padding: "y-md", children: [_jsxs(Row, { align: "end", gap: "md", children: [store.storeLogoURL ? (_jsx(Div, { className: "relative -mt-8 h-16 w-16 border-2 border-white", rounded: "xl", shadow: "sm", overflow: "hidden", children: _jsx(MediaImage, { src: store.storeLogoURL, alt: store.storeName, size: "avatar" }) })) : (_jsx(Div, { className: CLS_AVATAR, children: store.storeName[0]?.toUpperCase() })), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsxs(Row, { className: "mb-0.5", align: "center", gap: "sm", wrap: true, children: [_jsx(Heading, { level: 1, className: "text-[var(--appkit-color-text)]", size: "xl", weight: "bold", children: store.storeName }), store.averageRating != null && store.averageRating > 0 && (_jsxs(Span, { size: "sm", weight: "medium", className: CLS_STARS, children: ["\u2605 ", store.averageRating.toFixed(1)] })), trust && _jsx(SellerTrustBadge, { trust: trust }), _jsx(OwnerQuickActions, { resource: "STORE", placement: "detail", editHref: String(ROUTES.ADMIN.STORE_DETAIL(store.storeSlug)), recordLabel: store.storeName })] }), _jsxs(Row, { textSize: "xs", className: "text-[var(--appkit-color-text-muted)] mb-0.5", gap: "3", children: [store.category && _jsx(Span, { transform: "capitalize", children: store.category }), store.totalProducts != null && store.totalProducts > 0 && (_jsxs(Span, { children: [store.totalProducts, " ", labels.products ?? "products"] })), store.totalReviews != null && store.totalReviews > 0 && (_jsxs(Span, { children: [store.totalReviews, " ", labels.reviews ?? "reviews"] })), store.itemsSold != null && store.itemsSold > 0 && (_jsxs(Span, { children: [store.itemsSold, " ", labels.sold ?? "sold"] }))] }), store.storeDescription && (_jsx(RichText, { html: normalizeRichTextHtml(store.storeDescription), copyableCode: true, className: "mt-0.5" }))] }), _jsxs(Row, { gap: "sm", align: "center", className: "shrink-0", children: [_jsx(ShareButton, { title: store.storeName }), onFollow && (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onFollow(store.storeSlug), className: CLS_FOLLOW_BTN, children: labels.follow ?? "Follow" }))] })] }), store.isVacationMode && (_jsx(Text, { className: CLS_WARN_BANNER, children: store.vacationMessage ??
16
18
  labels.vacationMode ??
17
19
  "Store is on vacation mode" }))] })] }));
18
20
  }
package/dist/index.d.ts CHANGED
@@ -3123,6 +3123,7 @@ export { withRetry } from "./http/retry";
3123
3123
  export { normalizeError, getErrorMessage, isApiNormalized, isAppNormalized, isFirebaseAuthNormalized, isFirebaseFirestoreNormalized, isFirebaseStorageNormalized, isNativeNormalized, isNetworkNormalized, isUnknownNormalized, isZodNormalized, } from "./errors/normalize";
3124
3124
  export type { NormalizedError, NormalizedApiError, NormalizedAppError, NormalizedFirebaseAuthError, NormalizedFirebaseFirestoreError, NormalizedFirebaseStorageError, NormalizedNativeError, NormalizedNetworkError, NormalizedUnknownThrownValue, NormalizedZodError, } from "./errors/normalize";
3125
3125
  export { CART_LANE, CART_LANE_PRIORITY, CART_LANE_LABELS, laneOf, activeLane, laneItems, laneCounts, isLaneCheckoutable, laneBlockReason, isLockedLane, canAddNewItems, type CartLane, type LaneAssignable, } from "./_internal/shared/checkout/lanes";
3126
+ export { roundShippingUp, toQuoteOptions, reconcileShipping, SHIPPING_ROUND_UP_TO, type ShippingQuoteOption, type SelectedShippingQuote, type ActualShipmentCost, type ShippingReconciliation, } from "./_internal/shared/shipping/quote";
3126
3127
  export { newsletterSubscribeSchema, quickCreateTaxonomySchema, payoutMarkPaidSchema, } from "./features/admin/schemas/small-forms";
3127
3128
  export { raffleEntrySchema } from "./features/contact/schemas/inquiry-forms";
3128
3129
  export { orderCancelSchema, paymentProofSchema, } from "./features/orders/schemas/buyer-forms";
package/dist/index.js CHANGED
@@ -5559,6 +5559,14 @@ export { normalizeError, getErrorMessage, isApiNormalized, isAppNormalized, isFi
5559
5559
  // Checkout lanes — the derived auction > offer > standard partition of the
5560
5560
  // cart, and the priority rule that decides which one may be checked out.
5561
5561
  export { CART_LANE, CART_LANE_PRIORITY, CART_LANE_LABELS, laneOf, activeLane, laneItems, laneCounts, isLaneCheckoutable, laneBlockReason, isLockedLane, canAddNewItems, } from "./_internal/shared/checkout/lanes.js";
5562
+ /*
5563
+ * Shipping quote model. Public because the CONSUMER owns the route that asks
5564
+ * the carrier for rates (`/api/shipping/quote`) and the checkout UI that
5565
+ * renders them — the rounding rule has to be reachable from both, and it must
5566
+ * be the same rule the server-side reconciliation uses, or the buyer is
5567
+ * credited against a figure they were never charged.
5568
+ */
5569
+ export { roundShippingUp, toQuoteOptions, reconcileShipping, SHIPPING_ROUND_UP_TO, } from "./_internal/shared/shipping/quote.js";
5562
5570
  export { newsletterSubscribeSchema, quickCreateTaxonomySchema, payoutMarkPaidSchema, } from "./features/admin/schemas/small-forms.js";
5563
5571
  export { raffleEntrySchema } from "./features/contact/schemas/inquiry-forms.js";
5564
5572
  export { orderCancelSchema, paymentProofSchema, } from "./features/orders/schemas/buyer-forms.js";
@@ -177,6 +177,8 @@ export declare const DEFAULT_ROUTE_MAP: {
177
177
  readonly NOTIFICATIONS: "/user/notifications";
178
178
  /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
179
179
  readonly CLAIMED_COUPONS: "/user/coupons";
180
+ /** Points balance + ledger. 1 point = ₹1, spendable at checkout. */
181
+ readonly POINTS: "/user/points";
180
182
  readonly BECOME_SELLER: "/user/become-seller";
181
183
  readonly CART: "/cart";
182
184
  readonly CHECKOUT: "/checkout";
@@ -610,6 +612,8 @@ export declare const ROUTES: {
610
612
  readonly NOTIFICATIONS: "/user/notifications";
611
613
  /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
612
614
  readonly CLAIMED_COUPONS: "/user/coupons";
615
+ /** Points balance + ledger. 1 point = ₹1, spendable at checkout. */
616
+ readonly POINTS: "/user/points";
613
617
  readonly BECOME_SELLER: "/user/become-seller";
614
618
  readonly CART: "/cart";
615
619
  readonly CHECKOUT: "/checkout";
@@ -278,6 +278,8 @@ export const DEFAULT_ROUTE_MAP = {
278
278
  NOTIFICATIONS: "/user/notifications",
279
279
  /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
280
280
  CLAIMED_COUPONS: "/user/coupons",
281
+ /** Points balance + ledger. 1 point = ₹1, spendable at checkout. */
282
+ POINTS: "/user/points",
281
283
  BECOME_SELLER: "/user/become-seller",
282
284
  CART: "/cart",
283
285
  CHECKOUT: "/checkout",
@@ -3036,6 +3036,7 @@ export declare const SCHEMAS: {
3036
3036
  } | undefined;
3037
3037
  offerId?: string | undefined;
3038
3038
  orderType?: string | undefined;
3039
+ isNonRefundable?: boolean | undefined;
3039
3040
  imageUrls?: string[] | undefined;
3040
3041
  refundFeeDeducted?: number | undefined;
3041
3042
  refundNetAmount?: number | undefined;
@@ -3072,7 +3073,6 @@ export declare const SCHEMAS: {
3072
3073
  }[] | undefined;
3073
3074
  emiRemainingBalance?: number | undefined;
3074
3075
  emiComplete?: boolean | undefined;
3075
- isNonRefundable?: boolean | undefined;
3076
3076
  paymentBatchId?: string | undefined;
3077
3077
  refunds?: {
3078
3078
  type: "full" | "partial";
@@ -3184,6 +3184,7 @@ export declare const SCHEMAS: {
3184
3184
  } | undefined;
3185
3185
  offerId?: string | undefined;
3186
3186
  orderType?: string | undefined;
3187
+ isNonRefundable?: boolean | undefined;
3187
3188
  imageUrls?: string[] | undefined;
3188
3189
  refundFeeDeducted?: number | undefined;
3189
3190
  refundNetAmount?: number | undefined;
@@ -3220,7 +3221,6 @@ export declare const SCHEMAS: {
3220
3221
  }[] | undefined;
3221
3222
  emiRemainingBalance?: number | undefined;
3222
3223
  emiComplete?: boolean | undefined;
3223
- isNonRefundable?: boolean | undefined;
3224
3224
  paymentBatchId?: string | undefined;
3225
3225
  refunds?: {
3226
3226
  type: "full" | "partial";
@@ -0,0 +1,2 @@
1
+ import type { CategoryTreeNode } from "../category-tree";
2
+ export declare const modelChunk0: Record<string, CategoryTreeNode[]>;