@mohasinac/appkit 4.71.2 → 4.72.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 (43) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/constants/api-endpoints.d.ts +3 -0
  3. package/dist/constants/api-endpoints.js +6 -0
  4. package/dist/features/classified/components/ClassifiedDetailPageView.js +2 -2
  5. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +2 -2
  6. package/dist/features/events/components/EntryVoteButtons.d.ts +19 -0
  7. package/dist/features/events/components/EntryVoteButtons.js +65 -0
  8. package/dist/features/events/repository/entry-votes.repository.d.ts +45 -0
  9. package/dist/features/events/repository/entry-votes.repository.js +154 -0
  10. package/dist/features/events/schemas/entry-votes.d.ts +134 -0
  11. package/dist/features/events/schemas/entry-votes.js +114 -0
  12. package/dist/features/events/schemas/index.d.ts +29 -7
  13. package/dist/features/events/schemas/index.js +29 -2
  14. package/dist/features/inventory/components/AdminMoveLedgerView.d.ts +1 -1
  15. package/dist/features/live/components/LiveItemDetailPageView.js +2 -2
  16. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +3 -3
  17. package/dist/features/products/components/ClearanceDetailPageView.js +2 -2
  18. package/dist/features/products/components/index.d.ts +0 -2
  19. package/dist/features/products/components/index.js +0 -1
  20. package/dist/features/products/schemas/index.d.ts +6 -7
  21. package/dist/features/products/schemas/index.js +20 -2
  22. package/dist/features/promotions/schemas/firestore.d.ts +17 -1
  23. package/dist/features/promotions/schemas/firestore.js +22 -0
  24. package/dist/features/promotions/schemas/index.d.ts +45 -21
  25. package/dist/features/promotions/schemas/index.js +37 -8
  26. package/dist/features/promotions/types/index.d.ts +1 -1
  27. package/dist/features/reviews/schemas/index.d.ts +3 -0
  28. package/dist/features/reviews/schemas/index.js +25 -0
  29. package/dist/index.d.ts +0 -2
  30. package/dist/index.js +0 -3
  31. package/dist/next/routing/portals.d.ts +22 -0
  32. package/dist/next/routing/portals.js +43 -0
  33. package/dist/providers/db-firebase/admin.d.ts +2 -0
  34. package/dist/providers/db-firebase/admin.js +25 -2
  35. package/dist/schemas/registry.d.ts +11 -8
  36. package/dist/styles.css +1 -1
  37. package/dist/tailwind-utilities.css +1 -1
  38. package/dist/ui/components/ListingDetailShell.d.ts +68 -0
  39. package/dist/ui/components/ListingDetailShell.js +32 -0
  40. package/package.json +533 -525
  41. package/scripts/seed-cli.mjs +32 -2
  42. package/dist/features/products/components/PreOrderDetailView.d.ts +0 -18
  43. package/dist/features/products/components/PreOrderDetailView.js +0 -12
