@burdenoff/microfe-ggnomad 2026.704.1 → 2026.705.2

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,22 @@
1
+ import { cn as e } from "../utils/cn.js";
2
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
+ //#region src/ggnomad/components/DetailHero.tsx
4
+ function r({ image: r, alt: i, className: a }) {
5
+ return /* @__PURE__ */ n("div", {
6
+ className: e("relative mb-5 aspect-[21/9] w-full overflow-hidden rounded-card border border-border-seam", a),
7
+ children: [r ? /* @__PURE__ */ t("img", {
8
+ src: r,
9
+ alt: i ?? "",
10
+ loading: "eager",
11
+ decoding: "async",
12
+ className: "size-full object-cover"
13
+ }) : /* @__PURE__ */ t("div", {
14
+ "aria-hidden": "true",
15
+ className: "size-full bg-gradient-to-br from-action-primary-bg/30 via-bg-sunken to-bg-sunken"
16
+ }), /* @__PURE__ */ t("div", { className: "pointer-events-none absolute inset-0 bg-gradient-to-t from-black/50 via-transparent to-transparent" })]
17
+ });
18
+ }
19
+ //#endregion
20
+ export { r as DetailHero };
21
+
22
+ //# sourceMappingURL=DetailHero.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DetailHero.js","names":[],"sources":["../../../src/ggnomad/components/DetailHero.tsx"],"sourcesContent":["import { cn } from '../utils/cn';\n\ninterface DetailHeroProps {\n /** Primary cover image URL; a branded gradient is shown when absent. */\n image?: string | null;\n alt?: string;\n className?: string;\n}\n\n/**\n * Full-width hero cover for a listing detail page — a 21:9 photo with a bottom\n * gradient scrim, or a branded gradient fallback when the listing has no media.\n */\nexport function DetailHero({ image, alt, className }: DetailHeroProps) {\n return (\n <div\n className={cn(\n 'relative mb-5 aspect-[21/9] w-full overflow-hidden rounded-card border border-border-seam',\n className\n )}\n >\n {image ? (\n <img\n src={image}\n alt={alt ?? ''}\n loading=\"eager\"\n decoding=\"async\"\n className=\"size-full object-cover\"\n />\n ) : (\n <div\n aria-hidden=\"true\"\n className=\"size-full bg-gradient-to-br from-action-primary-bg/30 via-bg-sunken to-bg-sunken\"\n />\n )}\n <div className=\"pointer-events-none absolute inset-0 bg-gradient-to-t from-black/50 via-transparent to-transparent\" />\n </div>\n );\n}\n"],"mappings":";;;AAaA,SAAgB,EAAW,EAAE,UAAO,QAAK,gBAA8B;AACrE,QACE,kBAAC,OAAD;EACE,WAAW,EACT,6FACA,EACD;YAJH,CAMG,IACC,kBAAC,OAAD;GACE,KAAK;GACL,KAAK,KAAO;GACZ,SAAQ;GACR,UAAS;GACT,WAAU;GACV,CAAA,GAEF,kBAAC,OAAD;GACE,eAAY;GACZ,WAAU;GACV,CAAA,EAEJ,kBAAC,OAAD,EAAK,WAAU,sGAAuG,CAAA,CAClH"}
@@ -3,22 +3,36 @@ import { Link as t } from "react-router-dom";
3
3
  import { GlassCard as n } from "@burdenoff/fe-libs/ui";
4
4
  import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
5
5
  //#region src/ggnomad/components/EntityCard.tsx
