@burdenoff/microfe-ggnomad 2026.705.1 → 2026.705.3
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/dist/ggnomad/GGNomadRoot.js +14 -14
- package/dist/ggnomad/components/BookingPanel.js +219 -0
- package/dist/ggnomad/components/BookingPanel.js.map +1 -0
- package/dist/ggnomad/components/DetailHero.js +22 -0
- package/dist/ggnomad/components/DetailHero.js.map +1 -0
- package/dist/ggnomad/components/EntityCard.js +36 -22
- package/dist/ggnomad/components/EntityCard.js.map +1 -1
- package/dist/ggnomad/components/index.js +2 -0
- package/dist/ggnomad/graphql.js +12 -1
- package/dist/ggnomad/graphql.js.map +1 -1
- package/dist/ggnomad/pages/ActivityDetailsPage.js +83 -74
- package/dist/ggnomad/pages/ActivityDetailsPage.js.map +1 -1
- package/dist/ggnomad/pages/BookingsPage.js +1 -1
- package/dist/ggnomad/pages/EntertainmentPage.js +2 -0
- package/dist/ggnomad/pages/EntertainmentPage.js.map +1 -1
- package/dist/ggnomad/pages/EventDetailsPage.js +87 -77
- package/dist/ggnomad/pages/EventDetailsPage.js.map +1 -1
- package/dist/ggnomad/pages/FavoritesPage.js +1 -1
- package/dist/ggnomad/pages/HospitalityPage.js +2 -0
- package/dist/ggnomad/pages/HospitalityPage.js.map +1 -1
- package/dist/ggnomad/pages/PropertyDetailsPage.js +89 -79
- package/dist/ggnomad/pages/PropertyDetailsPage.js.map +1 -1
- package/dist/ggnomad/pages/TourDetailsPage.js +86 -77
- package/dist/ggnomad/pages/TourDetailsPage.js.map +1 -1
- package/dist/ggnomad/pages/TourismPage.js +2 -0
- package/dist/ggnomad/pages/TourismPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,94 +2,103 @@ 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";
|
|
6
|
+
import { useGGNomad as a } from "../providers/GGNomadProvider.js";
|
|
7
|
+
import { joinPath as o } from "../utils/navigation.js";
|
|
8
|
+
import { BookingPanel as s } from "../components/BookingPanel.js";
|
|
5
9
|
import "../components/index.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { GlassCard as m, IllustratedEmptyState as h, NextSteps as g, PagePurpose as _ } from "@burdenoff/fe-libs/ui";
|
|
13
|
-
import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
10
|
+
import { Activity as c, Compass as l, ShieldCheck as u } from "lucide-react";
|
|
11
|
+
import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
12
|
+
import { useNavigate as f, useParams as p } from "react-router-dom";
|
|
13
|
+
import { useQuery as m } from "@apollo/client/react";
|
|
14
|
+
import { GlassCard as h, IllustratedEmptyState as g, NextSteps as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
|
|
15
|
+
import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
|
|
14
16
|
//#region src/ggnomad/pages/ActivityDetailsPage.tsx
|
|
15
|
-
function
|
|
16
|
-
let { t:
|
|
17
|
-
variables: { id:
|
|
18
|
-
skip: !
|
|
19
|
-
}),
|
|
20
|
-
return /* @__PURE__ */
|
|
21
|
-
title:
|
|
22
|
-
subtitle:
|
|
23
|
-
children:
|
|
24
|
-
/* @__PURE__ */
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
function S() {
|
|
18
|
+
let { t: S } = d(), C = f(), { basePath: w = "/" } = a(), { id: T = "" } = p(), { data: E } = m(e, {
|
|
19
|
+
variables: { id: T },
|
|
20
|
+
skip: !T
|
|
21
|
+
}), D = E?.ggnomadActivity;
|
|
22
|
+
return /* @__PURE__ */ b(t, {
|
|
23
|
+
title: D?.name ?? S("ggnomad.activity.fallbackTitle", "Activity details"),
|
|
24
|
+
subtitle: S("ggnomad.activity.subtitle", "Safety, inclusions and participation details"),
|
|
25
|
+
children: D ? /* @__PURE__ */ x(y, { children: [
|
|
26
|
+
/* @__PURE__ */ b(i, {
|
|
27
|
+
image: D.images?.[0],
|
|
28
|
+
alt: D.name
|
|
27
29
|
}),
|
|
28
|
-
/* @__PURE__ */
|
|
30
|
+
/* @__PURE__ */ b(v, {
|
|
31
|
+
icon: /* @__PURE__ */ b(c, { className: "size-4" }),
|
|
32
|
+
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.")
|
|
33
|
+
}),
|
|
34
|
+
/* @__PURE__ */ b(_, {
|
|
29
35
|
storageKey: "ggnomad-activity-detail",
|
|
30
36
|
steps: [{
|
|
31
|
-
id: "book",
|
|
32
|
-
label: x("ggnomad.activity.next.book", "Book this activity"),
|
|
33
|
-
description: x("ggnomad.activity.next.bookDesc", "Add it to your itinerary and track it under Bookings."),
|
|
34
|
-
icon: /* @__PURE__ */ y(s, { className: "size-4" }),
|
|
35
|
-
onClick: () => S(a(C, "bookings"))
|
|
36
|
-
}, {
|
|
37
37
|
id: "browse",
|
|
38
|
-
label:
|
|
39
|
-
description:
|
|
40
|
-
icon: /* @__PURE__ */
|
|
41
|
-
onClick: () =>
|
|
38
|
+
label: S("ggnomad.activity.next.browse", "Explore more experiences"),
|
|
39
|
+
description: S("ggnomad.activity.next.browseDesc", "Return to Tourism to compare tours and activities."),
|
|
40
|
+
icon: /* @__PURE__ */ b(l, { className: "size-4" }),
|
|
41
|
+
onClick: () => C(o(w, "tourism"))
|
|
42
42
|
}]
|
|
43
43
|
}),
|
|
44
|
-
/* @__PURE__ */
|
|
45
|
-
className: "grid gap-4 lg:grid-cols-
|
|
46
|
-
children: [/* @__PURE__ */
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
className: "
|
|
52
|
-
children:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
44
|
+
/* @__PURE__ */ x("div", {
|
|
45
|
+
className: "grid gap-4 lg:grid-cols-3",
|
|
46
|
+
children: [/* @__PURE__ */ x("div", {
|
|
47
|
+
className: "lg:col-span-2 space-y-4",
|
|
48
|
+
children: [/* @__PURE__ */ x(h, {
|
|
49
|
+
treatment: "glass",
|
|
50
|
+
glow: !0,
|
|
51
|
+
className: "border-border-seam p-5",
|
|
52
|
+
children: [/* @__PURE__ */ b("h2", {
|
|
53
|
+
className: "mb-4 text-lg font-medium tracking-tight text-text-primary",
|
|
54
|
+
children: S("ggnomad.activity.details", "Details")
|
|
55
|
+
}), /* @__PURE__ */ x("dl", {
|
|
56
|
+
className: "space-y-2 text-sm",
|
|
57
|
+
children: [
|
|
58
|
+
/* @__PURE__ */ b(r, {
|
|
59
|
+
label: S("ggnomad.activity.category", "Category"),
|
|
60
|
+
value: D.category
|
|
61
|
+
}),
|
|
62
|
+
/* @__PURE__ */ b(r, {
|
|
63
|
+
label: S("ggnomad.activity.duration", "Duration"),
|
|
64
|
+
value: D.duration
|
|
65
|
+
}),
|
|
66
|
+
/* @__PURE__ */ b(r, {
|
|
67
|
+
label: S("ggnomad.activity.maxParticipants", "Max participants"),
|
|
68
|
+
value: String(D.maxParticipants)
|
|
69
|
+
}),
|
|
70
|
+
/* @__PURE__ */ b(r, {
|
|
71
|
+
label: S("ggnomad.activity.price", "Price"),
|
|
72
|
+
value: `${D.currency} ${Number(D.price).toFixed(2)}`
|
|
73
|
+
})
|
|
74
|
+
]
|
|
75
|
+
})]
|
|
76
|
+
}), /* @__PURE__ */ b(n, {
|
|
77
|
+
title: S("ggnomad.activity.safety", "Safety information"),
|
|
78
|
+
children: /* @__PURE__ */ x("div", {
|
|
79
|
+
className: "flex items-start gap-2 text-sm text-text-primary",
|
|
80
|
+
children: [/* @__PURE__ */ b(u, {
|
|
81
|
+
className: "mt-0.5 size-4 flex-shrink-0 text-status-success-text",
|
|
82
|
+
"aria-hidden": "true"
|
|
83
|
+
}), /* @__PURE__ */ b("p", { children: D.safetyInfo ?? S("ggnomad.activity.defaultSafety", "Standard provider safety policy applies.") })]
|
|
84
|
+
})
|
|
73
85
|
})]
|
|
74
|
-
}), /* @__PURE__ */
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}), /* @__PURE__ */ y("p", { children: E.safetyInfo ?? x("ggnomad.activity.defaultSafety", "Standard provider safety policy applies.") })]
|
|
82
|
-
})
|
|
83
|
-
})]
|
|
86
|
+
}), /* @__PURE__ */ b("div", { children: /* @__PURE__ */ b(s, {
|
|
87
|
+
bookingType: "ACTIVITY",
|
|
88
|
+
itemId: D.id ?? T,
|
|
89
|
+
itemName: D.name,
|
|
90
|
+
unitPrice: D.price ?? 0,
|
|
91
|
+
currency: D.currency ?? "USD"
|
|
92
|
+
}) })]
|
|
84
93
|
})
|
|
85
|
-
] }) : /* @__PURE__ */
|
|
94
|
+
] }) : /* @__PURE__ */ b(g, {
|
|
86
95
|
illustration: "empty-data",
|
|
87
|
-
title:
|
|
88
|
-
description:
|
|
96
|
+
title: S("ggnomad.activity.notFoundTitle", "No activity found"),
|
|
97
|
+
description: S("ggnomad.activity.notFoundDescription", "This activity is unavailable or may have been removed.")
|
|
89
98
|
})
|
|
90
99
|
});
|
|
91
100
|
}
|
|
92
101
|
//#endregion
|
|
93
|
-
export {
|
|
102
|
+
export { S as ActivityDetailsPage };
|
|
94
103
|
|
|
95
104
|
//# 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,
|
|
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, 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, BookingPanel } 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 id: string;\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: '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-3\">\n <div className=\"lg:col-span-2 space-y-4\">\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(\n 'ggnomad.activity.defaultSafety',\n 'Standard provider safety policy applies.'\n )}\n </p>\n </div>\n </SectionCard>\n </div>\n <div>\n <BookingPanel\n bookingType=\"ACTIVITY\"\n itemId={activity.id ?? id}\n itemName={activity.name}\n unitPrice={activity.price ?? 0}\n currency={activity.currency ?? 'USD'}\n />\n </div>\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,GAgBA;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,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,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAW,WAAU;MAAQ,MAAA;MAAK,WAAU;gBAA5C,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAE,4BAA4B,UAAU;OACtC,CAAA,EACL,kBAAC,MAAD;OAAI,WAAU;iBAAd;QACE,kBAAC,GAAD;SACE,OAAO,EAAE,6BAA6B,WAAW;SACjD,OAAO,EAAS;SAChB,CAAA;QACF,kBAAC,GAAD;SACE,OAAO,EAAE,6BAA6B,WAAW;SACjD,OAAO,EAAS;SAChB,CAAA;QACF,kBAAC,GAAD;SACE,OAAO,EAAE,oCAAoC,mBAAmB;SAChE,OAAO,OAAO,EAAS,gBAAgB;SACvC,CAAA;QACF,kBAAC,GAAD;SACE,OAAO,EAAE,0BAA0B,QAAQ;SAC3C,OAAO,GAAG,EAAS,SAAS,GAAG,OAAO,EAAS,MAAM,CAAC,QAAQ,EAAE;SAChE,CAAA;QACC;SACK;SACZ,kBAAC,GAAD;MAAa,OAAO,EAAE,2BAA2B,qBAAqB;gBACpE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QACE,WAAU;QACV,eAAY;QACZ,CAAA,EACF,kBAAC,KAAD,EAAA,UACG,EAAS,cACR,EACE,kCACA,2CACD,EACD,CAAA,CACA;;MACM,CAAA,CACV;QACN,kBAAC,OAAD,EAAA,UACE,kBAAC,GAAD;KACE,aAAY;KACZ,QAAQ,EAAS,MAAM;KACvB,UAAU,EAAS;KACnB,WAAW,EAAS,SAAS;KAC7B,UAAU,EAAS,YAAY;KAC/B,CAAA,EACE,CAAA,CACF;;GACL,EAAA,CAAA,GArFH,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,kCAAkC,oBAAoB;GAC/D,aAAa,EACX,wCACA,yDACD;GACD,CAAA;EAgFM,CAAA"}
|
|
@@ -2,8 +2,8 @@ import { CANCEL_GGNOMAD_BOOKING_MUTATION as e, CREATE_GGNOMAD_BOOKING_MUTATION a
|
|
|
2
2
|
import { PageShell as i } from "./PageShell.js";
|
|
3
3
|
import { StatusBadge as a } from "../components/StatusBadge.js";
|
|
4
4
|
import { EntityCard as o } from "../components/EntityCard.js";
|
|
5
|
-
import "../components/index.js";
|
|
6
5
|
import { notify as s } from "../utils/notify.js";
|
|
6
|
+
import "../components/index.js";
|
|
7
7
|
import { useState as c } from "react";
|
|
8
8
|
import { CalendarCheck as l, Compass as u, Hotel as d, Plus as f, Ticket as p, XCircle as m } from "lucide-react";
|
|
9
9
|
import { useI18n as h } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
@@ -39,6 +39,8 @@ function p() {
|
|
|
39
39
|
className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3",
|
|
40
40
|
children: _.map((e) => /* @__PURE__ */ d(n, {
|
|
41
41
|
to: e.id,
|
|
42
|
+
image: e.images?.[0],
|
|
43
|
+
imageAlt: e.name,
|
|
42
44
|
title: e.name,
|
|
43
45
|
meta: e.category,
|
|
44
46
|
price: `${e.currency} ${Number(e.price).toFixed(2)}`,
|
|
@@ -1 +1 @@
|
|
|
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 }>;\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 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,
|
|
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"}
|
|
@@ -2,97 +2,107 @@ import { GGNOMAD_EVENT_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";
|
|
6
|
+
import { useGGNomad as a } from "../providers/GGNomadProvider.js";
|
|
7
|
+
import { joinPath as o } from "../utils/navigation.js";
|
|
8
|
+
import { BookingPanel as s } from "../components/BookingPanel.js";
|
|
5
9
|
import "../components/index.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { GlassCard as p, IllustratedEmptyState as m, NextSteps as h, PagePurpose as g } from "@burdenoff/fe-libs/ui";
|
|
13
|
-
import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
10
|
+
import { Mic2 as c, Ticket as l } from "lucide-react";
|
|
11
|
+
import { useI18n as u } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
12
|
+
import { useNavigate as d, useParams as f } from "react-router-dom";
|
|
13
|
+
import { useQuery as p } from "@apollo/client/react";
|
|
14
|
+
import { GlassCard as m, IllustratedEmptyState as h, NextSteps as g, PagePurpose as _ } from "@burdenoff/fe-libs/ui";
|
|
15
|
+
import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
14
16
|
//#region src/ggnomad/pages/EventDetailsPage.tsx
|
|
15
|
-
function
|
|
16
|
-
let { t:
|
|
17
|
-
variables: { id:
|
|
18
|
-
skip: !
|
|
19
|
-
}),
|
|
20
|
-
return /* @__PURE__ */
|
|
21
|
-
title:
|
|
22
|
-
subtitle:
|
|
23
|
-
children:
|
|
24
|
-
/* @__PURE__ */
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
function x() {
|
|
18
|
+
let { t: x } = u(), S = d(), { basePath: C = "/" } = a(), { id: w = "" } = f(), { data: T } = p(e, {
|
|
19
|
+
variables: { id: w },
|
|
20
|
+
skip: !w
|
|
21
|
+
}), E = T?.ggnomadEvent;
|
|
22
|
+
return /* @__PURE__ */ y(t, {
|
|
23
|
+
title: E?.name ?? x("ggnomad.event.fallbackTitle", "Event details"),
|
|
24
|
+
subtitle: x("ggnomad.event.subtitle", "Live event details, venue and lineup"),
|
|
25
|
+
children: E ? /* @__PURE__ */ b(v, { children: [
|
|
26
|
+
/* @__PURE__ */ y(i, {
|
|
27
|
+
image: E.images?.[0],
|
|
28
|
+
alt: E.name
|
|
27
29
|
}),
|
|
28
|
-
/* @__PURE__ */
|
|
30
|
+
/* @__PURE__ */ y(_, {
|
|
31
|
+
icon: /* @__PURE__ */ y(l, { className: "size-4" }),
|
|
32
|
+
children: x("ggnomad.event.purpose", "All the details for this live event in one place — category, start and end times, ticket price and the full lineup — so you can decide and book tickets before they sell out.")
|
|
33
|
+
}),
|
|
34
|
+
/* @__PURE__ */ y(g, {
|
|
29
35
|
storageKey: "ggnomad-event-detail",
|
|
30
36
|
steps: [{
|
|
31
|
-
id: "book",
|
|
32
|
-
label: b("ggnomad.event.next.book", "Book tickets"),
|
|
33
|
-
description: b("ggnomad.event.next.bookDesc", "Reserve seats and track them under Bookings."),
|
|
34
|
-
icon: /* @__PURE__ */ v(o, { className: "size-4" }),
|
|
35
|
-
onClick: () => x(a(S, "bookings"))
|
|
36
|
-
}, {
|
|
37
37
|
id: "browse",
|
|
38
|
-
label:
|
|
39
|
-
description:
|
|
40
|
-
icon: /* @__PURE__ */
|
|
41
|
-
onClick: () =>
|
|
38
|
+
label: x("ggnomad.event.next.browse", "See more events"),
|
|
39
|
+
description: x("ggnomad.event.next.browseDesc", "Return to Entertainment for other live experiences."),
|
|
40
|
+
icon: /* @__PURE__ */ y(l, { className: "size-4" }),
|
|
41
|
+
onClick: () => S(o(C, "entertainment"))
|
|
42
42
|
}]
|
|
43
43
|
}),
|
|
44
|
-
/* @__PURE__ */
|
|
45
|
-
className: "grid gap-4 lg:grid-cols-
|
|
46
|
-
children: [/* @__PURE__ */
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
className: "
|
|
52
|
-
children:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
44
|
+
/* @__PURE__ */ b("div", {
|
|
45
|
+
className: "grid gap-4 lg:grid-cols-3",
|
|
46
|
+
children: [/* @__PURE__ */ b("div", {
|
|
47
|
+
className: "lg:col-span-2 space-y-4",
|
|
48
|
+
children: [/* @__PURE__ */ b(m, {
|
|
49
|
+
treatment: "glass",
|
|
50
|
+
glow: !0,
|
|
51
|
+
className: "border-border-seam p-5",
|
|
52
|
+
children: [/* @__PURE__ */ y("h2", {
|
|
53
|
+
className: "mb-4 text-lg font-medium tracking-tight text-text-primary",
|
|
54
|
+
children: x("ggnomad.event.details", "Details")
|
|
55
|
+
}), /* @__PURE__ */ b("dl", {
|
|
56
|
+
className: "space-y-2 text-sm",
|
|
57
|
+
children: [
|
|
58
|
+
/* @__PURE__ */ y(r, {
|
|
59
|
+
label: x("ggnomad.event.category", "Category"),
|
|
60
|
+
value: E.category
|
|
61
|
+
}),
|
|
62
|
+
/* @__PURE__ */ y(r, {
|
|
63
|
+
label: x("ggnomad.event.starts", "Starts"),
|
|
64
|
+
value: new Date(E.startsAt).toLocaleString()
|
|
65
|
+
}),
|
|
66
|
+
/* @__PURE__ */ y(r, {
|
|
67
|
+
label: x("ggnomad.event.ends", "Ends"),
|
|
68
|
+
value: E.endsAt ? new Date(E.endsAt).toLocaleString() : x("ggnomad.event.na", "N/A")
|
|
69
|
+
}),
|
|
70
|
+
/* @__PURE__ */ y(r, {
|
|
71
|
+
label: x("ggnomad.event.price", "Price"),
|
|
72
|
+
value: `${E.currency} ${Number(E.price).toFixed(2)}`
|
|
73
|
+
})
|
|
74
|
+
]
|
|
75
|
+
})]
|
|
76
|
+
}), /* @__PURE__ */ y(n, {
|
|
77
|
+
title: x("ggnomad.event.performers", "Performers"),
|
|
78
|
+
children: /* @__PURE__ */ y("ul", {
|
|
79
|
+
className: "space-y-2 text-sm",
|
|
80
|
+
children: (E.performers ?? []).map((e) => /* @__PURE__ */ b("li", {
|
|
81
|
+
className: "flex items-start gap-2 text-text-primary",
|
|
82
|
+
children: [/* @__PURE__ */ y(c, {
|
|
83
|
+
className: "mt-0.5 size-4 flex-shrink-0 text-action-primary-bg",
|
|
84
|
+
"aria-hidden": "true"
|
|
85
|
+
}), e]
|
|
86
|
+
}, e))
|
|
87
|
+
})
|
|
73
88
|
})]
|
|
74
|
-
}), /* @__PURE__ */
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
"aria-hidden": "true"
|
|
83
|
-
}), e]
|
|
84
|
-
}, e))
|
|
85
|
-
})
|
|
86
|
-
})]
|
|
89
|
+
}), /* @__PURE__ */ y("div", { children: /* @__PURE__ */ y(s, {
|
|
90
|
+
bookingType: "EVENT",
|
|
91
|
+
itemId: E.id ?? w,
|
|
92
|
+
itemName: E.name,
|
|
93
|
+
unitPrice: E.price ?? 0,
|
|
94
|
+
currency: E.currency ?? "USD",
|
|
95
|
+
eventDate: E.startsAt
|
|
96
|
+
}) })]
|
|
87
97
|
})
|
|
88
|
-
] }) : /* @__PURE__ */
|
|
98
|
+
] }) : /* @__PURE__ */ y(h, {
|
|
89
99
|
illustration: "empty-data",
|
|
90
|
-
title:
|
|
91
|
-
description:
|
|
100
|
+
title: x("ggnomad.event.notFoundTitle", "No event found"),
|
|
101
|
+
description: x("ggnomad.event.notFoundDescription", "This event is unavailable or may have been removed.")
|
|
92
102
|
})
|
|
93
103
|
});
|
|
94
104
|
}
|
|
95
105
|
//#endregion
|
|
96
|
-
export {
|
|
106
|
+
export { x as EventDetailsPage };
|
|
97
107
|
|
|
98
108
|
//# sourceMappingURL=EventDetailsPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventDetailsPage.js","names":[],"sources":["../../../src/ggnomad/pages/EventDetailsPage.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 {
|
|
1
|
+
{"version":3,"file":"EventDetailsPage.js","names":[],"sources":["../../../src/ggnomad/pages/EventDetailsPage.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 { Mic2, Ticket } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, NextSteps, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_EVENT_QUERY } from '../graphql';\nimport { useGGNomad } from '../providers/GGNomadProvider';\nimport { joinPath } from '../utils/navigation';\nimport { PageShell } from './PageShell';\nimport { DetailRow, SectionCard, DetailHero, BookingPanel } from '../components';\n\nexport function EventDetailsPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { basePath = '/' } = useGGNomad();\n const { id = '' } = useParams();\n const { data } = useQuery(\n GGNOMAD_EVENT_QUERY as TypedDocumentNode<\n {\n ggnomadEvent: {\n id: string;\n name: string;\n category: string;\n startsAt: string;\n endsAt?: string;\n currency: string;\n price: number;\n performers: string[];\n images?: string[];\n } | null;\n },\n { id: string }\n >,\n { variables: { id }, skip: !id }\n );\n const event = data?.ggnomadEvent;\n\n return (\n <PageShell\n title={event?.name ?? t('ggnomad.event.fallbackTitle', 'Event details')}\n subtitle={t('ggnomad.event.subtitle', 'Live event details, venue and lineup')}\n >\n {!event ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.event.notFoundTitle', 'No event found')}\n description={t(\n 'ggnomad.event.notFoundDescription',\n 'This event is unavailable or may have been removed.'\n )}\n />\n ) : (\n <>\n <DetailHero image={event.images?.[0]} alt={event.name} />\n <PagePurpose icon={<Ticket className=\"size-4\" />}>\n {t(\n 'ggnomad.event.purpose',\n 'All the details for this live event in one place — category, start and end times, ticket price and the full lineup — so you can decide and book tickets before they sell out.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"ggnomad-event-detail\"\n steps={[\n {\n id: 'browse',\n label: t('ggnomad.event.next.browse', 'See more events'),\n description: t(\n 'ggnomad.event.next.browseDesc',\n 'Return to Entertainment for other live experiences.'\n ),\n icon: <Ticket className=\"size-4\" />,\n onClick: () => navigate(joinPath(basePath, 'entertainment')),\n },\n ]}\n />\n\n <div className=\"grid gap-4 lg:grid-cols-3\">\n <div className=\"lg:col-span-2 space-y-4\">\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.event.details', 'Details')}\n </h2>\n <dl className=\"space-y-2 text-sm\">\n <DetailRow\n label={t('ggnomad.event.category', 'Category')}\n value={event.category}\n />\n <DetailRow\n label={t('ggnomad.event.starts', 'Starts')}\n value={new Date(event.startsAt).toLocaleString()}\n />\n <DetailRow\n label={t('ggnomad.event.ends', 'Ends')}\n value={\n event.endsAt\n ? new Date(event.endsAt).toLocaleString()\n : t('ggnomad.event.na', 'N/A')\n }\n />\n <DetailRow\n label={t('ggnomad.event.price', 'Price')}\n value={`${event.currency} ${Number(event.price).toFixed(2)}`}\n />\n </dl>\n </GlassCard>\n <SectionCard title={t('ggnomad.event.performers', 'Performers')}>\n <ul className=\"space-y-2 text-sm\">\n {(event.performers ?? []).map((performer) => (\n <li key={performer} className=\"flex items-start gap-2 text-text-primary\">\n <Mic2\n className=\"mt-0.5 size-4 flex-shrink-0 text-action-primary-bg\"\n aria-hidden=\"true\"\n />\n {performer}\n </li>\n ))}\n </ul>\n </SectionCard>\n </div>\n <div>\n <BookingPanel\n bookingType=\"EVENT\"\n itemId={event.id ?? id}\n itemName={event.name}\n unitPrice={event.price ?? 0}\n currency={event.currency ?? 'USD'}\n eventDate={event.startsAt}\n />\n </div>\n </div>\n </>\n )}\n </PageShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAaA,SAAgB,IAAmB;CACjC,IAAM,EAAE,SAAM,GAAS,EACjB,IAAW,GAAa,EACxB,EAAE,cAAW,QAAQ,GAAY,EACjC,EAAE,QAAK,OAAO,GAAW,EACzB,EAAE,YAAS,EACf,GAgBA;EAAE,WAAW,EAAE,OAAI;EAAE,MAAM,CAAC;EAAI,CACjC,EACK,IAAQ,GAAM;AAEpB,QACE,kBAAC,GAAD;EACE,OAAO,GAAO,QAAQ,EAAE,+BAA+B,gBAAgB;EACvE,UAAU,EAAE,0BAA0B,uCAAuC;YAE3E,IAUA,kBAAA,GAAA,EAAA,UAAA;GACE,kBAAC,GAAD;IAAY,OAAO,EAAM,SAAS;IAAI,KAAK,EAAM;IAAQ,CAAA;GACzD,kBAAC,GAAD;IAAa,MAAM,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA;cAC7C,EACC,yBACA,gLACD;IACW,CAAA;GAEd,kBAAC,GAAD;IACE,YAAW;IACX,OAAO,CACL;KACE,IAAI;KACJ,OAAO,EAAE,6BAA6B,kBAAkB;KACxD,aAAa,EACX,iCACA,sDACD;KACD,MAAM,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA;KACnC,eAAe,EAAS,EAAS,GAAU,gBAAgB,CAAC;KAC7D,CACF;IACD,CAAA;GAEF,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAW,WAAU;MAAQ,MAAA;MAAK,WAAU;gBAA5C,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAE,yBAAyB,UAAU;OACnC,CAAA,EACL,kBAAC,MAAD;OAAI,WAAU;iBAAd;QACE,kBAAC,GAAD;SACE,OAAO,EAAE,0BAA0B,WAAW;SAC9C,OAAO,EAAM;SACb,CAAA;QACF,kBAAC,GAAD;SACE,OAAO,EAAE,wBAAwB,SAAS;SAC1C,OAAO,IAAI,KAAK,EAAM,SAAS,CAAC,gBAAgB;SAChD,CAAA;QACF,kBAAC,GAAD;SACE,OAAO,EAAE,sBAAsB,OAAO;SACtC,OACE,EAAM,SACF,IAAI,KAAK,EAAM,OAAO,CAAC,gBAAgB,GACvC,EAAE,oBAAoB,MAAM;SAElC,CAAA;QACF,kBAAC,GAAD;SACE,OAAO,EAAE,uBAAuB,QAAQ;SACxC,OAAO,GAAG,EAAM,SAAS,GAAG,OAAO,EAAM,MAAM,CAAC,QAAQ,EAAE;SAC1D,CAAA;QACC;SACK;SACZ,kBAAC,GAAD;MAAa,OAAO,EAAE,4BAA4B,aAAa;gBAC7D,kBAAC,MAAD;OAAI,WAAU;kBACV,EAAM,cAAc,EAAE,EAAE,KAAK,MAC7B,kBAAC,MAAD;QAAoB,WAAU;kBAA9B,CACE,kBAAC,GAAD;SACE,WAAU;SACV,eAAY;SACZ,CAAA,EACD,EACE;UANI,EAMJ,CACL;OACC,CAAA;MACO,CAAA,CACV;QACN,kBAAC,OAAD,EAAA,UACE,kBAAC,GAAD;KACE,aAAY;KACZ,QAAQ,EAAM,MAAM;KACpB,UAAU,EAAM;KAChB,WAAW,EAAM,SAAS;KAC1B,UAAU,EAAM,YAAY;KAC5B,WAAW,EAAM;KACjB,CAAA,EACE,CAAA,CACF;;GACL,EAAA,CAAA,GAxFH,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,+BAA+B,iBAAiB;GACzD,aAAa,EACX,qCACA,sDACD;GACD,CAAA;EAmFM,CAAA"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { GGNOMAD_FAVORITES_QUERY as e, GGNOMAD_FAVORITE_TARGETS_QUERY as t, TOGGLE_GGNOMAD_FAVORITE_MUTATION as n } from "../graphql.js";
|
|
2
2
|
import { PageShell as r } from "./PageShell.js";
|
|
3
3
|
import { EntityCard as i } from "../components/EntityCard.js";
|
|
4
|
-
import "../components/index.js";
|
|
5
4
|
import { notify as a } from "../utils/notify.js";
|
|
5
|
+
import "../components/index.js";
|
|
6
6
|
import { useMemo as o } from "react";
|
|
7
7
|
import { Heart as s } from "lucide-react";
|
|
8
8
|
import { useI18n as c } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
@@ -39,6 +39,8 @@ function m() {
|
|
|
39
39
|
className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3",
|
|
40
40
|
children: v.map((e) => /* @__PURE__ */ f(n, {
|
|
41
41
|
to: e.id,
|
|
42
|
+
image: e.images?.[0],
|
|
43
|
+
imageAlt: e.name,
|
|
42
44
|
title: e.name,
|
|
43
45
|
meta: e.type,
|
|
44
46
|
price: `${e.currency} ${Number(e.pricePerNight).toFixed(2)} ${m("ggnomad.hospitality.card.perNight", "per night")}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HospitalityPage.js","names":[],"sources":["../../../src/ggnomad/pages/HospitalityPage.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 { Hotel, Star } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_PROPERTIES_QUERY } from '../graphql';\nimport { PageShell } from './PageShell';\nimport { EntityCard, LoadMoreButton } from '../components';\n\nexport function HospitalityPage() {\n const { t } = useI18n();\n const [limit, setLimit] = useState(12);\n const { data } = useQuery(\n GGNOMAD_PROPERTIES_QUERY as TypedDocumentNode<\n {\n ggnomadProperties: Array<{\n id: string;\n name: string;\n type: string;\n pricePerNight: number;\n currency: string;\n rating?: number;\n }>;\n },\n { first: number; skip: number }\n >,\n { variables: { first: limit, skip: 0 } }\n );\n const properties = data?.ggnomadProperties ?? [];\n\n return (\n <PageShell\n title={t('ggnomad.hospitality.title', 'Hospitality')}\n titleAccent={t('ggnomad.hospitality.title.accent', 'Hospitality')}\n subtitle={t(\n 'ggnomad.hospitality.subtitle',\n 'Property discovery powered by live GraphQL data'\n )}\n >\n <PagePurpose icon={<Hotel className=\"size-4\" />}>\n {t(\n 'ggnomad.hospitality.purpose',\n 'Discover places to stay — hotels, homestays and short-stay rentals. Open any property to review its nightly price, guest capacity and rating, then create a booking for the dates you need.'\n )}\n </PagePurpose>\n\n {properties.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.hospitality.emptyTitle', 'No properties available')}\n description={t(\n 'ggnomad.hospitality.emptyDescription',\n 'Properties published by providers will be discoverable 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.hospitality.featuredStays', 'Featured stays')}\n </h2>\n <div className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {properties.map((property) => (\n <EntityCard\n key={property.id}\n to={property.id}\n title={property.name}\n meta={property.type}\n price={`${property.currency} ${Number(property.pricePerNight).toFixed(2)} ${t(\n 'ggnomad.hospitality.card.perNight',\n 'per night'\n )}`}\n footer={\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Star className=\"size-3.5 text-status-warning-text\" aria-hidden=\"true\" />\n {property.rating ?? t('ggnomad.hospitality.card.noRating', 'N/A')}\n </span>\n }\n />\n ))}\n </div>\n <LoadMoreButton\n visible={properties.length >= limit}\n onLoadMore={() => setLimit((l) => l + 12)}\n />\n </GlassCard>\n )}\n </PageShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAWA,SAAgB,IAAkB;CAChC,IAAM,EAAE,SAAM,GAAS,EACjB,CAAC,GAAO,KAAY,EAAS,GAAG,EAChC,EAAE,YAAS,EACf,
|
|
1
|
+
{"version":3,"file":"HospitalityPage.js","names":[],"sources":["../../../src/ggnomad/pages/HospitalityPage.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 { Hotel, Star } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_PROPERTIES_QUERY } from '../graphql';\nimport { PageShell } from './PageShell';\nimport { EntityCard, LoadMoreButton } from '../components';\n\nexport function HospitalityPage() {\n const { t } = useI18n();\n const [limit, setLimit] = useState(12);\n const { data } = useQuery(\n GGNOMAD_PROPERTIES_QUERY as TypedDocumentNode<\n {\n ggnomadProperties: Array<{\n id: string;\n name: string;\n type: string;\n pricePerNight: number;\n currency: string;\n rating?: number;\n images?: string[];\n }>;\n },\n { first: number; skip: number }\n >,\n { variables: { first: limit, skip: 0 } }\n );\n const properties = data?.ggnomadProperties ?? [];\n\n return (\n <PageShell\n title={t('ggnomad.hospitality.title', 'Hospitality')}\n titleAccent={t('ggnomad.hospitality.title.accent', 'Hospitality')}\n subtitle={t(\n 'ggnomad.hospitality.subtitle',\n 'Property discovery powered by live GraphQL data'\n )}\n >\n <PagePurpose icon={<Hotel className=\"size-4\" />}>\n {t(\n 'ggnomad.hospitality.purpose',\n 'Discover places to stay — hotels, homestays and short-stay rentals. Open any property to review its nightly price, guest capacity and rating, then create a booking for the dates you need.'\n )}\n </PagePurpose>\n\n {properties.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.hospitality.emptyTitle', 'No properties available')}\n description={t(\n 'ggnomad.hospitality.emptyDescription',\n 'Properties published by providers will be discoverable 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.hospitality.featuredStays', 'Featured stays')}\n </h2>\n <div className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {properties.map((property) => (\n <EntityCard\n key={property.id}\n to={property.id}\n image={property.images?.[0]}\n imageAlt={property.name}\n title={property.name}\n meta={property.type}\n price={`${property.currency} ${Number(property.pricePerNight).toFixed(2)} ${t(\n 'ggnomad.hospitality.card.perNight',\n 'per night'\n )}`}\n footer={\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Star className=\"size-3.5 text-status-warning-text\" aria-hidden=\"true\" />\n {property.rating ?? t('ggnomad.hospitality.card.noRating', 'N/A')}\n </span>\n }\n />\n ))}\n </div>\n <LoadMoreButton\n visible={properties.length >= limit}\n onLoadMore={() => setLimit((l) => l + 12)}\n />\n </GlassCard>\n )}\n </PageShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAWA,SAAgB,IAAkB;CAChC,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,IAAa,GAAM,qBAAqB,EAAE;AAEhD,QACE,kBAAC,GAAD;EACE,OAAO,EAAE,6BAA6B,cAAc;EACpD,aAAa,EAAE,oCAAoC,cAAc;EACjE,UAAU,EACR,gCACA,kDACD;YANH,CAQE,kBAAC,GAAD;GAAa,MAAM,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA;aAC5C,EACC,+BACA,8LACD;GACW,CAAA,EAEb,EAAW,WAAW,IACrB,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,kCAAkC,0BAA0B;GACrE,aAAa,EACX,wCACA,+DACD;GACD,CAAA,GAEF,kBAAC,GAAD;GAAW,WAAU;GAAQ,MAAA;GAAK,WAAU;aAA5C;IACE,kBAAC,MAAD;KAAI,WAAU;eACX,EAAE,qCAAqC,iBAAiB;KACtD,CAAA;IACL,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAW,KAAK,MACf,kBAAC,GAAD;MAEE,IAAI,EAAS;MACb,OAAO,EAAS,SAAS;MACzB,UAAU,EAAS;MACnB,OAAO,EAAS;MAChB,MAAM,EAAS;MACf,OAAO,GAAG,EAAS,SAAS,GAAG,OAAO,EAAS,cAAc,CAAC,QAAQ,EAAE,CAAC,GAAG,EAC1E,qCACA,YACD;MACD,QACE,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CACE,kBAAC,GAAD;QAAM,WAAU;QAAoC,eAAY;QAAS,CAAA,EACxE,EAAS,UAAU,EAAE,qCAAqC,MAAM,CAC5D;;MAET,EAhBK,EAAS,GAgBd,CACF;KACE,CAAA;IACN,kBAAC,GAAD;KACE,SAAS,EAAW,UAAU;KAC9B,kBAAkB,GAAU,MAAM,IAAI,GAAG;KACzC,CAAA;IACQ;KAEJ"}
|