@@ -0,0 +1,68 @@
1
+ import React from "react";
2
+ import type { DetailViewShellProps } from "./DetailViewShell";
3
+ /**
4
+ * The one shell every listing detail page uses.
5
+ *
6
+ * Replaces `ProductDetailView`, `CollectorDropDetailView` and
7
+ * `PreOrderDetailView` — three files, 202 lines, ~22 render-prop slots each.
8
+ *
9
+ * ## 🛑 They were NOT duplicates, and the distinction matters
10
+ *
11
+ * A 2026-11-08 note called those three "near-identical duplicates, nobody knows
12
+ * why there are two" of their `*DetailPageView` counterparts. That was wrong:
13
+ * each was a SHELL and its counterpart was the PAGE that filled its slots. The
14
+ * error came from comparing filenames instead of reading files, and it nearly
15
+ * caused the shells to be deleted as redundant.
16
+ *
17
+ * What they actually were is three parameterisations of ONE layout:
18
+ *
19
+ * | | Product | CollectorDrop | PreOrder |
20
+ * |---|---|---|---|
21
+ * | layout | `grid-3` | `grid-3` | `grid-2` |
22
+ * | third slot | `renderActions`, sticky | `renderBidForm`, desktop-only | — |
23
+ * | afterMain | sublisting + group | mobile bid + sublisting | sublisting |
24
+ * | belowFold | tabs + bundle + related | tabs + bidHistory + related | tabs + related |
25
+ *
26
+ * Every difference above is a VALUE. So they are one component with props,
27
+ * which is the same argument the listing-type collapse makes one level up.
28
+ *
29
+ * ## Why slots are arrays rather than named props
30
+ *
31
+ * `renderBundleSection`, `renderBidHistory` and `renderGroupSection` were three
32
+ * names for "another thing below the tabs". Naming each one forced a new prop —
33
+ * and a new shell — every time a listing type wanted a different section. An
34
+ * ordered array takes any number of sections and needs no new prop, so adding a
35
+ * section to a type is a config change rather than an edit here.
36
+ *
37
+ * Falsy entries are dropped, so a caller can pass a conditional straight in
38
+ * without assembling the array itself.
39
+ */
40
+ export interface ListingDetailShellProps extends Omit<DetailViewShellProps, "mainSlots" | "belowFold" | "layout" | "afterMain"> {
41
+ /** `grid-3` gives gallery | info | aside. `grid-2` drops the aside column. */
42
+ layout?: "grid-2" | "grid-3";
43
+ renderGallery?: (isLoading: boolean) => React.ReactNode;
44
+ renderInfo?: (isLoading: boolean) => React.ReactNode;
45
+ /**
46
+ * The third column — a buy bar, an action rail, a bid form. Ignored when
47
+ * `layout` is `grid-2`.
48
+ */
49
+ renderAside?: () => React.ReactNode;
50
+ /**
51
+ * Hide the aside below `lg`. Used where the same control is rendered again
52
+ * in `afterMain` for mobile (the collector-drop bid form does this), so the
53
+ * two would otherwise both show on a phone.
54
+ */
55
+ asideDesktopOnly?: boolean;
56
+ /** Sections between the main grid and the below-fold stack, in order. */
57
+ afterMain?: Array<React.ReactNode | false | null | undefined>;
58
+ /** Sections below the fold, in order — tabs, history, related, anything. */
59
+ belowFold?: Array<React.ReactNode | false | null | undefined>;
60
+ renderSublistingSection?: () => React.ReactNode;
61
+ renderGroupSection?: () => React.ReactNode;
62
+ renderTabs?: () => React.ReactNode;
63
+ renderRelated?: () => React.ReactNode;
64
+ /** Sticky aside on desktop. Only meaningful with `grid-3`. */
65
+ stickyActionRail?: boolean;
66
+ stickyRailOffset?: string;
67
+ }
68
+ export declare function ListingDetailShell({ layout, renderGallery, renderInfo, renderAside, asideDesktopOnly, afterMain, belowFold, renderSublistingSection, renderGroupSection, renderTabs, renderRelated, isLoading, stickyActionRail, stickyRailOffset, ...rest }: ListingDetailShellProps): React.JSX.Element;
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { DetailViewShell } from "./DetailViewShell.js";
4
+ import { Div } from "./Div.js";
5
+ /** Drop falsy slots so callers can pass conditionals directly. */
6
+ function present(nodes = []) {
7
+ return nodes.filter(Boolean);
8
+ }
9
+ export function ListingDetailShell({ layout = "grid-3", renderGallery, renderInfo, renderAside, asideDesktopOnly = false, afterMain, belowFold, renderSublistingSection, renderGroupSection, renderTabs, renderRelated, isLoading = false, stickyActionRail = true, stickyRailOffset = "top-[var(--header-height,0px)]", ...rest }) {
10
+ const asideNode = layout === "grid-3" ? renderAside?.() : undefined;
11
+ const mainSlots = [
12
+ renderGallery?.(isLoading),
13
+ renderInfo?.(isLoading),
14
+ ];
15
+ if (layout === "grid-3") {
16
+ mainSlots.push(asideDesktopOnly ? (_jsx(Div, { className: "hidden lg:block", children: asideNode }, "aside")) : (asideNode));
17
+ }
18
+ const after = present([
19
+ renderSublistingSection?.(),
20
+ renderGroupSection?.(),
21
+ ...(afterMain ?? []),
22
+ ]);
23
+ const below = present([renderTabs?.(), ...(belowFold ?? []), renderRelated?.()]);
24
+ return (_jsx(DetailViewShell, { portal: "public", ...rest, layout: layout, isLoading: isLoading, stickyActionRail: layout === "grid-3" ? stickyActionRail : false, stickyRailOffset: stickyRailOffset, mainSlots: mainSlots,
25
+ /*
26
+ * `undefined`, not an empty fragment, when there is nothing — the shell
27
+ * renders a wrapper for a truthy `afterMain`, and an empty fragment
28
+ * would leave an empty bordered band on every page that has no
29
+ * sublisting or group section.
30
+ */
31
+ afterMain: after.length ? _jsx(React.Fragment, { children: after }) : undefined, belowFold: below }));
32
+ }