6
- function o({ title: o, meta: s, price: c, badge: l, footer: u, to: d, className: f }) {
7
- let p = /* @__PURE__ */ a(r, { children: [
6
+ function o({ title: o, meta: s, price: c, badge: l, footer: u, image: d, imageAlt: f, to: p, className: m }) {
7
+ let h = /* @__PURE__ */ a(r, { children: [
8
8
  /* @__PURE__ */ a("div", {
9
- className: "flex items-start justify-between gap-3",
10
- children: [/* @__PURE__ */ a("div", {
11
- className: "min-w-0",
12
- children: [/* @__PURE__ */ i("p", {
13
- className: "truncate font-medium text-text-primary",
14
- children: o
15
- }), s ? /* @__PURE__ */ i("p", {
16
- className: "mt-0.5 text-sm text-text-secondary",
17
- children: s
18
- }) : null]
19
- }), l ? /* @__PURE__ */ i("div", {
20
- className: "flex-shrink-0",
21
- children: l
9
+ className: "relative -mx-4 -mt-4 mb-3 aspect-[16/10] overflow-hidden",
10
+ children: [
11
+ d ? /* @__PURE__ */ i("img", {
12
+ src: d,
13
+ alt: f ?? "",
14
+ loading: "lazy",
15
+ decoding: "async",
16
+ className: "size-full object-cover transition-transform duration-300 group-hover:scale-[1.04]"
17
+ }) : /* @__PURE__ */ i("div", {
18
+ "aria-hidden": "true",
19
+ className: "size-full bg-gradient-to-br from-action-primary-bg/25 via-bg-sunken to-bg-sunken"
20
+ }),
21
+ /* @__PURE__ */ i("div", { className: "pointer-events-none absolute inset-0 bg-gradient-to-t from-black/45 via-transparent to-transparent" }),
22
+ l ? /* @__PURE__ */ i("div", {
23
+ className: "absolute left-2 top-2",
24
+ children: l
25
+ }) : null
26
+ ]
27
+ }),
28
+ /* @__PURE__ */ a("div", {
29
+ className: "min-w-0",
30
+ children: [/* @__PURE__ */ i("p", {
31
+ className: "truncate font-medium text-text-primary",
32
+ children: o
33
+ }), s ? /* @__PURE__ */ i("p", {
34
+ className: "mt-0.5 text-sm text-text-secondary",
35
+ children: s
22
36
  }) : null]
23
37
  }),
24
38
  c ? /* @__PURE__ */ i("p", {
@@ -30,18 +44,18 @@ function o({ title: o, meta: s, price: c, badge: l, footer: u, to: d, className:
30
44
  children: u
31
45
  }) : null
32
46
  ] });
33
- return d ? /* @__PURE__ */ i(t, {
34
- to: d,
35
- className: "block rounded-card focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-canvas",
47
+ return p ? /* @__PURE__ */ i(t, {
48
+ to: p,
49
+ className: "group block rounded-card focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-canvas",
36
50
  children: /* @__PURE__ */ i(n, {
37
51
  treatment: "plain",
38
- className: e("border-border-seam p-4", f),
39
- children: p
52
+ className: e("overflow-hidden border-border-seam p-4", m),
53
+ children: h
40
54
  })
41
55
  }) : /* @__PURE__ */ i(n, {
42
56
  treatment: "plain",
43
- className: e("border-border-seam p-4", f),
44
- children: p
57
+ className: e("group overflow-hidden border-border-seam p-4", m),
58
+ children: h
45
59
  });
46
60
  }
47
61
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"EntityCard.js","names":[],"sources":["../../../src/ggnomad/components/EntityCard.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { Link } from 'react-router-dom';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\n\ntype EntityCardProps = {\n title: ReactNode;\n /** Optional secondary line (category / type / duration). */\n meta?: ReactNode;\n /** Right-aligned price or primary figure. */\n price?: ReactNode;\n badge?: ReactNode;\n footer?: ReactNode;\n /** When provided, the whole card becomes a router Link. */\n to?: string;\n className?: string;\n};\n\n/**\n * A calm, low-contrast tile for an inventory item (property, tour, event,\n * provider). Hover only lifts the shadow / seam — never moves. When `to` is set\n * the entire surface is a single accessible link.\n */\nexport function EntityCard({ title, meta, price, badge, footer, to, className }: EntityCardProps) {\n const body = (\n <>\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{title}</p>\n {meta ? <p className=\"mt-0.5 text-sm text-text-secondary\">{meta}</p> : null}\n </div>\n {badge ? <div className=\"flex-shrink-0\">{badge}</div> : null}\n </div>\n {price ? (\n <p className=\"mt-2 text-sm font-medium tabular-nums text-text-primary\">{price}</p>\n ) : null}\n {footer ? <div className=\"mt-2 text-sm text-text-secondary\">{footer}</div> : null}\n </>\n );\n\n if (to) {\n return (\n <Link\n to={to}\n className=\"block rounded-card focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-canvas\"\n >\n <GlassCard treatment=\"plain\" className={cn('border-border-seam p-4', className)}>\n {body}\n </GlassCard>\n </Link>\n );\n }\n\n return (\n <GlassCard treatment=\"plain\" className={cn('border-border-seam p-4', className)}>\n {body}\n </GlassCard>\n );\n}\n"],"mappings":";;;;;AAuBA,SAAgB,EAAW,EAAE,UAAO,SAAM,UAAO,UAAO,WAAQ,OAAI,gBAA8B;CAChG,IAAM,IACJ,kBAAA,GAAA,EAAA,UAAA;EACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eAA0C;KAAU,CAAA,EAChE,IAAO,kBAAC,KAAD;KAAG,WAAU;eAAsC;KAAS,CAAA,GAAG,KACnE;OACL,IAAQ,kBAAC,OAAD;IAAK,WAAU;cAAiB;IAAY,CAAA,GAAG,KACpD;;EACL,IACC,kBAAC,KAAD;GAAG,WAAU;aAA2D;GAAU,CAAA,GAChF;EACH,IAAS,kBAAC,OAAD;GAAK,WAAU;aAAoC;GAAa,CAAA,GAAG;EAC5E,EAAA,CAAA;AAgBL,QAbI,IAEA,kBAAC,GAAD;EACM;EACJ,WAAU;YAEV,kBAAC,GAAD;GAAW,WAAU;GAAQ,WAAW,EAAG,0BAA0B,EAAU;aAC5E;GACS,CAAA;EACP,CAAA,GAKT,kBAAC,GAAD;EAAW,WAAU;EAAQ,WAAW,EAAG,0BAA0B,EAAU;YAC5E;EACS,CAAA"}
1
+ {"version":3,"file":"EntityCard.js","names":[],"sources":["../../../src/ggnomad/components/EntityCard.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { Link } from 'react-router-dom';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/cn';\n\ntype EntityCardProps = {\n title: ReactNode;\n /** Optional secondary line (category / type / duration). */\n meta?: ReactNode;\n /** Right-aligned price or primary figure. */\n price?: ReactNode;\n badge?: ReactNode;\n footer?: ReactNode;\n /** Optional cover photo URL. Falls back to a branded gradient tile. */\n image?: string | null;\n /** Accessible description for the cover photo. */\n imageAlt?: string;\n /** When provided, the whole card becomes a router Link. */\n to?: string;\n className?: string;\n};\n\n/**\n * An inventory tile for a property / tour / event / activity / provider. When an\n * `image` is supplied it renders a 16:10 cover photo (with a branded gradient\n * fallback otherwise) above the title / meta / price. Hover lifts the shadow and\n * gently zooms the photo. When `to` is set the whole surface is one accessible link.\n */\nexport function EntityCard({\n title,\n meta,\n price,\n badge,\n footer,\n image,\n imageAlt,\n to,\n className,\n}: EntityCardProps) {\n const cover = (\n <div className=\"relative -mx-4 -mt-4 mb-3 aspect-[16/10] overflow-hidden\">\n {image ? (\n <img\n src={image}\n alt={imageAlt ?? ''}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"size-full object-cover transition-transform duration-300 group-hover:scale-[1.04]\"\n />\n ) : (\n <div\n aria-hidden=\"true\"\n className=\"size-full bg-gradient-to-br from-action-primary-bg/25 via-bg-sunken to-bg-sunken\"\n />\n )}\n <div className=\"pointer-events-none absolute inset-0 bg-gradient-to-t from-black/45 via-transparent to-transparent\" />\n {badge ? <div className=\"absolute left-2 top-2\">{badge}</div> : null}\n </div>\n );\n\n const body = (\n <>\n {cover}\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{title}</p>\n {meta ? <p className=\"mt-0.5 text-sm text-text-secondary\">{meta}</p> : null}\n </div>\n {price ? (\n <p className=\"mt-2 text-sm font-medium tabular-nums text-text-primary\">{price}</p>\n ) : null}\n {footer ? <div className=\"mt-2 text-sm text-text-secondary\">{footer}</div> : null}\n </>\n );\n\n if (to) {\n return (\n <Link\n to={to}\n className=\"group block rounded-card focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-canvas\"\n >\n <GlassCard\n treatment=\"plain\"\n className={cn('overflow-hidden border-border-seam p-4', className)}\n >\n {body}\n </GlassCard>\n </Link>\n );\n }\n\n return (\n <GlassCard\n treatment=\"plain\"\n className={cn('group overflow-hidden border-border-seam p-4', className)}\n >\n {body}\n </GlassCard>\n );\n}\n"],"mappings":";;;;;AA4BA,SAAgB,EAAW,EACzB,UACA,SACA,UACA,UACA,WACA,UACA,aACA,OACA,gBACkB;CAsBlB,IAAM,IACJ,kBAAA,GAAA,EAAA,UAAA;EArBA,kBAAC,OAAD;GAAK,WAAU;aAAf;IACG,IACC,kBAAC,OAAD;KACE,KAAK;KACL,KAAK,KAAY;KACjB,SAAQ;KACR,UAAS;KACT,WAAU;KACV,CAAA,GAEF,kBAAC,OAAD;KACE,eAAY;KACZ,WAAU;KACV,CAAA;IAEJ,kBAAC,OAAD,EAAK,WAAU,sGAAuG,CAAA;IACrH,IAAQ,kBAAC,OAAD;KAAK,WAAU;eAAyB;KAAY,CAAA,GAAG;IAC5D;;EAMJ,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAA0C;IAAU,CAAA,EAChE,IAAO,kBAAC,KAAD;IAAG,WAAU;cAAsC;IAAS,CAAA,GAAG,KACnE;;EACL,IACC,kBAAC,KAAD;GAAG,WAAU;aAA2D;GAAU,CAAA,GAChF;EACH,IAAS,kBAAC,OAAD;GAAK,WAAU;aAAoC;GAAa,CAAA,GAAG;EAC5E,EAAA,CAAA;AAmBL,QAhBI,IAEA,kBAAC,GAAD;EACM;EACJ,WAAU;YAEV,kBAAC,GAAD;GACE,WAAU;GACV,WAAW,EAAG,0CAA0C,EAAU;aAEjE;GACS,CAAA;EACP,CAAA,GAKT,kBAAC,GAAD;EACE,WAAU;EACV,WAAW,EAAG,gDAAgD,EAAU;YAEvE;EACS,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { useI18n as e } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
2
+ import { jsx as t } from "react/jsx-runtime";
3
+ //#region src/ggnomad/components/LoadMoreButton.tsx
4
+ function n({ visible: n, onLoadMore: r }) {
5
+ let { t: i } = e();
6
+ return n ? /* @__PURE__ */ t("div", {
7
+ className: "mt-6 flex justify-center",
8
+ children: /* @__PURE__ */ t("button", {
9
+ type: "button",
10
+ onClick: r,
11
+ className: "rounded-lg border border-border-seam bg-bg-surface px-5 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-action-primary-bg",
12
+ children: i("ggnomad.common.loadMore", "Load more")
13
+ })
14
+ }) : null;
15
+ }
16
+ //#endregion
17
+ export { n as LoadMoreButton };
18
+
19
+ //# sourceMappingURL=LoadMoreButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadMoreButton.js","names":[],"sources":["../../../src/ggnomad/components/LoadMoreButton.tsx"],"sourcesContent":["import { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface LoadMoreButtonProps {\n /** Whether more items may exist (typically items.length >= current limit). */\n visible: boolean;\n /** Increase the page limit to fetch the next batch. */\n onLoadMore: () => void;\n}\n\n/**\n * Offset \"Load more\" control shown under a list grid when the current page is\n * full and more results may exist. Tokenized + responsive; no fixed widths.\n */\nexport function LoadMoreButton({ visible, onLoadMore }: LoadMoreButtonProps) {\n const { t } = useI18n();\n if (!visible) return null;\n return (\n <div className=\"mt-6 flex justify-center\">\n <button\n type=\"button\"\n onClick={onLoadMore}\n className=\"rounded-lg border border-border-seam bg-bg-surface px-5 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-action-primary-bg\"\n >\n {t('ggnomad.common.loadMore', 'Load more')}\n </button>\n </div>\n );\n}\n"],"mappings":";;;AAaA,SAAgB,EAAe,EAAE,YAAS,iBAAmC;CAC3E,IAAM,EAAE,SAAM,GAAS;AAEvB,QADK,IAEH,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,UAAD;GACE,MAAK;GACL,SAAS;GACT,WAAU;aAET,EAAE,2BAA2B,YAAY;GACnC,CAAA;EACL,CAAA,GAVa"}
@@ -3,3 +3,5 @@ import "./StatusBadge.js";
3
3
  import "./SectionCard.js";
4
4
  import "./EntityCard.js";
5
5
  import "./DetailRow.js";
6
+ import "./LoadMoreButton.js";
7
+ import "./DetailHero.js";
@@ -2,92 +2,99 @@ import { GGNOMAD_ACTIVITY_QUERY as e } from "../graphql.js";
2
2
  import { PageShell as t } from "./PageShell.js";
3
3
  import { SectionCard as n } from "../components/SectionCard.js";
4
4
  import { DetailRow as r } from "../components/DetailRow.js";
5
+ import { DetailHero as i } from "../components/DetailHero.js";
5
6
  import "../components/index.js";
6
- import { Activity as i, CalendarCheck as a, Compass as o, ShieldCheck as s } from "lucide-react";
7
- import { useI18n as c } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
8
- import { useNavigate as l, useParams as u } from "react-router-dom";
9
- import { useQuery as d } from "@apollo/client/react";
10
- import { GlassCard as f, IllustratedEmptyState as p, NextSteps as m, PagePurpose as h } from "@burdenoff/fe-libs/ui";
11
- import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
7
+ import { useGGNomad as a } from "../providers/GGNomadProvider.js";
8
+ import { joinPath as o } from "../utils/navigation.js";
9
+ import { Activity as s, CalendarCheck as c, Compass as l, ShieldCheck as u } from "lucide-react";
10
+ import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
11
+ import { useNavigate as f, useParams as p } from "react-router-dom";
12
+ import { useQuery as m } from "@apollo/client/react";
13
+ import { GlassCard as h, IllustratedEmptyState as g, NextSteps as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
14
+ import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
12
15
  //#region src/ggnomad/pages/ActivityDetailsPage.tsx
13
- function y() {
14
- let { t: y } = c(), b = l(), { id: x = "" } = u(), { data: S } = d(e, {
15
- variables: { id: x },
16
- skip: !x
17
- }), C = S?.ggnomadActivity;
18
- return /* @__PURE__ */ _(t, {
19
- title: C?.name ?? y("ggnomad.activity.fallbackTitle", "Activity details"),
20
- subtitle: y("ggnomad.activity.subtitle", "Safety, inclusions and participation details"),
21
- children: C ? /* @__PURE__ */ v(g, { children: [
22
- /* @__PURE__ */ _(h, {
23
- icon: /* @__PURE__ */ _(i, { className: "size-4" }),
24
- children: y("ggnomad.activity.purpose", "Everything you need to know before joining this activity — its category, duration, group size, price and the safety policy that applies — so you can be confident it fits your group before you book.")
16
+ function S() {
17
+ let { t: S } = d(), C = f(), { basePath: w = "/" } = a(), { id: T = "" } = p(), { data: E } = m(e, {
18
+ variables: { id: T },
19
+ skip: !T
20
+ }), D = E?.ggnomadActivity;
21
+ return /* @__PURE__ */ b(t, {
22
+ title: D?.name ?? S("ggnomad.activity.fallbackTitle", "Activity details"),
23
+ subtitle: S("ggnomad.activity.subtitle", "Safety, inclusions and participation details"),
24
+ children: D ? /* @__PURE__ */ x(y, { children: [
25
+ /* @__PURE__ */ b(i, {
26
+ image: D.images?.[0],
27
+ alt: D.name
25
28
  }),
26
- /* @__PURE__ */ _(m, {
29
+ /* @__PURE__ */ b(v, {
30
+ icon: /* @__PURE__ */ b(s, { className: "size-4" }),
31
+ children: S("ggnomad.activity.purpose", "Everything you need to know before joining this activity — its category, duration, group size, price and the safety policy that applies — so you can be confident it fits your group before you book.")
32
+ }),
33
+ /* @__PURE__ */ b(_, {
27
34
  storageKey: "ggnomad-activity-detail",
28
35
  steps: [{
29
36
  id: "book",
30
- label: y("ggnomad.activity.next.book", "Book this activity"),
31
- description: y("ggnomad.activity.next.bookDesc", "Add it to your itinerary and track it under Bookings."),
32
- icon: /* @__PURE__ */ _(a, { className: "size-4" }),
33
- onClick: () => b("../../../bookings")
37
+ label: S("ggnomad.activity.next.book", "Book this activity"),
38
+ description: S("ggnomad.activity.next.bookDesc", "Add it to your itinerary and track it under Bookings."),
39
+ icon: /* @__PURE__ */ b(c, { className: "size-4" }),
40
+ onClick: () => C(o(w, "bookings"))
34
41
  }, {
35
42
  id: "browse",
36
- label: y("ggnomad.activity.next.browse", "Explore more experiences"),
37
- description: y("ggnomad.activity.next.browseDesc", "Return to Tourism to compare tours and activities."),
38
- icon: /* @__PURE__ */ _(o, { className: "size-4" }),
39
- onClick: () => b("../..")
43
+ label: S("ggnomad.activity.next.browse", "Explore more experiences"),
44
+ description: S("ggnomad.activity.next.browseDesc", "Return to Tourism to compare tours and activities."),
45
+ icon: /* @__PURE__ */ b(l, { className: "size-4" }),
46
+ onClick: () => C(o(w, "tourism"))
40
47
  }]
41
48
  }),
42
- /* @__PURE__ */ v("div", {
49
+ /* @__PURE__ */ x("div", {
43
50
  className: "grid gap-4 lg:grid-cols-2",
44
- children: [/* @__PURE__ */ v(f, {
51
+ children: [/* @__PURE__ */ x(h, {
45
52
  treatment: "glass",
46
53
  glow: !0,
47
54
  className: "border-border-seam p-5",
48
- children: [/* @__PURE__ */ _("h2", {
55
+ children: [/* @__PURE__ */ b("h2", {
49
56
  className: "mb-4 text-lg font-medium tracking-tight text-text-primary",
50
- children: y("ggnomad.activity.details", "Details")
51
- }), /* @__PURE__ */ v("dl", {
57
+ children: S("ggnomad.activity.details", "Details")
58
+ }), /* @__PURE__ */ x("dl", {
52
59
  className: "space-y-2 text-sm",
53
60
  children: [
54
- /* @__PURE__ */ _(r, {
55
- label: y("ggnomad.activity.category", "Category"),
56
- value: C.category
61
+ /* @__PURE__ */ b(r, {
62
+ label: S("ggnomad.activity.category", "Category"),
63
+ value: D.category
57
64
  }),
58
- /* @__PURE__ */ _(r, {
59
- label: y("ggnomad.activity.duration", "Duration"),
60
- value: C.duration
65
+ /* @__PURE__ */ b(r, {
66
+ label: S("ggnomad.activity.duration", "Duration"),
67
+ value: D.duration
61
68
  }),
62
- /* @__PURE__ */ _(r, {
63
- label: y("ggnomad.activity.maxParticipants", "Max participants"),
64
- value: String(C.maxParticipants)
69
+ /* @__PURE__ */ b(r, {
70
+ label: S("ggnomad.activity.maxParticipants", "Max participants"),
71
+ value: String(D.maxParticipants)
65
72
  }),
66
- /* @__PURE__ */ _(r, {
67
- label: y("ggnomad.activity.price", "Price"),
68
- value: `${C.currency} ${Number(C.price).toFixed(2)}`
73
+ /* @__PURE__ */ b(r, {
74
+ label: S("ggnomad.activity.price", "Price"),
75
+ value: `${D.currency} ${Number(D.price).toFixed(2)}`
69
76
  })
70
77
  ]
71
78
  })]
72
- }), /* @__PURE__ */ _(n, {
73
- title: y("ggnomad.activity.safety", "Safety information"),
74
- children: /* @__PURE__ */ v("div", {
79
+ }), /* @__PURE__ */ b(n, {
80
+ title: S("ggnomad.activity.safety", "Safety information"),
81
+ children: /* @__PURE__ */ x("div", {
75
82
  className: "flex items-start gap-2 text-sm text-text-primary",
76
- children: [/* @__PURE__ */ _(s, {
83
+ children: [/* @__PURE__ */ b(u, {
77
84
  className: "mt-0.5 size-4 flex-shrink-0 text-status-success-text",
78
85
  "aria-hidden": "true"
79
- }), /* @__PURE__ */ _("p", { children: C.safetyInfo ?? y("ggnomad.activity.defaultSafety", "Standard provider safety policy applies.") })]
86
+ }), /* @__PURE__ */ b("p", { children: D.safetyInfo ?? S("ggnomad.activity.defaultSafety", "Standard provider safety policy applies.") })]
80
87
  })
81
88
  })]
82
89
  })
83
- ] }) : /* @__PURE__ */ _(p, {
90
+ ] }) : /* @__PURE__ */ b(g, {
84
91
  illustration: "empty-data",
85
- title: y("ggnomad.activity.notFoundTitle", "No activity found"),
86
- description: y("ggnomad.activity.notFoundDescription", "This activity is unavailable or may have been removed.")
92
+ title: S("ggnomad.activity.notFoundTitle", "No activity found"),
93
+ description: S("ggnomad.activity.notFoundDescription", "This activity is unavailable or may have been removed.")
87
94
  })
88
95
  });
89
96
  }
90
97
  //#endregion
91
- export { y as ActivityDetailsPage };
98
+ export { S as ActivityDetailsPage };
92
99
 
93
100
  //# sourceMappingURL=ActivityDetailsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ActivityDetailsPage.js","names":[],"sources":["../../../src/ggnomad/pages/ActivityDetailsPage.tsx"],"sourcesContent":["import { useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { Activity, CalendarCheck, Compass, ShieldCheck } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, NextSteps, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_ACTIVITY_QUERY } from '../graphql';\nimport { PageShell } from './PageShell';\nimport { DetailRow, SectionCard } from '../components';\n\nexport function ActivityDetailsPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { id = '' } = useParams();\n const { data } = useQuery(\n GGNOMAD_ACTIVITY_QUERY as TypedDocumentNode<\n {\n ggnomadActivity: {\n name: string;\n category: string;\n duration: string;\n maxParticipants: number;\n currency: string;\n price: number;\n safetyInfo?: string;\n } | null;\n },\n { id: string }\n >,\n { variables: { id }, skip: !id }\n );\n const activity = data?.ggnomadActivity;\n\n return (\n <PageShell\n title={activity?.name ?? t('ggnomad.activity.fallbackTitle', 'Activity details')}\n subtitle={t('ggnomad.activity.subtitle', 'Safety, inclusions and participation details')}\n >\n {!activity ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.activity.notFoundTitle', 'No activity found')}\n description={t(\n 'ggnomad.activity.notFoundDescription',\n 'This activity is unavailable or may have been removed.'\n )}\n />\n ) : (\n <>\n <PagePurpose icon={<Activity className=\"size-4\" />}>\n {t(\n 'ggnomad.activity.purpose',\n 'Everything you need to know before joining this activity — its category, duration, group size, price and the safety policy that applies — so you can be confident it fits your group before you book.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"ggnomad-activity-detail\"\n steps={[\n {\n id: 'book',\n label: t('ggnomad.activity.next.book', 'Book this activity'),\n description: t(\n 'ggnomad.activity.next.bookDesc',\n 'Add it to your itinerary and track it under Bookings.'\n ),\n icon: <CalendarCheck className=\"size-4\" />,\n onClick: () => navigate('../../../bookings'),\n },\n {\n id: 'browse',\n label: t('ggnomad.activity.next.browse', 'Explore more experiences'),\n description: t(\n 'ggnomad.activity.next.browseDesc',\n 'Return to Tourism to compare tours and activities.'\n ),\n icon: <Compass className=\"size-4\" />,\n onClick: () => navigate('../..'),\n },\n ]}\n />\n\n <div className=\"grid gap-4 lg:grid-cols-2\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-5\">\n <h2 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.activity.details', 'Details')}\n </h2>\n <dl className=\"space-y-2 text-sm\">\n <DetailRow\n label={t('ggnomad.activity.category', 'Category')}\n value={activity.category}\n />\n <DetailRow\n label={t('ggnomad.activity.duration', 'Duration')}\n value={activity.duration}\n />\n <DetailRow\n label={t('ggnomad.activity.maxParticipants', 'Max participants')}\n value={String(activity.maxParticipants)}\n />\n <DetailRow\n label={t('ggnomad.activity.price', 'Price')}\n value={`${activity.currency} ${Number(activity.price).toFixed(2)}`}\n />\n </dl>\n </GlassCard>\n <SectionCard title={t('ggnomad.activity.safety', 'Safety information')}>\n <div className=\"flex items-start gap-2 text-sm text-text-primary\">\n <ShieldCheck\n className=\"mt-0.5 size-4 flex-shrink-0 text-status-success-text\"\n aria-hidden=\"true\"\n />\n <p>\n {activity.safetyInfo ??\n t('ggnomad.activity.defaultSafety', 'Standard provider safety policy applies.')}\n </p>\n </div>\n </SectionCard>\n </div>\n </>\n )}\n </PageShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAWA,SAAgB,IAAsB;CACpC,IAAM,EAAE,SAAM,GAAS,EACjB,IAAW,GAAa,EACxB,EAAE,QAAK,OAAO,GAAW,EACzB,EAAE,YAAS,EACf,GAcA;EAAE,WAAW,EAAE,OAAI;EAAE,MAAM,CAAC;EAAI,CACjC,EACK,IAAW,GAAM;AAEvB,QACE,kBAAC,GAAD;EACE,OAAO,GAAU,QAAQ,EAAE,kCAAkC,mBAAmB;EAChF,UAAU,EAAE,6BAA6B,+CAA+C;YAEtF,IAUA,kBAAA,GAAA,EAAA,UAAA;GACE,kBAAC,GAAD;IAAa,MAAM,kBAAC,GAAD,EAAU,WAAU,UAAW,CAAA;cAC/C,EACC,4BACA,wMACD;IACW,CAAA;GAEd,kBAAC,GAAD;IACE,YAAW;IACX,OAAO,CACL;KACE,IAAI;KACJ,OAAO,EAAE,8BAA8B,qBAAqB;KAC5D,aAAa,EACX,kCACA,wDACD;KACD,MAAM,kBAAC,GAAD,EAAe,WAAU,UAAW,CAAA;KAC1C,eAAe,EAAS,oBAAoB;KAC7C,EACD;KACE,IAAI;KACJ,OAAO,EAAE,gCAAgC,2BAA2B;KACpE,aAAa,EACX,oCACA,qDACD;KACD,MAAM,kBAAC,GAAD,EAAS,WAAU,UAAW,CAAA;KACpC,eAAe,EAAS,QAAQ;KACjC,CACF;IACD,CAAA;GAEF,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAW,WAAU;KAAQ,MAAA;KAAK,WAAU;eAA5C,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAE,4BAA4B,UAAU;MACtC,CAAA,EACL,kBAAC,MAAD;MAAI,WAAU;gBAAd;OACE,kBAAC,GAAD;QACE,OAAO,EAAE,6BAA6B,WAAW;QACjD,OAAO,EAAS;QAChB,CAAA;OACF,kBAAC,GAAD;QACE,OAAO,EAAE,6BAA6B,WAAW;QACjD,OAAO,EAAS;QAChB,CAAA;OACF,kBAAC,GAAD;QACE,OAAO,EAAE,oCAAoC,mBAAmB;QAChE,OAAO,OAAO,EAAS,gBAAgB;QACvC,CAAA;OACF,kBAAC,GAAD;QACE,OAAO,EAAE,0BAA0B,QAAQ;QAC3C,OAAO,GAAG,EAAS,SAAS,GAAG,OAAO,EAAS,MAAM,CAAC,QAAQ,EAAE;QAChE,CAAA;OACC;QACK;QACZ,kBAAC,GAAD;KAAa,OAAO,EAAE,2BAA2B,qBAAqB;eACpE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD;OACE,WAAU;OACV,eAAY;OACZ,CAAA,EACF,kBAAC,KAAD,EAAA,UACG,EAAS,cACR,EAAE,kCAAkC,2CAA2C,EAC/E,CAAA,CACA;;KACM,CAAA,CACV;;GACL,EAAA,CAAA,GAhFH,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,kCAAkC,oBAAoB;GAC/D,aAAa,EACX,wCACA,yDACD;GACD,CAAA;EA2EM,CAAA"}
1
+ {"version":3,"file":"ActivityDetailsPage.js","names":[],"sources":["../../../src/ggnomad/pages/ActivityDetailsPage.tsx"],"sourcesContent":["import { useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { Activity, CalendarCheck, Compass, ShieldCheck } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, NextSteps, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_ACTIVITY_QUERY } from '../graphql';\nimport { useGGNomad } from '../providers/GGNomadProvider';\nimport { joinPath } from '../utils/navigation';\nimport { PageShell } from './PageShell';\nimport { DetailRow, SectionCard, DetailHero } from '../components';\n\nexport function ActivityDetailsPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { basePath = '/' } = useGGNomad();\n const { id = '' } = useParams();\n const { data } = useQuery(\n GGNOMAD_ACTIVITY_QUERY as TypedDocumentNode<\n {\n ggnomadActivity: {\n name: string;\n category: string;\n duration: string;\n maxParticipants: number;\n currency: string;\n price: number;\n safetyInfo?: string;\n images?: string[];\n } | null;\n },\n { id: string }\n >,\n { variables: { id }, skip: !id }\n );\n const activity = data?.ggnomadActivity;\n\n return (\n <PageShell\n title={activity?.name ?? t('ggnomad.activity.fallbackTitle', 'Activity details')}\n subtitle={t('ggnomad.activity.subtitle', 'Safety, inclusions and participation details')}\n >\n {!activity ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.activity.notFoundTitle', 'No activity found')}\n description={t(\n 'ggnomad.activity.notFoundDescription',\n 'This activity is unavailable or may have been removed.'\n )}\n />\n ) : (\n <>\n <DetailHero image={activity.images?.[0]} alt={activity.name} />\n <PagePurpose icon={<Activity className=\"size-4\" />}>\n {t(\n 'ggnomad.activity.purpose',\n 'Everything you need to know before joining this activity — its category, duration, group size, price and the safety policy that applies — so you can be confident it fits your group before you book.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"ggnomad-activity-detail\"\n steps={[\n {\n id: 'book',\n label: t('ggnomad.activity.next.book', 'Book this activity'),\n description: t(\n 'ggnomad.activity.next.bookDesc',\n 'Add it to your itinerary and track it under Bookings.'\n ),\n icon: <CalendarCheck className=\"size-4\" />,\n onClick: () => navigate(joinPath(basePath, 'bookings')),\n },\n {\n id: 'browse',\n label: t('ggnomad.activity.next.browse', 'Explore more experiences'),\n description: t(\n 'ggnomad.activity.next.browseDesc',\n 'Return to Tourism to compare tours and activities.'\n ),\n icon: <Compass className=\"size-4\" />,\n onClick: () => navigate(joinPath(basePath, 'tourism')),\n },\n ]}\n />\n\n <div className=\"grid gap-4 lg:grid-cols-2\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-5\">\n <h2 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.activity.details', 'Details')}\n </h2>\n <dl className=\"space-y-2 text-sm\">\n <DetailRow\n label={t('ggnomad.activity.category', 'Category')}\n value={activity.category}\n />\n <DetailRow\n label={t('ggnomad.activity.duration', 'Duration')}\n value={activity.duration}\n />\n <DetailRow\n label={t('ggnomad.activity.maxParticipants', 'Max participants')}\n value={String(activity.maxParticipants)}\n />\n <DetailRow\n label={t('ggnomad.activity.price', 'Price')}\n value={`${activity.currency} ${Number(activity.price).toFixed(2)}`}\n />\n </dl>\n </GlassCard>\n <SectionCard title={t('ggnomad.activity.safety', 'Safety information')}>\n <div className=\"flex items-start gap-2 text-sm text-text-primary\">\n <ShieldCheck\n className=\"mt-0.5 size-4 flex-shrink-0 text-status-success-text\"\n aria-hidden=\"true\"\n />\n <p>\n {activity.safetyInfo ??\n t('ggnomad.activity.defaultSafety', 'Standard provider safety policy applies.')}\n </p>\n </div>\n </SectionCard>\n </div>\n </>\n )}\n </PageShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAaA,SAAgB,IAAsB;CACpC,IAAM,EAAE,SAAM,GAAS,EACjB,IAAW,GAAa,EACxB,EAAE,cAAW,QAAQ,GAAY,EACjC,EAAE,QAAK,OAAO,GAAW,EACzB,EAAE,YAAS,EACf,GAeA;EAAE,WAAW,EAAE,OAAI;EAAE,MAAM,CAAC;EAAI,CACjC,EACK,IAAW,GAAM;AAEvB,QACE,kBAAC,GAAD;EACE,OAAO,GAAU,QAAQ,EAAE,kCAAkC,mBAAmB;EAChF,UAAU,EAAE,6BAA6B,+CAA+C;YAEtF,IAUA,kBAAA,GAAA,EAAA,UAAA;GACE,kBAAC,GAAD;IAAY,OAAO,EAAS,SAAS;IAAI,KAAK,EAAS;IAAQ,CAAA;GAC/D,kBAAC,GAAD;IAAa,MAAM,kBAAC,GAAD,EAAU,WAAU,UAAW,CAAA;cAC/C,EACC,4BACA,wMACD;IACW,CAAA;GAEd,kBAAC,GAAD;IACE,YAAW;IACX,OAAO,CACL;KACE,IAAI;KACJ,OAAO,EAAE,8BAA8B,qBAAqB;KAC5D,aAAa,EACX,kCACA,wDACD;KACD,MAAM,kBAAC,GAAD,EAAe,WAAU,UAAW,CAAA;KAC1C,eAAe,EAAS,EAAS,GAAU,WAAW,CAAC;KACxD,EACD;KACE,IAAI;KACJ,OAAO,EAAE,gCAAgC,2BAA2B;KACpE,aAAa,EACX,oCACA,qDACD;KACD,MAAM,kBAAC,GAAD,EAAS,WAAU,UAAW,CAAA;KACpC,eAAe,EAAS,EAAS,GAAU,UAAU,CAAC;KACvD,CACF;IACD,CAAA;GAEF,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAW,WAAU;KAAQ,MAAA;KAAK,WAAU;eAA5C,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAE,4BAA4B,UAAU;MACtC,CAAA,EACL,kBAAC,MAAD;MAAI,WAAU;gBAAd;OACE,kBAAC,GAAD;QACE,OAAO,EAAE,6BAA6B,WAAW;QACjD,OAAO,EAAS;QAChB,CAAA;OACF,kBAAC,GAAD;QACE,OAAO,EAAE,6BAA6B,WAAW;QACjD,OAAO,EAAS;QAChB,CAAA;OACF,kBAAC,GAAD;QACE,OAAO,EAAE,oCAAoC,mBAAmB;QAChE,OAAO,OAAO,EAAS,gBAAgB;QACvC,CAAA;OACF,kBAAC,GAAD;QACE,OAAO,EAAE,0BAA0B,QAAQ;QAC3C,OAAO,GAAG,EAAS,SAAS,GAAG,OAAO,EAAS,MAAM,CAAC,QAAQ,EAAE;QAChE,CAAA;OACC;QACK;QACZ,kBAAC,GAAD;KAAa,OAAO,EAAE,2BAA2B,qBAAqB;eACpE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD;OACE,WAAU;OACV,eAAY;OACZ,CAAA,EACF,kBAAC,KAAD,EAAA,UACG,EAAS,cACR,EAAE,kCAAkC,2CAA2C,EAC/E,CAAA,CACA;;KACM,CAAA,CACV;;GACL,EAAA,CAAA,GAjFH,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,kCAAkC,oBAAoB;GAC/D,aAAa,EACX,wCACA,yDACD;GACD,CAAA;EA4EM,CAAA"}
@@ -1,50 +1,61 @@
1
1
  import { GGNOMAD_EVENTS_QUERY as e } from "../graphql.js";
2
2
  import { PageShell as t } from "./PageShell.js";
3
3
  import { EntityCard as n } from "../components/EntityCard.js";
4
+ import { LoadMoreButton as r } from "../components/LoadMoreButton.js";
4
5
  import "../components/index.js";
5
- import { Ticket as r } from "lucide-react";
6
- import { useI18n as i } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
7
- import { useQuery as a } from "@apollo/client/react";
8
- import { GlassCard as o, IllustratedEmptyState as s, PagePurpose as c } from "@burdenoff/fe-libs/ui";
9
- import { jsx as l, jsxs as u } from "react/jsx-runtime";
6
+ import { useState as i } from "react";
7
+ import { Ticket as a } from "lucide-react";
8
+ import { useI18n as o } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
9
+ import { useQuery as s } from "@apollo/client/react";
10
+ import { GlassCard as c, IllustratedEmptyState as l, PagePurpose as u } from "@burdenoff/fe-libs/ui";
11
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
10
12
  //#region src/ggnomad/pages/EntertainmentPage.tsx
11
- function d() {
12
- let { t: d } = i(), { data: f } = a(e, { variables: {
13
- first: 20,
13
+ function p() {
14
+ let { t: p } = o(), [m, h] = i(12), { data: g } = s(e, { variables: {
15
+ first: m,
14
16
  skip: 0
15
- } }), p = f?.ggnomadEvents ?? [];
16
- return /* @__PURE__ */ u(t, {
17
- title: d("ggnomad.entertainment.title", "Entertainment"),
18
- titleAccent: d("ggnomad.entertainment.title.accent", "Entertainment"),
19
- subtitle: d("ggnomad.entertainment.subtitle", "Events and live experiences"),
20
- children: [/* @__PURE__ */ l(c, {
21
- icon: /* @__PURE__ */ l(r, { className: "size-4" }),
22
- children: d("ggnomad.entertainment.purpose", "Find live events and experiences — concerts, shows and local happenings. Open an event to see its lineup, venue and timing, then book tickets for your trip dates.")
23
- }), p.length === 0 ? /* @__PURE__ */ l(s, {
17
+ } }), _ = g?.ggnomadEvents ?? [];
18
+ return /* @__PURE__ */ f(t, {
19
+ title: p("ggnomad.entertainment.title", "Entertainment"),
20
+ titleAccent: p("ggnomad.entertainment.title.accent", "Entertainment"),
21
+ subtitle: p("ggnomad.entertainment.subtitle", "Events and live experiences"),
22
+ children: [/* @__PURE__ */ d(u, {
23
+ icon: /* @__PURE__ */ d(a, { className: "size-4" }),
24
+ children: p("ggnomad.entertainment.purpose", "Find live events and experiences — concerts, shows and local happenings. Open an event to see its lineup, venue and timing, then book tickets for your trip dates.")
25
+ }), _.length === 0 ? /* @__PURE__ */ d(l, {
24
26
  illustration: "empty-data",
25
- title: d("ggnomad.entertainment.emptyTitle", "No events scheduled"),
26
- description: d("ggnomad.entertainment.emptyDescription", "Upcoming events and live experiences will be listed here.")
27
- }) : /* @__PURE__ */ u(o, {
27
+ title: p("ggnomad.entertainment.emptyTitle", "No events scheduled"),
28
+ description: p("ggnomad.entertainment.emptyDescription", "Upcoming events and live experiences will be listed here.")
29
+ }) : /* @__PURE__ */ f(c, {
28
30
  treatment: "glass",
29
31
  glow: !0,
30
32
  className: "border-border-seam p-5",
31
- children: [/* @__PURE__ */ l("h2", {
32
- className: "mb-4 text-lg font-medium tracking-tight text-text-primary",
33
- children: d("ggnomad.entertainment.upcomingEvents", "Upcoming events")
34
- }), /* @__PURE__ */ l("div", {
35
- className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3",
36
- children: p.map((e) => /* @__PURE__ */ l(n, {
37
- to: e.id,
38
- title: e.name,
39
- meta: e.category,
40
- price: `${e.currency} ${Number(e.price).toFixed(2)}`,
41
- footer: new Date(e.startsAt).toLocaleString()
42
- }, e.id))
43
- })]
33
+ children: [
34
+ /* @__PURE__ */ d("h2", {
35
+ className: "mb-4 text-lg font-medium tracking-tight text-text-primary",
36
+ children: p("ggnomad.entertainment.upcomingEvents", "Upcoming events")
37
+ }),
38
+ /* @__PURE__ */ d("div", {
39
+ className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3",
40
+ children: _.map((e) => /* @__PURE__ */ d(n, {
41
+ to: e.id,
42
+ image: e.images?.[0],
43
+ imageAlt: e.name,
44
+ title: e.name,
45
+ meta: e.category,
46
+ price: `${e.currency} ${Number(e.price).toFixed(2)}`,
47
+ footer: new Date(e.startsAt).toLocaleString()
48
+ }, e.id))
49
+ }),
50
+ /* @__PURE__ */ d(r, {
51
+ visible: _.length >= m,
52
+ onLoadMore: () => h((e) => e + 12)
53
+ })
54
+ ]
44
55
  })]
45
56
  });
46
57
  }
47
58
  //#endregion
48
- export { d as EntertainmentPage };
59
+ export { p as EntertainmentPage };
49
60
 
50
61
  //# sourceMappingURL=EntertainmentPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EntertainmentPage.js","names":[],"sources":["../../../src/ggnomad/pages/EntertainmentPage.tsx"],"sourcesContent":["import { useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Ticket } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_EVENTS_QUERY } from '../graphql';\nimport { PageShell } from './PageShell';\nimport { EntityCard } from '../components';\n\nexport function EntertainmentPage() {\n const { t } = useI18n();\n const { data } = useQuery(\n GGNOMAD_EVENTS_QUERY as TypedDocumentNode<\n {\n ggnomadEvents: Array<{\n id: string;\n name: string;\n category: string;\n startsAt: string;\n price: number;\n currency: string;\n }>;\n },\n { first: number; skip: number }\n >,\n { variables: { first: 20, skip: 0 } }\n );\n const events = data?.ggnomadEvents ?? [];\n\n return (\n <PageShell\n title={t('ggnomad.entertainment.title', 'Entertainment')}\n titleAccent={t('ggnomad.entertainment.title.accent', 'Entertainment')}\n subtitle={t('ggnomad.entertainment.subtitle', 'Events and live experiences')}\n >\n <PagePurpose icon={<Ticket className=\"size-4\" />}>\n {t(\n 'ggnomad.entertainment.purpose',\n 'Find live events and experiences — concerts, shows and local happenings. Open an event to see its lineup, venue and timing, then book tickets for your trip dates.'\n )}\n </PagePurpose>\n\n {events.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.entertainment.emptyTitle', 'No events scheduled')}\n description={t(\n 'ggnomad.entertainment.emptyDescription',\n 'Upcoming events and live experiences will be listed here.'\n )}\n />\n ) : (\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-5\">\n <h2 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.entertainment.upcomingEvents', 'Upcoming events')}\n </h2>\n <div className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {events.map((event) => (\n <EntityCard\n key={event.id}\n to={event.id}\n title={event.name}\n meta={event.category}\n price={`${event.currency} ${Number(event.price).toFixed(2)}`}\n footer={new Date(event.startsAt).toLocaleString()}\n />\n ))}\n </div>\n </GlassCard>\n )}\n </PageShell>\n );\n}\n"],"mappings":";;;;;;;;;;AAUA,SAAgB,IAAoB;CAClC,IAAM,EAAE,SAAM,GAAS,EACjB,EAAE,YAAS,EACf,GAaA,EAAE,WAAW;EAAE,OAAO;EAAI,MAAM;EAAG,EAAE,CACtC,EACK,IAAS,GAAM,iBAAiB,EAAE;AAExC,QACE,kBAAC,GAAD;EACE,OAAO,EAAE,+BAA+B,gBAAgB;EACxD,aAAa,EAAE,sCAAsC,gBAAgB;EACrE,UAAU,EAAE,kCAAkC,8BAA8B;YAH9E,CAKE,kBAAC,GAAD;GAAa,MAAM,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA;aAC7C,EACC,iCACA,qKACD;GACW,CAAA,EAEb,EAAO,WAAW,IACjB,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,oCAAoC,sBAAsB;GACnE,aAAa,EACX,0CACA,4DACD;GACD,CAAA,GAEF,kBAAC,GAAD;GAAW,WAAU;GAAQ,MAAA;GAAK,WAAU;aAA5C,CACE,kBAAC,MAAD;IAAI,WAAU;cACX,EAAE,wCAAwC,kBAAkB;IAC1D,CAAA,EACL,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAO,KAAK,MACX,kBAAC,GAAD;KAEE,IAAI,EAAM;KACV,OAAO,EAAM;KACb,MAAM,EAAM;KACZ,OAAO,GAAG,EAAM,SAAS,GAAG,OAAO,EAAM,MAAM,CAAC,QAAQ,EAAE;KAC1D,QAAQ,IAAI,KAAK,EAAM,SAAS,CAAC,gBAAgB;KACjD,EANK,EAAM,GAMX,CACF;IACE,CAAA,CACI;KAEJ"}
1
+ {"version":3,"file":"EntertainmentPage.js","names":[],"sources":["../../../src/ggnomad/pages/EntertainmentPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Ticket } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_EVENTS_QUERY } from '../graphql';\nimport { PageShell } from './PageShell';\nimport { EntityCard, LoadMoreButton } from '../components';\n\nexport function EntertainmentPage() {\n const { t } = useI18n();\n const [limit, setLimit] = useState(12);\n const { data } = useQuery(\n GGNOMAD_EVENTS_QUERY as TypedDocumentNode<\n {\n ggnomadEvents: Array<{\n id: string;\n name: string;\n category: string;\n startsAt: string;\n price: number;\n currency: string;\n images?: string[];\n }>;\n },\n { first: number; skip: number }\n >,\n { variables: { first: limit, skip: 0 } }\n );\n const events = data?.ggnomadEvents ?? [];\n\n return (\n <PageShell\n title={t('ggnomad.entertainment.title', 'Entertainment')}\n titleAccent={t('ggnomad.entertainment.title.accent', 'Entertainment')}\n subtitle={t('ggnomad.entertainment.subtitle', 'Events and live experiences')}\n >\n <PagePurpose icon={<Ticket className=\"size-4\" />}>\n {t(\n 'ggnomad.entertainment.purpose',\n 'Find live events and experiences — concerts, shows and local happenings. Open an event to see its lineup, venue and timing, then book tickets for your trip dates.'\n )}\n </PagePurpose>\n\n {events.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.entertainment.emptyTitle', 'No events scheduled')}\n description={t(\n 'ggnomad.entertainment.emptyDescription',\n 'Upcoming events and live experiences will be listed here.'\n )}\n />\n ) : (\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-5\">\n <h2 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.entertainment.upcomingEvents', 'Upcoming events')}\n </h2>\n <div className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {events.map((event) => (\n <EntityCard\n key={event.id}\n to={event.id}\n image={event.images?.[0]}\n imageAlt={event.name}\n title={event.name}\n meta={event.category}\n price={`${event.currency} ${Number(event.price).toFixed(2)}`}\n footer={new Date(event.startsAt).toLocaleString()}\n />\n ))}\n </div>\n <LoadMoreButton\n visible={events.length >= limit}\n onLoadMore={() => setLimit((l) => l + 12)}\n />\n </GlassCard>\n )}\n </PageShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAWA,SAAgB,IAAoB;CAClC,IAAM,EAAE,SAAM,GAAS,EACjB,CAAC,GAAO,KAAY,EAAS,GAAG,EAChC,EAAE,YAAS,EACf,GAcA,EAAE,WAAW;EAAE,OAAO;EAAO,MAAM;EAAG,EAAE,CACzC,EACK,IAAS,GAAM,iBAAiB,EAAE;AAExC,QACE,kBAAC,GAAD;EACE,OAAO,EAAE,+BAA+B,gBAAgB;EACxD,aAAa,EAAE,sCAAsC,gBAAgB;EACrE,UAAU,EAAE,kCAAkC,8BAA8B;YAH9E,CAKE,kBAAC,GAAD;GAAa,MAAM,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA;aAC7C,EACC,iCACA,qKACD;GACW,CAAA,EAEb,EAAO,WAAW,IACjB,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,oCAAoC,sBAAsB;GACnE,aAAa,EACX,0CACA,4DACD;GACD,CAAA,GAEF,kBAAC,GAAD;GAAW,WAAU;GAAQ,MAAA;GAAK,WAAU;aAA5C;IACE,kBAAC,MAAD;KAAI,WAAU;eACX,EAAE,wCAAwC,kBAAkB;KAC1D,CAAA;IACL,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAO,KAAK,MACX,kBAAC,GAAD;MAEE,IAAI,EAAM;MACV,OAAO,EAAM,SAAS;MACtB,UAAU,EAAM;MAChB,OAAO,EAAM;MACb,MAAM,EAAM;MACZ,OAAO,GAAG,EAAM,SAAS,GAAG,OAAO,EAAM,MAAM,CAAC,QAAQ,EAAE;MAC1D,QAAQ,IAAI,KAAK,EAAM,SAAS,CAAC,gBAAgB;MACjD,EARK,EAAM,GAQX,CACF;KACE,CAAA;IACN,kBAAC,GAAD;KACE,SAAS,EAAO,UAAU;KAC1B,kBAAkB,GAAU,MAAM,IAAI,GAAG;KACzC,CAAA;IACQ;KAEJ"}