@burdenoff/microfe-ggnomad 2026.728.2 → 2026.730.1

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.
@@ -0,0 +1,9 @@
1
+ /**
2
+ * BOFF-4363 — the branded storefront page a traveler sees, backed by the
3
+ * genuinely public `ggnomadStorefrontBySlug` query. Note: this route still
4
+ * renders inside the authenticated app shell today — making it reachable
5
+ * without any login at all is a routing/CDN concern for the app shell, not
6
+ * this MFE (tracked alongside the deferred custom-domain work in BOFF-4363).
7
+ */
8
+ export declare function StorefrontPublicPage(): import("react").JSX.Element;
9
+ //# sourceMappingURL=StorefrontPublicPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StorefrontPublicPage.d.ts","sourceRoot":"","sources":["../../../src/ggnomad/pages/StorefrontPublicPage.tsx"],"names":[],"mappings":"AAqCA;;;;;;GAMG;AACH,wBAAgB,oBAAoB,gCAqHnC"}
@@ -0,0 +1,98 @@
1
+ import { GGNOMAD_STOREFRONT_BY_SLUG_QUERY as e } from "../graphql.js";
2
+ import { PageShell as t } from "./PageShell.js";
3
+ import { useGGNomad as n } from "../providers/GGNomadProvider.js";
4
+ import { Leaf as r } from "lucide-react";
5
+ import { useI18n as i } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
6
+ import { useParams as a } from "react-router-dom";
7
+ import { useQuery as o } from "@apollo/client/react";
8
+ import { GlassCard as s, IllustratedEmptyState as c, Spinner as l } from "@burdenoff/fe-libs/ui";
9
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
10
+ //#region src/ggnomad/pages/StorefrontPublicPage.tsx
11
+ function f() {
12
+ let { t: f } = i(), { slug: p = "" } = a(), { workspaceId: m = "" } = n(), { data: h, loading: g } = o(e, {
13
+ variables: {
14
+ workspaceId: m,
15
+ slug: p
16
+ },
17
+ skip: !m || !p
18
+ }), _ = h?.ggnomadStorefrontBySlug ?? null, v = _?.storefront.primaryColor ?? "#1E88E5", y = _ ? [
19
+ ..._.properties,
20
+ ..._.tours,
21
+ ..._.events,
22
+ ..._.activities
23
+ ] : [];
24
+ return g ? /* @__PURE__ */ u(t, {
25
+ title: f("ggnomad.storefrontPublic.title", "Storefront"),
26
+ subtitle: "",
27
+ children: /* @__PURE__ */ u("div", {
28
+ className: "flex justify-center py-10",
29
+ children: /* @__PURE__ */ u(l, {})
30
+ })
31
+ }) : _ ? /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("div", {
32
+ className: "p-6",
33
+ style: {
34
+ background: `${v}14`,
35
+ borderBottom: `4px solid ${v}`
36
+ },
37
+ children: /* @__PURE__ */ d("div", {
38
+ className: "mx-auto flex max-w-4xl items-center gap-4",
39
+ children: [_.storefront.logoUrl ? /* @__PURE__ */ u("img", {
40
+ src: _.storefront.logoUrl,
41
+ alt: "",
42
+ className: "size-16 rounded object-contain"
43
+ }) : /* @__PURE__ */ u("div", {
44
+ className: "flex size-16 items-center justify-center rounded text-2xl font-semibold text-white",
45
+ style: { background: v },
46
+ children: _.storefront.displayName.slice(0, 1).toUpperCase()
47
+ }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("h1", {
48
+ className: "text-2xl font-semibold text-text-primary",
49
+ children: _.storefront.displayName
50
+ }), _.storefront.aboutText ? /* @__PURE__ */ u("p", {
51
+ className: "mt-1 max-w-2xl text-sm text-text-secondary",
52
+ children: _.storefront.aboutText
53
+ }) : null] })]
54
+ })
55
+ }), /* @__PURE__ */ u("div", {
56
+ className: "mx-auto max-w-4xl p-6",
57
+ children: y.length === 0 ? /* @__PURE__ */ u(c, {
58
+ illustration: "empty-people",
59
+ title: f("ggnomad.storefrontPublic.emptyTitle", "Nothing listed yet"),
60
+ description: f("ggnomad.storefrontPublic.emptyDescription", "This operator has not published any active listings.")
61
+ }) : /* @__PURE__ */ u("div", {
62
+ className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
63
+ children: y.map((e) => /* @__PURE__ */ d(s, {
64
+ treatment: "glass",
65
+ className: "border-border-seam p-4",
66
+ children: [
67
+ /* @__PURE__ */ u("h3", {
68
+ className: "font-medium text-text-primary",
69
+ children: e.name
70
+ }),
71
+ /* @__PURE__ */ u("p", {
72
+ className: "mt-1 text-sm text-text-secondary",
73
+ children: (e.price ?? e.pricePerNight ?? 0).toLocaleString(void 0, {
74
+ style: "currency",
75
+ currency: e.currency
76
+ })
77
+ }),
78
+ e.sustainabilityScore > 0 ? /* @__PURE__ */ d("p", {
79
+ className: "mt-2 inline-flex items-center gap-1 text-xs text-text-secondary",
80
+ children: [/* @__PURE__ */ u(r, { className: "size-3.5 text-emerald-500" }), f("ggnomad.storefrontPublic.sustainabilityScore", "{score}% self-reported sustainable").replace("{score}", String(e.sustainabilityScore))]
81
+ }) : null
82
+ ]
83
+ }, e.id))
84
+ })
85
+ })] }) : /* @__PURE__ */ u(t, {
86
+ title: f("ggnomad.storefrontPublic.title", "Storefront"),
87
+ subtitle: f("ggnomad.storefrontPublic.notFoundSubtitle", "This storefront is not available."),
88
+ children: /* @__PURE__ */ u(c, {
89
+ illustration: "empty-search",
90
+ title: f("ggnomad.storefrontPublic.notFoundTitle", "Storefront not found"),
91
+ description: f("ggnomad.storefrontPublic.notFoundDescription", "This link may be mistyped, or the operator has not published a storefront yet.")
92
+ })
93
+ });
94
+ }
95
+ //#endregion
96
+ export { f as StorefrontPublicPage };
97
+
98
+ //# sourceMappingURL=StorefrontPublicPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StorefrontPublicPage.js","names":[],"sources":["../../../src/ggnomad/pages/StorefrontPublicPage.tsx"],"sourcesContent":["import { useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useParams } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Leaf } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, Spinner } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_STOREFRONT_BY_SLUG_QUERY } from '../graphql';\nimport { PageShell } from './PageShell';\nimport { useGGNomad } from '../providers/GGNomadProvider';\n\ntype StorefrontListing = {\n id: string;\n name: string;\n price?: number;\n pricePerNight?: number;\n currency: string;\n images: string[];\n rating?: number | null;\n sustainabilityScore: number;\n};\n\ntype StorefrontPage = {\n storefront: {\n id: string;\n displayName: string;\n logoUrl: string | null;\n primaryColor: string | null;\n aboutText: string | null;\n publishedAt: string | null;\n };\n properties: StorefrontListing[];\n tours: StorefrontListing[];\n events: StorefrontListing[];\n activities: StorefrontListing[];\n};\n\n/**\n * BOFF-4363 — the branded storefront page a traveler sees, backed by the\n * genuinely public `ggnomadStorefrontBySlug` query. Note: this route still\n * renders inside the authenticated app shell today — making it reachable\n * without any login at all is a routing/CDN concern for the app shell, not\n * this MFE (tracked alongside the deferred custom-domain work in BOFF-4363).\n */\nexport function StorefrontPublicPage() {\n const { t } = useI18n();\n const { slug = '' } = useParams();\n const { workspaceId = '' } = useGGNomad();\n\n const { data, loading } = useQuery(\n GGNOMAD_STOREFRONT_BY_SLUG_QUERY as TypedDocumentNode<\n { ggnomadStorefrontBySlug: StorefrontPage | null },\n { workspaceId: string; slug: string }\n >,\n { variables: { workspaceId, slug }, skip: !workspaceId || !slug }\n );\n\n const page = data?.ggnomadStorefrontBySlug ?? null;\n const brandColor = page?.storefront.primaryColor ?? '#1E88E5';\n const allListings = page\n ? [...page.properties, ...page.tours, ...page.events, ...page.activities]\n : [];\n\n if (loading) {\n return (\n <PageShell title={t('ggnomad.storefrontPublic.title', 'Storefront')} subtitle=\"\">\n <div className=\"flex justify-center py-10\">\n <Spinner />\n </div>\n </PageShell>\n );\n }\n\n if (!page) {\n return (\n <PageShell\n title={t('ggnomad.storefrontPublic.title', 'Storefront')}\n subtitle={t(\n 'ggnomad.storefrontPublic.notFoundSubtitle',\n 'This storefront is not available.'\n )}\n >\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={t('ggnomad.storefrontPublic.notFoundTitle', 'Storefront not found')}\n description={t(\n 'ggnomad.storefrontPublic.notFoundDescription',\n 'This link may be mistyped, or the operator has not published a storefront yet.'\n )}\n />\n </PageShell>\n );\n }\n\n return (\n <div>\n <div\n className=\"p-6\"\n style={{ background: `${brandColor}14`, borderBottom: `4px solid ${brandColor}` }}\n >\n <div className=\"mx-auto flex max-w-4xl items-center gap-4\">\n {page.storefront.logoUrl ? (\n <img src={page.storefront.logoUrl} alt=\"\" className=\"size-16 rounded object-contain\" />\n ) : (\n <div\n className=\"flex size-16 items-center justify-center rounded text-2xl font-semibold text-white\"\n style={{ background: brandColor }}\n >\n {page.storefront.displayName.slice(0, 1).toUpperCase()}\n </div>\n )}\n <div>\n <h1 className=\"text-2xl font-semibold text-text-primary\">\n {page.storefront.displayName}\n </h1>\n {page.storefront.aboutText ? (\n <p className=\"mt-1 max-w-2xl text-sm text-text-secondary\">\n {page.storefront.aboutText}\n </p>\n ) : null}\n </div>\n </div>\n </div>\n\n <div className=\"mx-auto max-w-4xl p-6\">\n {allListings.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title={t('ggnomad.storefrontPublic.emptyTitle', 'Nothing listed yet')}\n description={t(\n 'ggnomad.storefrontPublic.emptyDescription',\n 'This operator has not published any active listings.'\n )}\n />\n ) : (\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {allListings.map((listing) => (\n <GlassCard key={listing.id} treatment=\"glass\" className=\"border-border-seam p-4\">\n <h3 className=\"font-medium text-text-primary\">{listing.name}</h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {(listing.price ?? listing.pricePerNight ?? 0).toLocaleString(undefined, {\n style: 'currency',\n currency: listing.currency,\n })}\n </p>\n {listing.sustainabilityScore > 0 ? (\n <p className=\"mt-2 inline-flex items-center gap-1 text-xs text-text-secondary\">\n <Leaf className=\"size-3.5 text-emerald-500\" />\n {t(\n 'ggnomad.storefrontPublic.sustainabilityScore',\n '{score}% self-reported sustainable'\n ).replace('{score}', String(listing.sustainabilityScore))}\n </p>\n ) : null}\n </GlassCard>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AA4CA,SAAgB,IAAuB;CACrC,IAAM,EAAE,SAAM,EAAQ,GAChB,EAAE,UAAO,OAAO,EAAU,GAC1B,EAAE,iBAAc,OAAO,EAAW,GAElC,EAAE,SAAM,eAAY,EACxB,GAIA;EAAE,WAAW;GAAE;GAAa;EAAK;EAAG,MAAM,CAAC,KAAe,CAAC;CAAK,CAClE,GAEM,IAAO,GAAM,2BAA2B,MACxC,IAAa,GAAM,WAAW,gBAAgB,WAC9C,IAAc,IAChB;EAAC,GAAG,EAAK;EAAY,GAAG,EAAK;EAAO,GAAG,EAAK;EAAQ,GAAG,EAAK;CAAU,IACtE,CAAC;CAiCL,OA/BI,IAEA,kBAAC,GAAD;EAAW,OAAO,EAAE,kCAAkC,YAAY;EAAG,UAAS;YAC5E,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,GAAD,CAAU,CAAA;EACP,CAAA;CACI,CAAA,IAIV,IAsBH,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;EACE,WAAU;EACV,OAAO;GAAE,YAAY,GAAG,EAAW;GAAK,cAAc,aAAa;EAAa;YAEhF,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAK,WAAW,UACf,kBAAC,OAAD;IAAK,KAAK,EAAK,WAAW;IAAS,KAAI;IAAG,WAAU;GAAkC,CAAA,IAEtF,kBAAC,OAAD;IACE,WAAU;IACV,OAAO,EAAE,YAAY,EAAW;cAE/B,EAAK,WAAW,YAAY,MAAM,GAAG,CAAC,EAAE,YAAY;GAClD,CAAA,GAEP,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;cACX,EAAK,WAAW;GACf,CAAA,GACH,EAAK,WAAW,YACf,kBAAC,KAAD;IAAG,WAAU;cACV,EAAK,WAAW;GAChB,CAAA,IACD,IACD,EAAA,CAAA,CACF;;CACF,CAAA,GAEL,kBAAC,OAAD;EAAK,WAAU;YACZ,EAAY,WAAW,IACtB,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,uCAAuC,oBAAoB;GACpE,aAAa,EACX,6CACA,sDACF;EACD,CAAA,IAED,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAY,KAAK,MAChB,kBAAC,GAAD;IAA4B,WAAU;IAAQ,WAAU;cAAxD;KACE,kBAAC,MAAD;MAAI,WAAU;gBAAiC,EAAQ;KAAS,CAAA;KAChE,kBAAC,KAAD;MAAG,WAAU;iBACT,EAAQ,SAAS,EAAQ,iBAAiB,GAAG,eAAe,KAAA,GAAW;OACvE,OAAO;OACP,UAAU,EAAQ;MACpB,CAAC;KACA,CAAA;KACF,EAAQ,sBAAsB,IAC7B,kBAAC,KAAD;MAAG,WAAU;gBAAb,CACE,kBAAC,GAAD,EAAM,WAAU,4BAA6B,CAAA,GAC5C,EACC,gDACA,oCACF,EAAE,QAAQ,WAAW,OAAO,EAAQ,mBAAmB,CAAC,CACvD;UACD;IACK;MAjBK,EAAQ,EAiBb,CACZ;EACE,CAAA;CAEJ,CAAA,CACF,EAAA,CAAA,IApFH,kBAAC,GAAD;EACE,OAAO,EAAE,kCAAkC,YAAY;EACvD,UAAU,EACR,6CACA,mCACF;YAEA,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,0CAA0C,sBAAsB;GACzE,aAAa,EACX,gDACA,gFACF;EACD,CAAA;CACQ,CAAA;AAuEjB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-ggnomad",
3
- "version": "2026.728.2",
3
+ "version": "2026.730.1",
4
4
  "description": "Burdenoff GGNomad Microfrontend",
5
5
  "type": "module",
6
6
  "files": [