@tokenoftrust/storefront-runner 2.4.83 → 2.4.85
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/apps/storefront/public/shared/commerce-marketing.css +3 -3
- package/apps/storefront/src/components/CollectionCard.astro +1 -1
- package/apps/storefront/src/components/ProductCard.astro +1 -1
- package/apps/storefront/src/components/{Img.astro → assets/storefront/Img.astro} +2 -2
- package/apps/storefront/src/components/commerce/ArticleCard.astro +1 -1
- package/apps/storefront/src/components/commerce/BrandGrid.astro +1 -1
- package/apps/storefront/src/components/{islands → customers/storefront/islands}/SavedList.tsx +1 -1
- package/apps/storefront/src/components/home/Hero.astro +1 -1
- package/apps/storefront/src/components/islands/ImageGallery.tsx +1 -1
- package/apps/storefront/src/components/membership/{TierCards.astro → storefront/membership/TierCards.astro} +1 -1
- package/apps/storefront/src/components/membership/{TierComparisonTable.astro → storefront/membership/TierComparisonTable.astro} +1 -1
- package/apps/storefront/src/components/subscription/SavingsExplainer.astro +1 -1
- package/apps/storefront/src/layouts/Layout.astro +1 -1
- package/apps/storefront/src/lib/{admin/services/mock → activity/fixtures}/evidence.ts +6 -6
- package/apps/storefront/src/lib/admin/README.md +3 -3
- package/apps/storefront/src/lib/admin/adminShell.ts +27 -39
- package/apps/storefront/src/lib/admin/ai/askEnvelope.ts +2 -3
- package/apps/storefront/src/lib/admin/services/mock/index.ts +3 -3
- package/apps/storefront/src/lib/admin/services/mock/subscriptions.ts +2 -2
- package/apps/storefront/src/lib/{imageAttrs.ts → assets/shared/imageAttrs.ts} +1 -1
- package/apps/storefront/src/lib/{admin/services/mock → customers/fixtures}/customers.ts +4 -4
- package/apps/storefront/src/lib/{admin/services/mock → reporting/fixtures}/reporting.ts +4 -4
- package/apps/storefront/src/pages/collections/[handle].astro +1 -1
- package/apps/storefront/src/pages/index.astro +2 -2
- package/apps/storefront/src/pages/saved.astro +1 -1
- package/apps/storefront/src/pages/style-guide/[tenant]/[theme].astro +3 -3
- package/docs/widget-library-guide.md +6 -6
- package/package.json +1 -1
- /package/apps/storefront/src/components/membership/{IllustrativeLabel.astro → storefront/membership/IllustrativeLabel.astro} +0 -0
- /package/apps/storefront/src/lib/{admin → activity}/evidence/evidenceReference.ts +0 -0
- /package/apps/storefront/src/lib/{admin → customers/admin}/viewmodels/customers.ts +0 -0
- /package/apps/storefront/src/lib/{wishlist.ts → customers/shared/wishlist.ts} +0 -0
- /package/apps/storefront/src/lib/{admin → fulfillment/admin}/viewmodels/fulfillment.ts +0 -0
- /package/apps/storefront/src/lib/{admin → reporting/admin}/viewmodels/reporting.ts +0 -0
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
.contact-form .attest input { width: auto; margin-top: 3px; }
|
|
142
142
|
.contact-form .btn { align-self: flex-start; }
|
|
143
143
|
|
|
144
|
-
/* --- Membership tier cards (mirrors components/membership/TierCards.astro) --
|
|
144
|
+
/* --- Membership tier cards (mirrors components/membership/storefront/membership/TierCards.astro) --
|
|
145
145
|
Illustrative figures carry an "e.g." affordance + data-illustrative hooks in the
|
|
146
146
|
markup; this sheet is presentational only. */
|
|
147
147
|
.tier-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(14px, 2vw, 24px); align-items: stretch; }
|
|
@@ -162,12 +162,12 @@
|
|
|
162
162
|
.tier-feats li.is-no .glyph { color: var(--color-muted); }
|
|
163
163
|
.tier-cta { margin-top: 24px; width: 100%; }
|
|
164
164
|
|
|
165
|
-
/* --- Illustrative label (mirrors components/membership/IllustrativeLabel.astro) */
|
|
165
|
+
/* --- Illustrative label (mirrors components/membership/storefront/membership/IllustrativeLabel.astro) */
|
|
166
166
|
.illus-badge-wrap { margin-top: 14px; }
|
|
167
167
|
.illus-badge { display: inline-flex; align-items: center; gap: 5px; border: 1px solid var(--color-info); color: var(--color-info); border-radius: var(--radius-full); padding: 2px 9px; font-size: .65rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
|
|
168
168
|
.illus-note { margin-top: 16px; text-align: center; font-size: .75rem; font-style: italic; color: var(--color-muted); }
|
|
169
169
|
|
|
170
|
-
/* --- Tier comparison table (mirrors components/membership/TierComparisonTable.astro) */
|
|
170
|
+
/* --- Tier comparison table (mirrors components/membership/storefront/membership/TierComparisonTable.astro) */
|
|
171
171
|
.cmp-wrap { overflow-x: auto; border: 1px solid var(--color-border); border-radius: var(--radius-lg); }
|
|
172
172
|
table.cmp { width: 100%; border-collapse: collapse; min-width: 640px; background: var(--color-surface); }
|
|
173
173
|
table.cmp th, table.cmp td { padding: 13px 16px; border-bottom: 1px solid var(--color-border); font-size: .9rem; vertical-align: middle; }
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* utilities only).
|
|
6
6
|
*/
|
|
7
7
|
import type { CatalogCollection } from "@tot/public-runtime";
|
|
8
|
-
import Img from "@/components/Img.astro";
|
|
8
|
+
import Img from "@/components/assets/storefront/Img.astro";
|
|
9
9
|
import { withBase } from "@/lib/basePath";
|
|
10
10
|
import { pageUrlForm } from "@/lib/seo/urlForm";
|
|
11
11
|
|
|
@@ -10,7 +10,7 @@ import type { CatalogProduct } from "@tot/public-runtime";
|
|
|
10
10
|
import { discountPercent, truncate } from "@/lib/format";
|
|
11
11
|
import { isOnSale, isNew, isAvailable, fromPrice } from "@/lib/tot/query";
|
|
12
12
|
import { colorOptionValues, resolveSwatch, isLightFill } from "@/lib/colors";
|
|
13
|
-
import Img from "@/components/Img.astro";
|
|
13
|
+
import Img from "@/components/assets/storefront/Img.astro";
|
|
14
14
|
import Badge from "@/components/Badge.astro";
|
|
15
15
|
import PriceDisplay from "@/components/commerce/PriceDisplay.astro";
|
|
16
16
|
import RatingStars from "@/components/commerce/RatingStars.astro";
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* the storefront is served by Cloudflare or CloudFront, so this component never
|
|
15
15
|
* routes them through a provider-specific transformation path.
|
|
16
16
|
*/
|
|
17
|
-
import { resolveImage } from "@/lib/imageAttrs";
|
|
17
|
+
import { resolveImage } from "@/lib/assets/shared/imageAttrs";
|
|
18
18
|
|
|
19
19
|
interface Props {
|
|
20
20
|
src?: string;
|
|
@@ -48,7 +48,7 @@ const {
|
|
|
48
48
|
} = Astro.props;
|
|
49
49
|
|
|
50
50
|
// Render decision (placeholder / direct rehost / Shopify ?width=) lives in
|
|
51
|
-
// lib/imageAttrs.ts so it's unit-testable without rendering this component.
|
|
51
|
+
// lib/assets/shared/imageAttrs.ts so it's unit-testable without rendering this component.
|
|
52
52
|
const { src: resolvedSrc, srcset } = resolveImage({ src, rehosted, width, height, seed, label });
|
|
53
53
|
|
|
54
54
|
const loadingAttr = loading ?? (priority ? "eager" : "lazy");
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* imported/source-copied blog data) and NEVER fabricates authors, dates, or
|
|
17
17
|
* excerpts — omit a field and its row simply doesn't render.
|
|
18
18
|
*/
|
|
19
|
-
import Img from "@/components/Img.astro";
|
|
19
|
+
import Img from "@/components/assets/storefront/Img.astro";
|
|
20
20
|
import { withBase } from "@/lib/basePath";
|
|
21
21
|
|
|
22
22
|
export interface ArticleImage {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* through the rawMarketingHtml splice pipeline. Keep the two visually equivalent.
|
|
15
15
|
*/
|
|
16
16
|
import Section from "@/components/Section.astro";
|
|
17
|
-
import Img from "@/components/Img.astro";
|
|
17
|
+
import Img from "@/components/assets/storefront/Img.astro";
|
|
18
18
|
import { withBase } from "@/lib/basePath";
|
|
19
19
|
|
|
20
20
|
export interface Brand {
|
package/apps/storefront/src/components/{islands → customers/storefront/islands}/SavedList.tsx
RENAMED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
toggleSaved,
|
|
11
11
|
WISHLIST_EVENT,
|
|
12
12
|
type SavedItem,
|
|
13
|
-
} from "@/lib/wishlist";
|
|
13
|
+
} from "@/lib/customers/shared/wishlist";
|
|
14
14
|
import { formatPrice } from "@/lib/format";
|
|
15
15
|
import { placeholderDataUri, isUsableImageUrl } from "@/lib/placeholder";
|
|
16
16
|
import { withClientBase } from "@/lib/basePath";
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import type { HeroBlock } from "@/lib/storyblok/content-model";
|
|
23
23
|
import type { CatalogProduct } from "@tot/public-runtime";
|
|
24
|
-
import Img from "@/components/Img.astro";
|
|
24
|
+
import Img from "@/components/assets/storefront/Img.astro";
|
|
25
25
|
import { withBase } from "@/lib/basePath";
|
|
26
26
|
import { pageUrlForm } from "@/lib/seo/urlForm";
|
|
27
27
|
import { heroSlideshowView } from "@/lib/heroSlideshow";
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import { useCallback, useEffect, useMemo, useRef, useState } from "preact/hooks";
|
|
17
17
|
import type { CatalogImage } from "@tot/public-runtime";
|
|
18
18
|
import { placeholderDataUri, isUsableImageUrl } from "@/lib/placeholder";
|
|
19
|
-
import { resolveImage } from "@/lib/imageAttrs";
|
|
19
|
+
import { resolveImage } from "@/lib/assets/shared/imageAttrs";
|
|
20
20
|
|
|
21
21
|
interface Props {
|
|
22
22
|
images: CatalogImage[];
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import type { Tier } from "@/lib/membership/model";
|
|
22
22
|
import { isIllustrative } from "@/lib/membership/model";
|
|
23
|
-
import IllustrativeLabel from "@/components/membership/IllustrativeLabel.astro";
|
|
23
|
+
import IllustrativeLabel from "@/components/membership/storefront/membership/IllustrativeLabel.astro";
|
|
24
24
|
|
|
25
25
|
interface Props {
|
|
26
26
|
tiers: Tier[];
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import type { Tier, ComparisonRow } from "@/lib/membership/model";
|
|
21
21
|
import { isIllustrative } from "@/lib/membership/model";
|
|
22
|
-
import IllustrativeLabel from "@/components/membership/IllustrativeLabel.astro";
|
|
22
|
+
import IllustrativeLabel from "@/components/membership/storefront/membership/IllustrativeLabel.astro";
|
|
23
23
|
|
|
24
24
|
interface Props {
|
|
25
25
|
tiers: Tier[];
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import type { SubscriptionFigure } from "@/lib/subscription/model";
|
|
20
20
|
import { isIllustrative } from "@/lib/subscription/model";
|
|
21
|
-
import IllustrativeLabel from "@/components/membership/IllustrativeLabel.astro";
|
|
21
|
+
import IllustrativeLabel from "@/components/membership/storefront/membership/IllustrativeLabel.astro";
|
|
22
22
|
|
|
23
23
|
interface Props {
|
|
24
24
|
figure: SubscriptionFigure;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { AdminTenantEnvelope } from "../../envelope";
|
|
2
|
-
import { memoizeByEnvelope } from "../../memoizeByEnvelope";
|
|
3
|
-
import type { EvidenceReference } from "
|
|
4
|
-
import { getCustomersViewModel } from "
|
|
5
|
-
import { getOrdersViewModel } from "
|
|
6
|
-
import { getProductsViewModel } from "
|
|
1
|
+
import type { AdminTenantEnvelope } from "../../admin/envelope";
|
|
2
|
+
import { memoizeByEnvelope } from "../../admin/memoizeByEnvelope";
|
|
3
|
+
import type { EvidenceReference } from "../evidence/evidenceReference";
|
|
4
|
+
import { getCustomersViewModel } from "../../customers/fixtures/customers";
|
|
5
|
+
import { getOrdersViewModel } from "../../admin/services/mock/orders";
|
|
6
|
+
import { getProductsViewModel } from "../../admin/services/mock/products";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Deterministic evidence graph, built by connecting the domains already
|
|
@@ -81,8 +81,8 @@ lib/admin/
|
|
|
81
81
|
testable source of truth for what the floating Ask button emits — the full
|
|
82
82
|
tenant envelope, active tab, selected record id (if any), role +
|
|
83
83
|
permissions (derived from `isStaff`), active filters, and evidence context.
|
|
84
|
-
`
|
|
85
|
-
|
|
84
|
+
The processed `adminShell.ts` client imports this builder and emits its
|
|
85
|
+
result on Ask-button click as
|
|
86
86
|
`window.__toTAdminAsk` and a `tot:admin-ask` `CustomEvent` — **dev-inspectable
|
|
87
87
|
only, no chat backend yet.** The envelope changes whenever the active tab
|
|
88
88
|
changes (kept current by `setAskContext`) and is rebuilt fresh on click so a
|
|
@@ -117,6 +117,6 @@ const orders = getOrdersViewModel({
|
|
|
117
117
|
- **Tabs/pages → lib, never lib → tabs/pages.** Nothing under `lib/admin/**`
|
|
118
118
|
imports from `components/admin/**` or `pages/admin.astro`. Tab components
|
|
119
119
|
and `admin.astro` are free to import from here (`admin.astro` already does,
|
|
120
|
-
for `resolveAdminTenantMode` and the
|
|
120
|
+
for `resolveAdminTenantMode` and the shared shell configuration).
|
|
121
121
|
- Gaps in these contracts should go back to the workstream board as a
|
|
122
122
|
decision, not get patched from a tab's unit.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* the tablists. Imported from a processed `<script>` in admin.astro (ADR 0013):
|
|
5
5
|
* type-checked, bundled, tree-shaken, and its bundle hash is in the enforced
|
|
6
6
|
* CSP. The Ask envelope is built with the shared, unit-tested
|
|
7
|
-
* `buildAskEnvelope` (ai/askEnvelope)
|
|
7
|
+
* `buildAskEnvelope` (ai/askEnvelope).
|
|
8
8
|
*
|
|
9
9
|
* There is no chat backend yet — the Ask envelope is emitted for dev inspection
|
|
10
10
|
* only (window.__toTAdminAsk + a "tot:admin-ask" CustomEvent), never sent over
|
|
@@ -12,33 +12,23 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { buildAskEnvelope, type AskEnvelope } from "./ai/askEnvelope";
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
orders: "
|
|
31
|
-
|
|
32
|
-
subscriptions: "Subscriptions",
|
|
33
|
-
customers: "Customers",
|
|
34
|
-
fulfillment: "Fulfillment",
|
|
35
|
-
reporting: "Reporting",
|
|
36
|
-
"ai-workflows": "AI Workflows",
|
|
37
|
-
blog: "Blog",
|
|
38
|
-
publish: "Publish",
|
|
39
|
-
integrations: "Integrations",
|
|
40
|
-
settings: "Settings",
|
|
41
|
-
};
|
|
15
|
+
/** Static shell data shared by server-rendered navigation and browser startup. */
|
|
16
|
+
export const ADMIN_SHELL_CONFIG = {
|
|
17
|
+
workAreas: [
|
|
18
|
+
{ id: "orders", label: "Orders", icon: "i-file" },
|
|
19
|
+
{ id: "products", label: "Products", icon: "i-box" },
|
|
20
|
+
{ id: "subscriptions", label: "Subscriptions", icon: "i-refresh" },
|
|
21
|
+
{ id: "customers", label: "Customers", icon: "i-users" },
|
|
22
|
+
{ id: "fulfillment", label: "Fulfillment", icon: "i-truck" },
|
|
23
|
+
{ id: "reporting", label: "Reporting", icon: "i-chart" },
|
|
24
|
+
{ id: "ai-workflows", label: "AI Workflows", icon: "i-workflows" },
|
|
25
|
+
{ id: "blog", label: "Blog", icon: "i-file" },
|
|
26
|
+
{ id: "publish", label: "Publish", icon: "i-export" },
|
|
27
|
+
{ id: "integrations", label: "Integrations", icon: "i-workflows" },
|
|
28
|
+
{ id: "settings", label: "Settings", icon: "i-gear" },
|
|
29
|
+
],
|
|
30
|
+
defaultTabs: { staff: "orders", merchant: "settings" },
|
|
31
|
+
} as const;
|
|
42
32
|
|
|
43
33
|
declare global {
|
|
44
34
|
interface Window {
|
|
@@ -47,11 +37,13 @@ declare global {
|
|
|
47
37
|
}
|
|
48
38
|
|
|
49
39
|
export function initAdminShell(): void {
|
|
50
|
-
const
|
|
51
|
-
const
|
|
40
|
+
const tabIds = ADMIN_SHELL_CONFIG.workAreas.map(({ id }) => id);
|
|
41
|
+
const tabSet = new Set<string>(tabIds);
|
|
42
|
+
const tabHashPattern = new RegExp(`^#(${tabIds.join("|")})$`);
|
|
52
43
|
const canViewInternalGuide =
|
|
53
44
|
document.documentElement.dataset.internalAdminGuide === "true";
|
|
54
|
-
const defaultTab =
|
|
45
|
+
const defaultTab =
|
|
46
|
+
ADMIN_SHELL_CONFIG.defaultTabs[canViewInternalGuide ? "staff" : "merchant"];
|
|
55
47
|
|
|
56
48
|
const buildAskEnvelopeForTab = (id: string): AskEnvelope => {
|
|
57
49
|
const root = document.documentElement.dataset;
|
|
@@ -74,7 +66,9 @@ export function initAdminShell(): void {
|
|
|
74
66
|
};
|
|
75
67
|
|
|
76
68
|
const setAskContext = (id: string): void => {
|
|
77
|
-
const label =
|
|
69
|
+
const label =
|
|
70
|
+
ADMIN_SHELL_CONFIG.workAreas.find((area) => area.id === id)?.label ??
|
|
71
|
+
"Storefront";
|
|
78
72
|
const askButton = document.querySelector<HTMLElement>("[data-admin-ask]");
|
|
79
73
|
const askContext = document.querySelector<HTMLElement>(
|
|
80
74
|
"[data-admin-ask-context]",
|
|
@@ -196,7 +190,7 @@ export function initAdminShell(): void {
|
|
|
196
190
|
// normalized away to #settings for merchant viewers.
|
|
197
191
|
const hashTab = window.location.hash.slice(1).split("?")[0] ?? "";
|
|
198
192
|
if (!canViewInternalGuide && !tabSet.has(hashTab)) {
|
|
199
|
-
history.replaceState(null, "",
|
|
193
|
+
history.replaceState(null, "", `#${defaultTab}`);
|
|
200
194
|
}
|
|
201
195
|
if (scroll) requestAnimationFrame(() => scrollToHashTarget(panelId));
|
|
202
196
|
return;
|
|
@@ -229,12 +223,6 @@ export function initAdminShell(): void {
|
|
|
229
223
|
const envelope = buildAskEnvelopeForTab(activeTab);
|
|
230
224
|
window.__toTAdminAsk = envelope;
|
|
231
225
|
document.dispatchEvent(new CustomEvent("tot:admin-ask", { detail: envelope }));
|
|
232
|
-
if (
|
|
233
|
-
window.location.hostname === "localhost" ||
|
|
234
|
-
window.location.hostname === "127.0.0.1"
|
|
235
|
-
) {
|
|
236
|
-
console.debug("[admin:ask]", envelope);
|
|
237
|
-
}
|
|
238
226
|
});
|
|
239
227
|
|
|
240
228
|
document.addEventListener("click", (event) => {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The floating `Ask` button's context envelope (baseline §Horizontal AI
|
|
3
3
|
* Concepts / Ask; ai-evidence-substrate item a). PURE + no I/O so it is
|
|
4
|
-
* unit-testable and reusable from
|
|
5
|
-
* plain-object mirror, since `is:inline` scripts cannot import modules) and
|
|
4
|
+
* unit-testable and reusable from the processed adminShell.ts client and
|
|
6
5
|
* any future server-side Ask route. There is no chat backend yet — today
|
|
7
|
-
* this is emitted for dev inspection only (see
|
|
6
|
+
* this is emitted for dev inspection only (see adminShell.ts's `data-admin-ask`
|
|
8
7
|
* click handler), never sent over the network.
|
|
9
8
|
*/
|
|
10
9
|
import type { AdminTenantEnvelope } from "../envelope";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export { getOrdersViewModel } from "./orders";
|
|
2
2
|
export { getProductsViewModel } from "./products";
|
|
3
|
-
export { getCustomersViewModel } from "
|
|
4
|
-
export { getReportingViewModel } from "
|
|
3
|
+
export { getCustomersViewModel } from "../../../customers/fixtures/customers";
|
|
4
|
+
export { getReportingViewModel } from "../../../reporting/fixtures/reporting";
|
|
5
5
|
export { getSettingsViewModel } from "./settings";
|
|
6
6
|
export { getCheckoutSettingsViewModel } from "./checkoutSettings";
|
|
7
7
|
export type { CheckoutSettingsViewModel } from "./checkoutSettings";
|
|
8
8
|
export { getSubscriptionsViewModel } from "./subscriptions";
|
|
9
9
|
export { getAiWorkflowsViewModel } from "./aiWorkflows";
|
|
10
|
-
export { getEvidenceViewModel } from "
|
|
10
|
+
export { getEvidenceViewModel } from "../../../activity/fixtures/evidence";
|
|
11
11
|
export { SEEDED_TENANTS, tenantProfile } from "./tenants";
|
|
12
12
|
export type { SeededTenantProfile, MockVertical } from "./tenants";
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
randomInt,
|
|
16
16
|
seededRandom,
|
|
17
17
|
} from "../../seed";
|
|
18
|
-
import type { CustomerRow } from "
|
|
18
|
+
import type { CustomerRow } from "../../../customers/admin/viewmodels/customers";
|
|
19
19
|
import type { ProductDetail, ProductRow } from "../../viewmodels/products";
|
|
20
20
|
import type {
|
|
21
21
|
SubscriptionAttentionRow,
|
|
@@ -28,7 +28,7 @@ import type {
|
|
|
28
28
|
SubscriptionSubscriberRow,
|
|
29
29
|
SubscriptionsViewModel,
|
|
30
30
|
} from "../../viewmodels/subscriptions";
|
|
31
|
-
import { getCustomersViewModel } from "
|
|
31
|
+
import { getCustomersViewModel } from "../../../customers/fixtures/customers";
|
|
32
32
|
import { getProductsViewModel } from "./products";
|
|
33
33
|
|
|
34
34
|
export interface SubscriptionProductSource {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - referenced Shopify CDN -> Shopify's native ?width= scheme
|
|
9
9
|
* - anything else usable -> the URL as-is, no srcset
|
|
10
10
|
*/
|
|
11
|
-
import { placeholderDataUri, isUsableImageUrl } from "
|
|
11
|
+
import { placeholderDataUri, isUsableImageUrl } from "../../placeholder.js";
|
|
12
12
|
|
|
13
13
|
const RESPONSIVE_IMAGE_WIDTHS = [320, 480, 640, 960, 1280, 1600] as const;
|
|
14
14
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { AdminTenantEnvelope } from "../../envelope";
|
|
2
|
-
import { memoizeByEnvelope } from "../../memoizeByEnvelope";
|
|
3
|
-
import { MOCK_ANCHOR_ISO, offsetIso, pick, randomBool, randomInt, seededRandom } from "../../seed";
|
|
1
|
+
import type { AdminTenantEnvelope } from "../../admin/envelope";
|
|
2
|
+
import { memoizeByEnvelope } from "../../admin/memoizeByEnvelope";
|
|
3
|
+
import { MOCK_ANCHOR_ISO, offsetIso, pick, randomBool, randomInt, seededRandom } from "../../admin/seed";
|
|
4
4
|
import type {
|
|
5
5
|
BlockedReason,
|
|
6
6
|
CustomerBlockedQueueRow,
|
|
@@ -8,7 +8,7 @@ import type {
|
|
|
8
8
|
CustomerRow,
|
|
9
9
|
CustomersViewModel,
|
|
10
10
|
VerificationState,
|
|
11
|
-
} from "
|
|
11
|
+
} from "../admin/viewmodels/customers";
|
|
12
12
|
|
|
13
13
|
// Must stay index-aligned with orders.ts's CUSTOMER_NAMES: a customer's id is
|
|
14
14
|
// `cust-<tenant>-<position here>`, and orders.ts derives each order's customerId
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { AdminTenantEnvelope } from "../../envelope";
|
|
2
|
-
import { memoizeByEnvelope } from "../../memoizeByEnvelope";
|
|
3
|
-
import { pick, randomInt, seededRandom } from "../../seed";
|
|
4
|
-
import type { AnalysisBriefItem, ReportingCategory, ReportingSummary, ReportingViewModel } from "
|
|
1
|
+
import type { AdminTenantEnvelope } from "../../admin/envelope";
|
|
2
|
+
import { memoizeByEnvelope } from "../../admin/memoizeByEnvelope";
|
|
3
|
+
import { pick, randomInt, seededRandom } from "../../admin/seed";
|
|
4
|
+
import type { AnalysisBriefItem, ReportingCategory, ReportingSummary, ReportingViewModel } from "../admin/viewmodels/reporting";
|
|
5
5
|
|
|
6
6
|
const CATEGORY_DEFS: { category: ReportingCategory; label: string; drilldownHref: string }[] = [
|
|
7
7
|
{ category: "sales", label: "Sales", drilldownHref: "#orders" },
|
|
@@ -14,7 +14,7 @@ import FacetSidebar from "@/components/plp/FacetSidebar.astro";
|
|
|
14
14
|
import ActiveFilters from "@/components/plp/ActiveFilters.astro";
|
|
15
15
|
import SortSelect from "@/components/plp/SortSelect.astro";
|
|
16
16
|
import Pagination from "@/components/plp/Pagination.astro";
|
|
17
|
-
import Img from "@/components/Img.astro";
|
|
17
|
+
import Img from "@/components/assets/storefront/Img.astro";
|
|
18
18
|
import { parseQuery, buildQueryString } from "@/lib/url";
|
|
19
19
|
import { breadcrumbLd, itemListLd } from "@/lib/jsonld";
|
|
20
20
|
import { truncate } from "@/lib/format";
|
|
@@ -12,12 +12,12 @@ import Hero from "@/components/home/Hero.astro";
|
|
|
12
12
|
import ProductCarousel from "@/components/commerce/ProductCarousel.astro";
|
|
13
13
|
import ProductGrid from "@/components/commerce/ProductGrid.astro";
|
|
14
14
|
import CollectionCard from "@/components/CollectionCard.astro";
|
|
15
|
-
import Img from "@/components/Img.astro";
|
|
15
|
+
import Img from "@/components/assets/storefront/Img.astro";
|
|
16
16
|
import PromoTiles from "@/components/content/PromoTiles.astro";
|
|
17
17
|
import TrustStrip from "@/components/content/TrustStrip.astro";
|
|
18
18
|
import Faq from "@/components/marketing/Faq.astro";
|
|
19
19
|
import MarketingBlocks from "@/components/marketing/MarketingBlocks.astro";
|
|
20
|
-
import TierCards from "@/components/membership/TierCards.astro";
|
|
20
|
+
import TierCards from "@/components/membership/storefront/membership/TierCards.astro";
|
|
21
21
|
import { withBase } from "@/lib/basePath";
|
|
22
22
|
import { rawHtmlPolicy, rawHtmlResponse } from "@/lib/rawMarketingHtml";
|
|
23
23
|
import { renderRawComplianceTop, renderRawComplianceBottom } from "@/lib/compliance/rawComplianceNotices";
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import Layout from "@/layouts/Layout.astro";
|
|
7
7
|
import Breadcrumbs from "@/components/Breadcrumbs.astro";
|
|
8
8
|
import { homeCrumbLabel, siteTrail } from "@/lib/breadcrumbs";
|
|
9
|
-
import SavedList from "@/components/islands/SavedList.tsx";
|
|
9
|
+
import SavedList from "@/components/customers/storefront/islands/SavedList.tsx";
|
|
10
10
|
|
|
11
11
|
const { tenant } = Astro.locals;
|
|
12
12
|
// Commerce-only route: marketing tenants have no saved-items surface.
|
|
@@ -55,8 +55,8 @@ import PurchaseLimitNotice from "@/components/compliance/PurchaseLimitNotice.ast
|
|
|
55
55
|
import StateEligibilityNotice from "@/components/compliance/StateEligibilityNotice.astro";
|
|
56
56
|
import ShippingRestrictionNotice from "@/components/compliance/ShippingRestrictionNotice.astro";
|
|
57
57
|
import ExciseTaxNotice from "@/components/compliance/ExciseTaxNotice.astro";
|
|
58
|
-
import TierCards from "@/components/membership/TierCards.astro";
|
|
59
|
-
import TierComparisonTable from "@/components/membership/TierComparisonTable.astro";
|
|
58
|
+
import TierCards from "@/components/membership/storefront/membership/TierCards.astro";
|
|
59
|
+
import TierComparisonTable from "@/components/membership/storefront/membership/TierComparisonTable.astro";
|
|
60
60
|
import ProseSections from "@/components/content/ProseSections.astro";
|
|
61
61
|
import ProseToc from "@/components/content/ProseToc.astro";
|
|
62
62
|
import Callout from "@/components/content/Callout.astro";
|
|
@@ -74,7 +74,7 @@ import SearchTypeahead from "@/components/islands/SearchTypeahead.tsx";
|
|
|
74
74
|
import MobileNav from "@/components/islands/MobileNav.tsx";
|
|
75
75
|
import RecentlyViewed from "@/components/islands/RecentlyViewed.tsx";
|
|
76
76
|
import type { RVItem } from "@/components/islands/RecentlyViewed.tsx";
|
|
77
|
-
import SavedList from "@/components/islands/SavedList.tsx";
|
|
77
|
+
import SavedList from "@/components/customers/storefront/islands/SavedList.tsx";
|
|
78
78
|
import FacetSidebar from "@/components/plp/FacetSidebar.astro";
|
|
79
79
|
import ActiveFilters from "@/components/plp/ActiveFilters.astro";
|
|
80
80
|
import SortSelect from "@/components/plp/SortSelect.astro";
|
|
@@ -607,7 +607,7 @@ Model types (`lib/membership/model.ts`):
|
|
|
607
607
|
by index: boolean→check/dash, string→text, null→em dash).
|
|
608
608
|
- `isIllustrative(tier: Pick<Tier, "real">): boolean` → `tier.real !== true`.
|
|
609
609
|
|
|
610
|
-
### IllustrativeLabel (`components/membership/IllustrativeLabel.astro`)
|
|
610
|
+
### IllustrativeLabel (`components/membership/storefront/membership/IllustrativeLabel.astro`)
|
|
611
611
|
|
|
612
612
|
- **Purpose:** The first-class "these figures are examples, not an offer" affordance shared by
|
|
613
613
|
`TierCards`, `TierComparisonTable`, and `SavingsExplainer`.
|
|
@@ -618,7 +618,7 @@ Model types (`lib/membership/model.ts`):
|
|
|
618
618
|
- **Delivery:** platform component (no raw-chrome twin).
|
|
619
619
|
- **Usage:** rendered internally by the tier/savings widgets; `<IllustrativeLabel as="badge" />`.
|
|
620
620
|
|
|
621
|
-
### TierCards (`components/membership/TierCards.astro`)
|
|
621
|
+
### TierCards (`components/membership/storefront/membership/TierCards.astro`)
|
|
622
622
|
|
|
623
623
|
- **Purpose:** Membership/pricing tier comparison card row (e.g. Guest / Member / Autopilot). Shows
|
|
624
624
|
tiers, headline figures, feature bullets; each CTA is a plain handoff link. When any shown tier is
|
|
@@ -637,7 +637,7 @@ Model types (`lib/membership/model.ts`):
|
|
|
637
637
|
<TierCards eyebrow="Membership" heading="Choose how you shop" subhead="Compare guest checkout with our membership tiers." tiers={tiers} />
|
|
638
638
|
```
|
|
639
639
|
|
|
640
|
-
### TierComparisonTable (`components/membership/TierComparisonTable.astro`)
|
|
640
|
+
### TierComparisonTable (`components/membership/storefront/membership/TierComparisonTable.astro`)
|
|
641
641
|
|
|
642
642
|
- **Purpose:** Feature matrix companion to `TierCards` — tiers across the top, features down the side,
|
|
643
643
|
one cell per (feature × tier). Same illustrative-figure affordance. Horizontally scrollable.
|
|
@@ -1185,7 +1185,7 @@ Client-hydrated Preact `.tsx`. Every island is tenant-agnostic and reads only fi
|
|
|
1185
1185
|
<RecentlyViewed client:idle current={rvItem} locale="en-US" />
|
|
1186
1186
|
```
|
|
1187
1187
|
|
|
1188
|
-
### SavedList (`components/islands/SavedList.tsx`)
|
|
1188
|
+
### SavedList (`components/customers/storefront/islands/SavedList.tsx`)
|
|
1189
1189
|
|
|
1190
1190
|
- **Purpose:** Renders the wishlist from localStorage on the `/saved` page. Client-only; each item
|
|
1191
1191
|
links to its PDP and can be removed inline; empty state invites browsing. Phase 2 swaps the store for
|
|
@@ -1301,7 +1301,7 @@ Shared primitives composed by the higher-level widgets, plus the homepage hero.
|
|
|
1301
1301
|
<EmptyState title="No results" body="Try broadening your filters." ctaLabel="Browse all" ctaHref="/collections/all" />
|
|
1302
1302
|
```
|
|
1303
1303
|
|
|
1304
|
-
### Img (`components/Img.astro`)
|
|
1304
|
+
### Img (`components/assets/storefront/Img.astro`)
|
|
1305
1305
|
|
|
1306
1306
|
- **Purpose:** CLS-free, theme-agnostic image with offline placeholder fallback — dead fixture URLs
|
|
1307
1307
|
render a deterministic gradient SVG keyed by `seed`; real rehosted / Shopify `?width=` URLs get
|
|
@@ -1481,7 +1481,7 @@ single themed layer. **Contract-token-only** — reads only `--color-*` / `--fon
|
|
|
1481
1481
|
|
|
1482
1482
|
**Cross-island `window` CustomEvents:** `variant:image` (VariantSelector → ImageGallery),
|
|
1483
1483
|
`variant:change` (VariantSelector → any listener), `tot:wishlist-changed` / `WISHLIST_EVENT`
|
|
1484
|
-
(`lib/wishlist` → SavedList + header count), and delegated `[data-quickview]` buttons → QuickView.
|
|
1484
|
+
(`lib/customers/shared/wishlist` → SavedList + header count), and delegated `[data-quickview]` buttons → QuickView.
|
|
1485
1485
|
|
|
1486
1486
|
**`localStorage` keys:** `"tot:age-affirmed"` (age gate), `"tot:recently-viewed"` (RecentlyViewed),
|
|
1487
1487
|
`"tot:wishlist"` (SavedList/wishlist), `tot_announce_dismissed` (raw-chrome announce dismissal).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/storefront-runner",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.85",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"description": "World-shareable storefront runner: multi-tenant renderer on Astro/Cloudflare. No control plane.",
|
|
6
6
|
"packageManager": "pnpm@11.9.0",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|