@burdenoff/microfe-ggnomad 2026.624.1 → 2026.704.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.
- package/dist/ggnomad/components/DetailRow.js +18 -0
- package/dist/ggnomad/components/DetailRow.js.map +1 -0
- package/dist/ggnomad/components/EntityCard.js +50 -0
- package/dist/ggnomad/components/EntityCard.js.map +1 -0
- package/dist/ggnomad/components/SectionCard.js +21 -0
- package/dist/ggnomad/components/SectionCard.js.map +1 -0
- package/dist/ggnomad/components/StatCard.js +27 -0
- package/dist/ggnomad/components/StatCard.js.map +1 -0
- package/dist/ggnomad/components/StatusBadge.js +65 -0
- package/dist/ggnomad/components/StatusBadge.js.map +1 -0
- package/dist/ggnomad/components/index.js +5 -0
- package/dist/ggnomad/graphql.js +61 -17
- package/dist/ggnomad/graphql.js.map +1 -1
- package/dist/ggnomad/pages/ActivityDetailsPage.js +84 -37
- package/dist/ggnomad/pages/ActivityDetailsPage.js.map +1 -1
- package/dist/ggnomad/pages/AnalyticsPage.js +111 -55
- package/dist/ggnomad/pages/AnalyticsPage.js.map +1 -1
- package/dist/ggnomad/pages/BookingsPage.js +183 -61
- package/dist/ggnomad/pages/BookingsPage.js.map +1 -1
- package/dist/ggnomad/pages/DashboardPage.js +132 -107
- package/dist/ggnomad/pages/DashboardPage.js.map +1 -1
- package/dist/ggnomad/pages/EntertainmentPage.js +40 -33
- package/dist/ggnomad/pages/EntertainmentPage.js.map +1 -1
- package/dist/ggnomad/pages/EventDetailsPage.js +86 -39
- package/dist/ggnomad/pages/EventDetailsPage.js.map +1 -1
- package/dist/ggnomad/pages/FavoritesPage.js +110 -33
- package/dist/ggnomad/pages/FavoritesPage.js.map +1 -1
- package/dist/ggnomad/pages/HospitalityPage.js +45 -42
- package/dist/ggnomad/pages/HospitalityPage.js.map +1 -1
- package/dist/ggnomad/pages/PageShell.js +33 -11
- package/dist/ggnomad/pages/PageShell.js.map +1 -1
- package/dist/ggnomad/pages/PropertyDetailsPage.js +95 -45
- package/dist/ggnomad/pages/PropertyDetailsPage.js.map +1 -1
- package/dist/ggnomad/pages/ProviderPage.js +65 -29
- package/dist/ggnomad/pages/ProviderPage.js.map +1 -1
- package/dist/ggnomad/pages/SearchPage.js +57 -48
- package/dist/ggnomad/pages/SearchPage.js.map +1 -1
- package/dist/ggnomad/pages/TourDetailsPage.js +86 -39
- package/dist/ggnomad/pages/TourDetailsPage.js.map +1 -1
- package/dist/ggnomad/pages/TourismPage.js +64 -63
- package/dist/ggnomad/pages/TourismPage.js.map +1 -1
- package/dist/ggnomad/pages/TravelPage.js +43 -27
- package/dist/ggnomad/pages/TravelPage.js.map +1 -1
- package/dist/ggnomad/utils/cn.js +10 -0
- package/dist/ggnomad/utils/cn.js.map +1 -0
- package/dist/ggnomad/utils/notify.js +36 -0
- package/dist/ggnomad/utils/notify.js.map +1 -0
- package/package.json +3 -2
|
@@ -1,128 +1,153 @@
|
|
|
1
1
|
import { GGNOMAD_BOOKINGS_QUERY as e, GGNOMAD_EVENTS_QUERY as t, GGNOMAD_OVERVIEW_QUERY as n, GGNOMAD_PROPERTIES_QUERY as r, GGNOMAD_TOURS_QUERY as i } from "../graphql.js";
|
|
2
2
|
import { PageShell as a } from "./PageShell.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { StatCard as o } from "../components/StatCard.js";
|
|
4
|
+
import { StatusBadge as s } from "../components/StatusBadge.js";
|
|
5
|
+
import { SectionCard as c } from "../components/SectionCard.js";
|
|
6
|
+
import "../components/index.js";
|
|
7
|
+
import { Building as l, CalendarCheck as u, Compass as d, DollarSign as f, Hotel as p, Search as m, Users as h } from "lucide-react";
|
|
8
|
+
import { useI18n as g } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
9
|
+
import { useNavigate as _ } from "react-router-dom";
|
|
10
|
+
import { useQuery as v } from "@apollo/client/react";
|
|
11
|
+
import { EmphasisPanel as y, IllustratedEmptyState as b, NextSteps as x, PagePurpose as S } from "@burdenoff/fe-libs/ui";
|
|
12
|
+
import { jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
6
13
|
//#region src/ggnomad/pages/DashboardPage.tsx
|
|
7
|
-
function
|
|
8
|
-
let { t:
|
|
14
|
+
function T() {
|
|
15
|
+
let { t: T } = g(), E = _(), D = v(n), O = v(e, { variables: {
|
|
9
16
|
first: 5,
|
|
10
17
|
skip: 0
|
|
11
|
-
} }),
|
|
18
|
+
} }), k = v(r, { variables: {
|
|
12
19
|
first: 4,
|
|
13
20
|
skip: 0
|
|
14
|
-
} }),
|
|
21
|
+
} }), A = v(i, { variables: {
|
|
15
22
|
first: 4,
|
|
16
23
|
skip: 0
|
|
17
|
-
} }),
|
|
24
|
+
} }), j = v(t, { variables: {
|
|
18
25
|
first: 4,
|
|
19
26
|
skip: 0
|
|
20
|
-
} }),
|
|
21
|
-
return /* @__PURE__ */
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
} }), M = D.data?.ggnomadOverviewStats, N = O.data?.ggnomadBookings ?? [];
|
|
28
|
+
return /* @__PURE__ */ w(a, {
|
|
29
|
+
hero: !0,
|
|
30
|
+
title: T("ggnomad.dashboard.title", "GGNomad Dashboard"),
|
|
31
|
+
titleAccent: T("ggnomad.dashboard.title.accent", "GGNomad"),
|
|
32
|
+
subtitle: T("ggnomad.dashboard.subtitle", "Unified travel, hospitality, tourism and entertainment operations"),
|
|
33
|
+
children: [
|
|
34
|
+
/* @__PURE__ */ C(S, {
|
|
35
|
+
icon: /* @__PURE__ */ C(d, { className: "size-4" }),
|
|
36
|
+
children: T("ggnomad.dashboard.purpose", "Your command centre for the whole GGNomad marketplace — see live revenue, users, listings and bookings across travel, hospitality, tourism and entertainment in one place, and jump straight into the area you want to work on.")
|
|
37
|
+
}),
|
|
38
|
+
/* @__PURE__ */ C(x, {
|
|
39
|
+
storageKey: "ggnomad-dashboard",
|
|
40
|
+
steps: [
|
|
41
|
+
{
|
|
42
|
+
id: "search",
|
|
43
|
+
label: T("ggnomad.dashboard.next.search", "Search the catalogue"),
|
|
44
|
+
description: T("ggnomad.dashboard.next.searchDesc", "Find inventory across every domain at once."),
|
|
45
|
+
icon: /* @__PURE__ */ C(m, { className: "size-4" }),
|
|
46
|
+
onClick: () => E("search")
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: "stays",
|
|
50
|
+
label: T("ggnomad.dashboard.next.stays", "Browse places to stay"),
|
|
51
|
+
description: T("ggnomad.dashboard.next.staysDesc", "Explore hospitality listings and open a property."),
|
|
52
|
+
icon: /* @__PURE__ */ C(p, { className: "size-4" }),
|
|
53
|
+
onClick: () => E("hospitality")
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: "tourism",
|
|
57
|
+
label: T("ggnomad.dashboard.next.tourism", "Discover tours & activities"),
|
|
58
|
+
description: T("ggnomad.dashboard.next.tourismDesc", "Plan what to do at each destination."),
|
|
59
|
+
icon: /* @__PURE__ */ C(d, { className: "size-4" }),
|
|
60
|
+
onClick: () => E("tourism")
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: "bookings",
|
|
64
|
+
label: T("ggnomad.dashboard.next.bookings", "Manage bookings"),
|
|
65
|
+
description: T("ggnomad.dashboard.next.bookingsDesc", "Track and cancel reservations in real time."),
|
|
66
|
+
icon: /* @__PURE__ */ C(u, { className: "size-4" }),
|
|
67
|
+
onClick: () => E("bookings")
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}),
|
|
71
|
+
/* @__PURE__ */ w("section", {
|
|
72
|
+
className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4",
|
|
73
|
+
children: [
|
|
74
|
+
/* @__PURE__ */ C(o, {
|
|
75
|
+
hero: !0,
|
|
76
|
+
label: T("ggnomad.dashboard.stats.monthlyRevenue", "Monthly Revenue"),
|
|
77
|
+
value: `$${Number(M?.monthlyRevenue ?? 0).toLocaleString()}`,
|
|
78
|
+
icon: /* @__PURE__ */ C(f, {})
|
|
79
|
+
}),
|
|
80
|
+
/* @__PURE__ */ C(o, {
|
|
81
|
+
label: T("ggnomad.dashboard.stats.users", "Users"),
|
|
82
|
+
value: Number(M?.users ?? 0).toLocaleString(),
|
|
83
|
+
icon: /* @__PURE__ */ C(h, {})
|
|
84
|
+
}),
|
|
85
|
+
/* @__PURE__ */ C(o, {
|
|
86
|
+
label: T("ggnomad.dashboard.stats.listings", "Listings"),
|
|
87
|
+
value: Number(M?.listings ?? 0).toLocaleString(),
|
|
88
|
+
icon: /* @__PURE__ */ C(l, {})
|
|
89
|
+
}),
|
|
90
|
+
/* @__PURE__ */ C(o, {
|
|
91
|
+
label: T("ggnomad.dashboard.stats.bookings", "Bookings"),
|
|
92
|
+
value: Number(M?.bookings ?? 0).toLocaleString(),
|
|
93
|
+
icon: /* @__PURE__ */ C(u, {})
|
|
94
|
+
})
|
|
95
|
+
]
|
|
96
|
+
}),
|
|
97
|
+
/* @__PURE__ */ w(y, { children: [/* @__PURE__ */ w("div", {
|
|
98
|
+
className: "grid gap-4 sm:grid-cols-3",
|
|
99
|
+
children: [
|
|
100
|
+
/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
|
|
30
101
|
className: "text-sm text-text-secondary",
|
|
31
|
-
children:
|
|
32
|
-
}), /* @__PURE__ */
|
|
33
|
-
className: "text-2xl font-semibold",
|
|
34
|
-
children:
|
|
35
|
-
})]
|
|
36
|
-
|
|
37
|
-
/* @__PURE__ */ l("div", {
|
|
38
|
-
className: "rounded-lg border p-4",
|
|
39
|
-
children: [/* @__PURE__ */ c("p", {
|
|
102
|
+
children: T("ggnomad.dashboard.inventory.properties", "Properties")
|
|
103
|
+
}), /* @__PURE__ */ C("p", {
|
|
104
|
+
className: "mt-1 text-2xl font-semibold tabular-nums text-text-primary",
|
|
105
|
+
children: k.data?.ggnomadProperties?.length ?? 0
|
|
106
|
+
})] }),
|
|
107
|
+
/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
|
|
40
108
|
className: "text-sm text-text-secondary",
|
|
41
|
-
children:
|
|
42
|
-
}), /* @__PURE__ */
|
|
43
|
-
className: "text-2xl font-semibold",
|
|
44
|
-
children:
|
|
45
|
-
})]
|
|
46
|
-
|
|
47
|
-
/* @__PURE__ */ l("div", {
|
|
48
|
-
className: "rounded-lg border p-4",
|
|
49
|
-
children: [/* @__PURE__ */ c("p", {
|
|
109
|
+
children: T("ggnomad.dashboard.inventory.tours", "Tours")
|
|
110
|
+
}), /* @__PURE__ */ C("p", {
|
|
111
|
+
className: "mt-1 text-2xl font-semibold tabular-nums text-text-primary",
|
|
112
|
+
children: A.data?.ggnomadTours?.length ?? 0
|
|
113
|
+
})] }),
|
|
114
|
+
/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
|
|
50
115
|
className: "text-sm text-text-secondary",
|
|
51
|
-
children:
|
|
52
|
-
}), /* @__PURE__ */
|
|
53
|
-
className: "text-2xl font-semibold",
|
|
54
|
-
children:
|
|
55
|
-
})]
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}), /* @__PURE__ */ l("section", {
|
|
69
|
-
className: "grid gap-4 lg:grid-cols-2",
|
|
70
|
-
children: [/* @__PURE__ */ l("div", {
|
|
71
|
-
className: "rounded-lg border p-4",
|
|
72
|
-
children: [/* @__PURE__ */ c("h2", {
|
|
73
|
-
className: "mb-3 text-lg font-medium",
|
|
74
|
-
children: u("ggnomad.dashboard.sections.recentBookings", "Recent bookings")
|
|
75
|
-
}), /* @__PURE__ */ c("ul", {
|
|
116
|
+
children: T("ggnomad.dashboard.inventory.events", "Events")
|
|
117
|
+
}), /* @__PURE__ */ C("p", {
|
|
118
|
+
className: "mt-1 text-2xl font-semibold tabular-nums text-text-primary",
|
|
119
|
+
children: j.data?.ggnomadEvents?.length ?? 0
|
|
120
|
+
})] })
|
|
121
|
+
]
|
|
122
|
+
}), /* @__PURE__ */ C("p", {
|
|
123
|
+
className: "mt-4 text-sm text-text-secondary",
|
|
124
|
+
children: T("ggnomad.dashboard.inventory.liveDataNotice", "Data is live from `wspace-ggnomad-svc` GraphQL APIs.")
|
|
125
|
+
})] }),
|
|
126
|
+
/* @__PURE__ */ C(c, {
|
|
127
|
+
title: T("ggnomad.dashboard.sections.recentBookings", "Recent bookings"),
|
|
128
|
+
children: N.length === 0 ? /* @__PURE__ */ C(b, {
|
|
129
|
+
illustration: "empty-data",
|
|
130
|
+
title: T("ggnomad.dashboard.recentBookings.emptyTitle", "No recent bookings"),
|
|
131
|
+
description: T("ggnomad.dashboard.recentBookings.emptyDescription", "New bookings across travel, hospitality and tourism will appear here.")
|
|
132
|
+
}) : /* @__PURE__ */ C("ul", {
|
|
76
133
|
className: "space-y-2 text-sm",
|
|
77
|
-
children:
|
|
78
|
-
className: "flex items-center justify-between rounded border p-
|
|
79
|
-
children: [/* @__PURE__ */
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
})]
|
|
134
|
+
children: N.map((e) => /* @__PURE__ */ w("li", {
|
|
135
|
+
className: "flex items-center justify-between gap-3 rounded-lg border border-border-seam bg-bg-surface/40 p-3",
|
|
136
|
+
children: [/* @__PURE__ */ w("span", {
|
|
137
|
+
className: "min-w-0 truncate text-text-primary",
|
|
138
|
+
children: [
|
|
139
|
+
e.referenceCode,
|
|
140
|
+
" — ",
|
|
141
|
+
e.itemName
|
|
142
|
+
]
|
|
143
|
+
}), /* @__PURE__ */ C(s, { status: e.status })]
|
|
87
144
|
}, e.id))
|
|
88
|
-
})
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
children: [/* @__PURE__ */ c("h2", {
|
|
92
|
-
className: "mb-3 text-lg font-medium",
|
|
93
|
-
children: u("ggnomad.dashboard.sections.featuredInventory", "Featured inventory")
|
|
94
|
-
}), /* @__PURE__ */ l("div", {
|
|
95
|
-
className: "grid gap-2 text-sm",
|
|
96
|
-
children: [
|
|
97
|
-
/* @__PURE__ */ l("p", { children: [
|
|
98
|
-
u("ggnomad.dashboard.inventory.properties", "Properties"),
|
|
99
|
-
":",
|
|
100
|
-
" ",
|
|
101
|
-
p.data?.ggnomadProperties?.length ?? 0
|
|
102
|
-
] }),
|
|
103
|
-
/* @__PURE__ */ l("p", { children: [
|
|
104
|
-
u("ggnomad.dashboard.inventory.tours", "Tours"),
|
|
105
|
-
":",
|
|
106
|
-
" ",
|
|
107
|
-
m.data?.ggnomadTours?.length ?? 0
|
|
108
|
-
] }),
|
|
109
|
-
/* @__PURE__ */ l("p", { children: [
|
|
110
|
-
u("ggnomad.dashboard.inventory.events", "Events"),
|
|
111
|
-
":",
|
|
112
|
-
" ",
|
|
113
|
-
h.data?.ggnomadEvents?.length ?? 0
|
|
114
|
-
] }),
|
|
115
|
-
/* @__PURE__ */ c("p", {
|
|
116
|
-
className: "text-text-secondary",
|
|
117
|
-
children: u("ggnomad.dashboard.inventory.liveDataNotice", "Data is live from `wspace-ggnomad-svc` GraphQL APIs.")
|
|
118
|
-
})
|
|
119
|
-
]
|
|
120
|
-
})]
|
|
121
|
-
})]
|
|
122
|
-
})]
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
]
|
|
123
148
|
});
|
|
124
149
|
}
|
|
125
150
|
//#endregion
|
|
126
|
-
export {
|
|
151
|
+
export { T as DashboardPage };
|
|
127
152
|
|
|
128
153
|
//# sourceMappingURL=DashboardPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/ggnomad/pages/DashboardPage.tsx"],"sourcesContent":["import { useQuery } from '@apollo/client/react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\nimport {\n GGNOMAD_OVERVIEW_QUERY,\n GGNOMAD_BOOKINGS_QUERY,\n GGNOMAD_PROPERTIES_QUERY,\n GGNOMAD_TOURS_QUERY,\n GGNOMAD_EVENTS_QUERY,\n} from '../graphql';\nimport { PageShell } from './PageShell';\n\nexport function DashboardPage() {\n const { t } = useI18n();\n const overview = useQuery<{\n ggnomadOverviewStats: {\n users: number;\n listings: number;\n bookings: number;\n monthlyRevenue: number;\n };\n }>(GGNOMAD_OVERVIEW_QUERY);\n const bookings = useQuery<{\n ggnomadBookings: Array<{ id: string; referenceCode: string; itemName: string; status: string }>;\n }>(GGNOMAD_BOOKINGS_QUERY, {\n variables: { first: 5, skip: 0 },\n });\n const properties = useQuery<{ ggnomadProperties: Array<{ id: string }> }>(\n GGNOMAD_PROPERTIES_QUERY,\n { variables: { first: 4, skip: 0 } }\n );\n const tours = useQuery<{ ggnomadTours: Array<{ id: string }> }>(GGNOMAD_TOURS_QUERY, {\n variables: { first: 4, skip: 0 },\n });\n const events = useQuery<{ ggnomadEvents: Array<{ id: string }> }>(GGNOMAD_EVENTS_QUERY, {\n variables: { first: 4, skip: 0 },\n });\n\n const stats = overview.data?.ggnomadOverviewStats;\n\n return (\n <PageShell\n title={t('ggnomad.dashboard.title', 'GGNomad Dashboard')}\n subtitle={t(\n 'ggnomad.dashboard.subtitle',\n 'Unified travel, hospitality, tourism and entertainment operations'\n )}\n >\n <section className=\"grid gap-4 md:grid-cols-4\">\n <div className=\"rounded-lg border p-4\">\n <p className=\"text-sm text-text-secondary\">\n {t('ggnomad.dashboard.stats.users', 'Users')}\n </p>\n <p className=\"text-2xl font-semibold\">{stats?.users ?? 0}</p>\n </div>\n <div className=\"rounded-lg border p-4\">\n <p className=\"text-sm text-text-secondary\">\n {t('ggnomad.dashboard.stats.listings', 'Listings')}\n </p>\n <p className=\"text-2xl font-semibold\">{stats?.listings ?? 0}</p>\n </div>\n <div className=\"rounded-lg border p-4\">\n <p className=\"text-sm text-text-secondary\">\n {t('ggnomad.dashboard.stats.bookings', 'Bookings')}\n </p>\n <p className=\"text-2xl font-semibold\">{stats?.bookings ?? 0}</p>\n </div>\n <div className=\"rounded-lg border p-4\">\n <p className=\"text-sm text-text-secondary\">\n {t('ggnomad.dashboard.stats.monthlyRevenue', 'Monthly Revenue')}\n </p>\n <p className=\"text-2xl font-semibold\">\n ${Number(stats?.monthlyRevenue ?? 0).toLocaleString()}\n </p>\n </div>\n </section>\n\n <section className=\"grid gap-4 lg:grid-cols-2\">\n <div className=\"rounded-lg border p-4\">\n <h2 className=\"mb-3 text-lg font-medium\">\n {t('ggnomad.dashboard.sections.recentBookings', 'Recent bookings')}\n </h2>\n <ul className=\"space-y-2 text-sm\">\n {(bookings.data?.ggnomadBookings ?? []).map(\n (booking: {\n id: string;\n referenceCode: string;\n itemName: string;\n status: string;\n }) => (\n <li\n key={booking.id}\n className=\"flex items-center justify-between rounded border p-2\"\n >\n <span>\n {booking.referenceCode} - {booking.itemName}\n </span>\n <span className=\"text-text-secondary\">{booking.status}</span>\n </li>\n )\n )}\n </ul>\n </div>\n <div className=\"rounded-lg border p-4\">\n <h2 className=\"mb-3 text-lg font-medium\">\n {t('ggnomad.dashboard.sections.featuredInventory', 'Featured inventory')}\n </h2>\n <div className=\"grid gap-2 text-sm\">\n <p>\n {t('ggnomad.dashboard.inventory.properties', 'Properties')}:{' '}\n {properties.data?.ggnomadProperties?.length ?? 0}\n </p>\n <p>\n {t('ggnomad.dashboard.inventory.tours', 'Tours')}:{' '}\n {tours.data?.ggnomadTours?.length ?? 0}\n </p>\n <p>\n {t('ggnomad.dashboard.inventory.events', 'Events')}:{' '}\n {events.data?.ggnomadEvents?.length ?? 0}\n </p>\n <p className=\"text-text-secondary\">\n {t(\n 'ggnomad.dashboard.inventory.liveDataNotice',\n 'Data is live from `wspace-ggnomad-svc` GraphQL APIs.'\n )}\n </p>\n </div>\n </div>\n </section>\n </PageShell>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/ggnomad/pages/DashboardPage.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 { Building, CalendarCheck, Compass, DollarSign, Hotel, Search, Users } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n EmphasisPanel,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n GGNOMAD_OVERVIEW_QUERY,\n GGNOMAD_BOOKINGS_QUERY,\n GGNOMAD_PROPERTIES_QUERY,\n GGNOMAD_TOURS_QUERY,\n GGNOMAD_EVENTS_QUERY,\n} from '../graphql';\nimport { PageShell } from './PageShell';\nimport { SectionCard, StatCard, StatusBadge } from '../components';\n\nexport function DashboardPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const overview = useQuery(\n GGNOMAD_OVERVIEW_QUERY as TypedDocumentNode<\n {\n ggnomadOverviewStats: {\n users: number;\n listings: number;\n bookings: number;\n monthlyRevenue: number;\n };\n },\n Record<string, never>\n >\n );\n const bookings = useQuery(\n GGNOMAD_BOOKINGS_QUERY as TypedDocumentNode<\n {\n ggnomadBookings: Array<{\n id: string;\n referenceCode: string;\n itemName: string;\n status: string;\n }>;\n },\n { first: number; skip: number }\n >,\n {\n variables: { first: 5, skip: 0 },\n }\n );\n const properties = useQuery(\n GGNOMAD_PROPERTIES_QUERY as TypedDocumentNode<\n { ggnomadProperties: Array<{ id: string }> },\n { first: number; skip: number }\n >,\n { variables: { first: 4, skip: 0 } }\n );\n const tours = useQuery(\n GGNOMAD_TOURS_QUERY as TypedDocumentNode<\n { ggnomadTours: Array<{ id: string }> },\n { first: number; skip: number }\n >,\n {\n variables: { first: 4, skip: 0 },\n }\n );\n const events = useQuery(\n GGNOMAD_EVENTS_QUERY as TypedDocumentNode<\n { ggnomadEvents: Array<{ id: string }> },\n { first: number; skip: number }\n >,\n {\n variables: { first: 4, skip: 0 },\n }\n );\n\n const stats = overview.data?.ggnomadOverviewStats;\n const recentBookings = bookings.data?.ggnomadBookings ?? [];\n\n return (\n <PageShell\n hero\n title={t('ggnomad.dashboard.title', 'GGNomad Dashboard')}\n titleAccent={t('ggnomad.dashboard.title.accent', 'GGNomad')}\n subtitle={t(\n 'ggnomad.dashboard.subtitle',\n 'Unified travel, hospitality, tourism and entertainment operations'\n )}\n >\n <PagePurpose icon={<Compass className=\"size-4\" />}>\n {t(\n 'ggnomad.dashboard.purpose',\n 'Your command centre for the whole GGNomad marketplace — see live revenue, users, listings and bookings across travel, hospitality, tourism and entertainment in one place, and jump straight into the area you want to work on.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"ggnomad-dashboard\"\n steps={[\n {\n id: 'search',\n label: t('ggnomad.dashboard.next.search', 'Search the catalogue'),\n description: t(\n 'ggnomad.dashboard.next.searchDesc',\n 'Find inventory across every domain at once.'\n ),\n icon: <Search className=\"size-4\" />,\n onClick: () => navigate('search'),\n },\n {\n id: 'stays',\n label: t('ggnomad.dashboard.next.stays', 'Browse places to stay'),\n description: t(\n 'ggnomad.dashboard.next.staysDesc',\n 'Explore hospitality listings and open a property.'\n ),\n icon: <Hotel className=\"size-4\" />,\n onClick: () => navigate('hospitality'),\n },\n {\n id: 'tourism',\n label: t('ggnomad.dashboard.next.tourism', 'Discover tours & activities'),\n description: t(\n 'ggnomad.dashboard.next.tourismDesc',\n 'Plan what to do at each destination.'\n ),\n icon: <Compass className=\"size-4\" />,\n onClick: () => navigate('tourism'),\n },\n {\n id: 'bookings',\n label: t('ggnomad.dashboard.next.bookings', 'Manage bookings'),\n description: t(\n 'ggnomad.dashboard.next.bookingsDesc',\n 'Track and cancel reservations in real time.'\n ),\n icon: <CalendarCheck className=\"size-4\" />,\n onClick: () => navigate('bookings'),\n },\n ]}\n />\n\n <section className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n <StatCard\n hero\n label={t('ggnomad.dashboard.stats.monthlyRevenue', 'Monthly Revenue')}\n value={`$${Number(stats?.monthlyRevenue ?? 0).toLocaleString()}`}\n icon={<DollarSign />}\n />\n <StatCard\n label={t('ggnomad.dashboard.stats.users', 'Users')}\n value={Number(stats?.users ?? 0).toLocaleString()}\n icon={<Users />}\n />\n <StatCard\n label={t('ggnomad.dashboard.stats.listings', 'Listings')}\n value={Number(stats?.listings ?? 0).toLocaleString()}\n icon={<Building />}\n />\n <StatCard\n label={t('ggnomad.dashboard.stats.bookings', 'Bookings')}\n value={Number(stats?.bookings ?? 0).toLocaleString()}\n icon={<CalendarCheck />}\n />\n </section>\n\n <EmphasisPanel>\n <div className=\"grid gap-4 sm:grid-cols-3\">\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('ggnomad.dashboard.inventory.properties', 'Properties')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {properties.data?.ggnomadProperties?.length ?? 0}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('ggnomad.dashboard.inventory.tours', 'Tours')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {tours.data?.ggnomadTours?.length ?? 0}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">\n {t('ggnomad.dashboard.inventory.events', 'Events')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {events.data?.ggnomadEvents?.length ?? 0}\n </p>\n </div>\n </div>\n <p className=\"mt-4 text-sm text-text-secondary\">\n {t(\n 'ggnomad.dashboard.inventory.liveDataNotice',\n 'Data is live from `wspace-ggnomad-svc` GraphQL APIs.'\n )}\n </p>\n </EmphasisPanel>\n\n <SectionCard title={t('ggnomad.dashboard.sections.recentBookings', 'Recent bookings')}>\n {recentBookings.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.dashboard.recentBookings.emptyTitle', 'No recent bookings')}\n description={t(\n 'ggnomad.dashboard.recentBookings.emptyDescription',\n 'New bookings across travel, hospitality and tourism will appear here.'\n )}\n />\n ) : (\n <ul className=\"space-y-2 text-sm\">\n {recentBookings.map((booking) => (\n <li\n key={booking.id}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border-seam bg-bg-surface/40 p-3\"\n >\n <span className=\"min-w-0 truncate text-text-primary\">\n {booking.referenceCode} — {booking.itemName}\n </span>\n <StatusBadge status={booking.status} />\n </li>\n ))}\n </ul>\n )}\n </SectionCard>\n </PageShell>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,43 +1,50 @@
|
|
|
1
1
|
import { GGNOMAD_EVENTS_QUERY as e } from "../graphql.js";
|
|
2
2
|
import { PageShell as t } from "./PageShell.js";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
3
|
+
import { EntityCard as n } from "../components/EntityCard.js";
|
|
4
|
+
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
10
|
//#region src/ggnomad/pages/EntertainmentPage.tsx
|
|
7
|
-
function
|
|
8
|
-
let { data:
|
|
11
|
+
function d() {
|
|
12
|
+
let { t: d } = i(), { data: f } = a(e, { variables: {
|
|
9
13
|
first: 20,
|
|
10
14
|
skip: 0
|
|
11
|
-
} });
|
|
12
|
-
return /* @__PURE__ */
|
|
13
|
-
title: "Entertainment",
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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, {
|
|
24
|
+
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, {
|
|
28
|
+
treatment: "glass",
|
|
29
|
+
glow: !0,
|
|
30
|
+
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
|
+
})]
|
|
44
|
+
})]
|
|
38
45
|
});
|
|
39
46
|
}
|
|
40
47
|
//#endregion
|
|
41
|
-
export {
|
|
48
|
+
export { d as EntertainmentPage };
|
|
42
49
|
|
|
43
50
|
//# 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 {
|
|
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,49 +1,96 @@
|
|
|
1
1
|
import { GGNOMAD_EVENT_QUERY as e } from "../graphql.js";
|
|
2
2
|
import { PageShell as t } from "./PageShell.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
3
|
+
import { SectionCard as n } from "../components/SectionCard.js";
|
|
4
|
+
import { DetailRow as r } from "../components/DetailRow.js";
|
|
5
|
+
import "../components/index.js";
|
|
6
|
+
import { CalendarCheck as i, Mic2 as a, Ticket as o } from "lucide-react";
|
|
7
|
+
import { useI18n as s } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
8
|
+
import { useNavigate as c, useParams as l } from "react-router-dom";
|
|
9
|
+
import { useQuery as u } from "@apollo/client/react";
|
|
10
|
+
import { GlassCard as d, IllustratedEmptyState as f, NextSteps as p, PagePurpose as m } from "@burdenoff/fe-libs/ui";
|
|
11
|
+
import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
6
12
|
//#region src/ggnomad/pages/EventDetailsPage.tsx
|
|
7
|
-
function
|
|
8
|
-
let { id:
|
|
9
|
-
variables: { id:
|
|
10
|
-
skip: !
|
|
11
|
-
}),
|
|
12
|
-
return /* @__PURE__ */
|
|
13
|
-
title:
|
|
14
|
-
subtitle: "Live event details, venue and lineup",
|
|
15
|
-
children:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
13
|
+
function v() {
|
|
14
|
+
let { t: v } = s(), y = c(), { id: b = "" } = l(), { data: x } = u(e, {
|
|
15
|
+
variables: { id: b },
|
|
16
|
+
skip: !b
|
|
17
|
+
}), S = x?.ggnomadEvent;
|
|
18
|
+
return /* @__PURE__ */ g(t, {
|
|
19
|
+
title: S?.name ?? v("ggnomad.event.fallbackTitle", "Event details"),
|
|
20
|
+
subtitle: v("ggnomad.event.subtitle", "Live event details, venue and lineup"),
|
|
21
|
+
children: S ? /* @__PURE__ */ _(h, { children: [
|
|
22
|
+
/* @__PURE__ */ g(m, {
|
|
23
|
+
icon: /* @__PURE__ */ g(o, { className: "size-4" }),
|
|
24
|
+
children: v("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.")
|
|
25
|
+
}),
|
|
26
|
+
/* @__PURE__ */ g(p, {
|
|
27
|
+
storageKey: "ggnomad-event-detail",
|
|
28
|
+
steps: [{
|
|
29
|
+
id: "book",
|
|
30
|
+
label: v("ggnomad.event.next.book", "Book tickets"),
|
|
31
|
+
description: v("ggnomad.event.next.bookDesc", "Reserve seats and track them under Bookings."),
|
|
32
|
+
icon: /* @__PURE__ */ g(i, { className: "size-4" }),
|
|
33
|
+
onClick: () => y("../../bookings")
|
|
34
|
+
}, {
|
|
35
|
+
id: "browse",
|
|
36
|
+
label: v("ggnomad.event.next.browse", "See more events"),
|
|
37
|
+
description: v("ggnomad.event.next.browseDesc", "Return to Entertainment for other live experiences."),
|
|
38
|
+
icon: /* @__PURE__ */ g(o, { className: "size-4" }),
|
|
39
|
+
onClick: () => y("..")
|
|
40
|
+
}]
|
|
41
|
+
}),
|
|
42
|
+
/* @__PURE__ */ _("div", {
|
|
43
|
+
className: "grid gap-4 lg:grid-cols-2",
|
|
44
|
+
children: [/* @__PURE__ */ _(d, {
|
|
45
|
+
treatment: "glass",
|
|
46
|
+
glow: !0,
|
|
47
|
+
className: "border-border-seam p-5",
|
|
48
|
+
children: [/* @__PURE__ */ g("h2", {
|
|
49
|
+
className: "mb-4 text-lg font-medium tracking-tight text-text-primary",
|
|
50
|
+
children: v("ggnomad.event.details", "Details")
|
|
51
|
+
}), /* @__PURE__ */ _("dl", {
|
|
52
|
+
className: "space-y-2 text-sm",
|
|
53
|
+
children: [
|
|
54
|
+
/* @__PURE__ */ g(r, {
|
|
55
|
+
label: v("ggnomad.event.category", "Category"),
|
|
56
|
+
value: S.category
|
|
57
|
+
}),
|
|
58
|
+
/* @__PURE__ */ g(r, {
|
|
59
|
+
label: v("ggnomad.event.starts", "Starts"),
|
|
60
|
+
value: new Date(S.startsAt).toLocaleString()
|
|
61
|
+
}),
|
|
62
|
+
/* @__PURE__ */ g(r, {
|
|
63
|
+
label: v("ggnomad.event.ends", "Ends"),
|
|
64
|
+
value: S.endsAt ? new Date(S.endsAt).toLocaleString() : v("ggnomad.event.na", "N/A")
|
|
65
|
+
}),
|
|
66
|
+
/* @__PURE__ */ g(r, {
|
|
67
|
+
label: v("ggnomad.event.price", "Price"),
|
|
68
|
+
value: `${S.currency} ${Number(S.price).toFixed(2)}`
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
})]
|
|
72
|
+
}), /* @__PURE__ */ g(n, {
|
|
73
|
+
title: v("ggnomad.event.performers", "Performers"),
|
|
74
|
+
children: /* @__PURE__ */ g("ul", {
|
|
75
|
+
className: "space-y-2 text-sm",
|
|
76
|
+
children: (S.performers ?? []).map((e) => /* @__PURE__ */ _("li", {
|
|
77
|
+
className: "flex items-start gap-2 text-text-primary",
|
|
78
|
+
children: [/* @__PURE__ */ g(a, {
|
|
79
|
+
className: "mt-0.5 size-4 flex-shrink-0 text-action-primary-bg",
|
|
80
|
+
"aria-hidden": "true"
|
|
81
|
+
}), e]
|
|
82
|
+
}, e))
|
|
83
|
+
})
|
|
38
84
|
})]
|
|
39
|
-
})
|
|
40
|
-
}) : /* @__PURE__ */
|
|
41
|
-
|
|
42
|
-
|
|
85
|
+
})
|
|
86
|
+
] }) : /* @__PURE__ */ g(f, {
|
|
87
|
+
illustration: "empty-data",
|
|
88
|
+
title: v("ggnomad.event.notFoundTitle", "No event found"),
|
|
89
|
+
description: v("ggnomad.event.notFoundDescription", "This event is unavailable or may have been removed.")
|
|
43
90
|
})
|
|
44
91
|
});
|
|
45
92
|
}
|
|
46
93
|
//#endregion
|
|
47
|
-
export {
|
|
94
|
+
export { v as EventDetailsPage };
|
|
48
95
|
|
|
49
96
|
//# 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 { useParams } from 'react-router-dom';\n\nimport { GGNOMAD_EVENT_QUERY } from '../graphql';\nimport { PageShell } from './PageShell';\n\nexport function EventDetailsPage() {\n const { id = '' } = useParams();\n const { data } = useQuery
|
|
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 { CalendarCheck, Mic2, Ticket } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, NextSteps, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_EVENT_QUERY } from '../graphql';\nimport { PageShell } from './PageShell';\nimport { DetailRow, SectionCard } from '../components';\n\nexport function EventDetailsPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { id = '' } = useParams();\n const { data } = useQuery(\n GGNOMAD_EVENT_QUERY as TypedDocumentNode<\n {\n ggnomadEvent: {\n name: string;\n category: string;\n startsAt: string;\n endsAt?: string;\n currency: string;\n price: number;\n performers: 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 <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: 'book',\n label: t('ggnomad.event.next.book', 'Book tickets'),\n description: t(\n 'ggnomad.event.next.bookDesc',\n 'Reserve seats and track them under Bookings.'\n ),\n icon: <CalendarCheck className=\"size-4\" />,\n onClick: () => navigate('../../bookings'),\n },\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('..'),\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.event.details', 'Details')}\n </h2>\n <dl className=\"space-y-2 text-sm\">\n <DetailRow label={t('ggnomad.event.category', 'Category')} value={event.category} />\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 </>\n )}\n </PageShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAWA,SAAgB,IAAmB;CACjC,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,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;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,2BAA2B,eAAe;KACnD,aAAa,EACX,+BACA,+CACD;KACD,MAAM,kBAAC,GAAD,EAAe,WAAU,UAAW,CAAA;KAC1C,eAAe,EAAS,iBAAiB;KAC1C,EACD;KACE,IAAI;KACJ,OAAO,EAAE,6BAA6B,kBAAkB;KACxD,aAAa,EACX,iCACA,sDACD;KACD,MAAM,kBAAC,GAAD,EAAQ,WAAU,UAAW,CAAA;KACnC,eAAe,EAAS,KAAK;KAC9B,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,yBAAyB,UAAU;MACnC,CAAA,EACL,kBAAC,MAAD;MAAI,WAAU;gBAAd;OACE,kBAAC,GAAD;QAAW,OAAO,EAAE,0BAA0B,WAAW;QAAE,OAAO,EAAM;QAAY,CAAA;OACpF,kBAAC,GAAD;QACE,OAAO,EAAE,wBAAwB,SAAS;QAC1C,OAAO,IAAI,KAAK,EAAM,SAAS,CAAC,gBAAgB;QAChD,CAAA;OACF,kBAAC,GAAD;QACE,OAAO,EAAE,sBAAsB,OAAO;QACtC,OACE,EAAM,SACF,IAAI,KAAK,EAAM,OAAO,CAAC,gBAAgB,GACvC,EAAE,oBAAoB,MAAM;QAElC,CAAA;OACF,kBAAC,GAAD;QACE,OAAO,EAAE,uBAAuB,QAAQ;QACxC,OAAO,GAAG,EAAM,SAAS,GAAG,OAAO,EAAM,MAAM,CAAC,QAAQ,EAAE;QAC1D,CAAA;OACC;QACK;QACZ,kBAAC,GAAD;KAAa,OAAO,EAAE,4BAA4B,aAAa;eAC7D,kBAAC,MAAD;MAAI,WAAU;iBACV,EAAM,cAAc,EAAE,EAAE,KAAK,MAC7B,kBAAC,MAAD;OAAoB,WAAU;iBAA9B,CACE,kBAAC,GAAD;QACE,WAAU;QACV,eAAY;QACZ,CAAA,EACD,EACE;SANI,EAMJ,CACL;MACC,CAAA;KACO,CAAA,CACV;;GACL,EAAA,CAAA,GAlFH,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,+BAA+B,iBAAiB;GACzD,aAAa,EACX,qCACA,sDACD;GACD,CAAA;EA6EM,CAAA"}
|