@burdenoff/microfe-ggnomad 2026.705.5 → 2026.705.7

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.
@@ -6,103 +6,136 @@ import { DetailHero as i } from "../components/DetailHero.js";
6
6
  import { useGGNomad as a } from "../providers/GGNomadProvider.js";
7
7
  import { joinPath as o } from "../utils/navigation.js";
8
8
  import { BookingPanel as s } from "../components/BookingPanel.js";
9
+ import { ReviewsSection as c } from "../components/ReviewsSection.js";
10
+ import { ListingEditDialog as l } from "../components/ListingEditDialog.js";
9
11
  import "../components/index.js";
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";
12
+ import { useState as u } from "react";
13
+ import { Mic2 as d, Pencil as f, Ticket as p } from "lucide-react";
14
+ import { useI18n as m } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
+ import { useNavigate as h, useParams as g } from "react-router-dom";
16
+ import { useQuery as _ } from "@apollo/client/react";
17
+ import { GlassCard as v, IllustratedEmptyState as y, NextSteps as b, PagePurpose as x } from "@burdenoff/fe-libs/ui";
18
+ import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
16
19
  //#region src/ggnomad/pages/EventDetailsPage.tsx
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
20
+ function T() {
21
+ let { t: T } = m(), E = h(), { basePath: D = "/" } = a(), { id: O = "" } = g(), [k, A] = u(!1), { data: j, refetch: M } = _(e, {
22
+ variables: { id: O },
23
+ skip: !O
24
+ }), N = j?.ggnomadEvent;
25
+ return /* @__PURE__ */ C(t, {
26
+ title: N?.name ?? T("ggnomad.event.fallbackTitle", "Event details"),
27
+ subtitle: T("ggnomad.event.subtitle", "Live event details, venue and lineup"),
28
+ children: N ? /* @__PURE__ */ w(S, { children: [
29
+ /* @__PURE__ */ C(i, {
30
+ image: N.images?.[0],
31
+ alt: N.name
29
32
  }),
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
+ /* @__PURE__ */ C(x, {
34
+ icon: /* @__PURE__ */ C(p, { className: "size-4" }),
35
+ children: T("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
36
  }),
34
- /* @__PURE__ */ y(g, {
37
+ /* @__PURE__ */ C(b, {
35
38
  storageKey: "ggnomad-event-detail",
36
39
  steps: [{
37
40
  id: "browse",
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"))
41
+ label: T("ggnomad.event.next.browse", "See more events"),
42
+ description: T("ggnomad.event.next.browseDesc", "Return to Entertainment for other live experiences."),
43
+ icon: /* @__PURE__ */ C(p, { className: "size-4" }),
44
+ onClick: () => E(o(D, "entertainment"))
42
45
  }]
43
46
  }),
44
- /* @__PURE__ */ b("div", {
47
+ /* @__PURE__ */ w("div", {
45
48
  className: "grid gap-4 lg:grid-cols-3",
46
- children: [/* @__PURE__ */ b("div", {
49
+ children: [/* @__PURE__ */ w("div", {
47
50
  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))
51
+ children: [
52
+ /* @__PURE__ */ w(v, {
53
+ treatment: "glass",
54
+ glow: !0,
55
+ className: "border-border-seam p-5",
56
+ children: [/* @__PURE__ */ w("div", {
57
+ className: "mb-4 flex items-center justify-between gap-3",
58
+ children: [/* @__PURE__ */ C("h2", {
59
+ className: "text-lg font-medium tracking-tight text-text-primary",
60
+ children: T("ggnomad.event.details", "Details")
61
+ }), /* @__PURE__ */ C("button", {
62
+ onClick: () => A(!0),
63
+ className: "rounded-md p-2 text-text-secondary hover:bg-action-primary-bg hover:text-action-primary-text",
64
+ "aria-label": T("ggnomad.event.editListing", "Edit listing"),
65
+ title: T("ggnomad.event.editListing", "Edit listing"),
66
+ children: /* @__PURE__ */ C(f, { className: "size-4" })
67
+ })]
68
+ }), /* @__PURE__ */ w("dl", {
69
+ className: "space-y-2 text-sm",
70
+ children: [
71
+ /* @__PURE__ */ C(r, {
72
+ label: T("ggnomad.event.category", "Category"),
73
+ value: N.category
74
+ }),
75
+ /* @__PURE__ */ C(r, {
76
+ label: T("ggnomad.event.starts", "Starts"),
77
+ value: new Date(N.startsAt).toLocaleString()
78
+ }),
79
+ /* @__PURE__ */ C(r, {
80
+ label: T("ggnomad.event.ends", "Ends"),
81
+ value: N.endsAt ? new Date(N.endsAt).toLocaleString() : T("ggnomad.event.na", "N/A")
82
+ }),
83
+ /* @__PURE__ */ C(r, {
84
+ label: T("ggnomad.event.price", "Price"),
85
+ value: `${N.currency} ${Number(N.price).toFixed(2)}`
86
+ })
87
+ ]
88
+ })]
89
+ }),
90
+ /* @__PURE__ */ C(n, {
91
+ title: T("ggnomad.event.performers", "Performers"),
92
+ children: /* @__PURE__ */ C("ul", {
93
+ className: "space-y-2 text-sm",
94
+ children: (N.performers ?? []).map((e) => /* @__PURE__ */ w("li", {
95
+ className: "flex items-start gap-2 text-text-primary",
96
+ children: [/* @__PURE__ */ C(d, {
97
+ className: "mt-0.5 size-4 flex-shrink-0 text-action-primary-bg",
98
+ "aria-hidden": "true"
99
+ }), e]
100
+ }, e))
101
+ })
102
+ }),
103
+ /* @__PURE__ */ C(c, {
104
+ targetType: "EVENT",
105
+ targetId: N.id ?? O
87
106
  })
88
- })]
89
- }), /* @__PURE__ */ y("div", { children: /* @__PURE__ */ y(s, {
107
+ ]
108
+ }), /* @__PURE__ */ C("div", { children: /* @__PURE__ */ C(s, {
90
109
  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
110
+ itemId: N.id ?? O,
111
+ itemName: N.name,
112
+ unitPrice: N.price ?? 0,
113
+ currency: N.currency ?? "USD",
114
+ eventDate: N.startsAt
96
115
  }) })]
116
+ }),
117
+ /* @__PURE__ */ C(l, {
118
+ open: k,
119
+ onOpenChange: A,
120
+ targetType: "EVENT",
121
+ id: N.id ?? O,
122
+ initial: {
123
+ name: N.name,
124
+ description: N.description,
125
+ price: N.price,
126
+ status: N.status,
127
+ images: N.images
128
+ },
129
+ onSaved: () => M()
97
130
  })
98
- ] }) : /* @__PURE__ */ y(h, {
131
+ ] }) : /* @__PURE__ */ C(y, {
99
132
  illustration: "empty-data",
100
- title: x("ggnomad.event.notFoundTitle", "No event found"),
101
- description: x("ggnomad.event.notFoundDescription", "This event is unavailable or may have been removed.")
133
+ title: T("ggnomad.event.notFoundTitle", "No event found"),
134
+ description: T("ggnomad.event.notFoundDescription", "This event is unavailable or may have been removed.")
102
135
  })
103
136
  });
104
137
  }
105
138
  //#endregion
106
- export { x as EventDetailsPage };
139
+ export { T as EventDetailsPage };
107
140
 
108
141
  //# 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 { 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
+ {"version":3,"file":"EventDetailsPage.js","names":[],"sources":["../../../src/ggnomad/pages/EventDetailsPage.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 { useNavigate, useParams } from 'react-router-dom';\nimport { Mic2, Pencil, 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 {\n DetailRow,\n SectionCard,\n DetailHero,\n BookingPanel,\n ReviewsSection,\n ListingEditDialog,\n} from '../components';\n\nexport function EventDetailsPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { basePath = '/' } = useGGNomad();\n const { id = '' } = useParams();\n const [editDialogOpen, setEditDialogOpen] = useState(false);\n const { data, refetch } = useQuery(\n GGNOMAD_EVENT_QUERY as TypedDocumentNode<\n {\n ggnomadEvent: {\n id: string;\n name: string;\n description?: string;\n category: string;\n startsAt: string;\n endsAt?: string;\n currency: string;\n price: number;\n status?: string;\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 <div className=\"mb-4 flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.event.details', 'Details')}\n </h2>\n <button\n onClick={() => setEditDialogOpen(true)}\n className=\"rounded-md p-2 text-text-secondary hover:bg-action-primary-bg hover:text-action-primary-text\"\n aria-label={t('ggnomad.event.editListing', 'Edit listing')}\n title={t('ggnomad.event.editListing', 'Edit listing')}\n >\n <Pencil className=\"size-4\" />\n </button>\n </div>\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 <ReviewsSection targetType=\"EVENT\" targetId={event.id ?? id} />\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 <ListingEditDialog\n open={editDialogOpen}\n onOpenChange={setEditDialogOpen}\n targetType=\"EVENT\"\n id={event.id ?? id}\n initial={{\n name: event.name,\n description: event.description,\n price: event.price,\n status: event.status,\n images: event.images,\n }}\n onSaved={() => refetch()}\n />\n </>\n )}\n </PageShell>\n );\n}\n"],"mappings":"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"}
@@ -6,111 +6,144 @@ import { DetailHero as i } from "../components/DetailHero.js";
6
6
  import { useGGNomad as a } from "../providers/GGNomadProvider.js";
7
7
  import { joinPath as o } from "../utils/navigation.js";
8
8
  import { BookingPanel as s } from "../components/BookingPanel.js";
9
+ import { ReviewsSection as c } from "../components/ReviewsSection.js";
10
+ import { ListingEditDialog as l } from "../components/ListingEditDialog.js";
9
11
  import "../components/index.js";
10
- import { Hotel as c } from "lucide-react";
11
- import { useI18n as l } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
12
- import { useNavigate as u, useParams as d } from "react-router-dom";
13
- import { useQuery as f } from "@apollo/client/react";
14
- import { GlassCard as p, IllustratedEmptyState as m, NextSteps as h, PagePurpose as g } from "@burdenoff/fe-libs/ui";
15
- import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
12
+ import { useState as u } from "react";
13
+ import { Hotel as d, Pencil as f } from "lucide-react";
14
+ import { useI18n as p } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
+ import { useNavigate as m, useParams as h } from "react-router-dom";
16
+ import { useQuery as g } from "@apollo/client/react";
17
+ import { GlassCard as _, IllustratedEmptyState as v, NextSteps as y, PagePurpose as b } from "@burdenoff/fe-libs/ui";
18
+ import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
16
19
  //#region src/ggnomad/pages/PropertyDetailsPage.tsx
17
- function b() {
18
- let { t: b } = l(), x = u(), { basePath: S = "/" } = a(), { id: C = "" } = d(), { data: w } = f(e, {
19
- variables: { id: C },
20
- skip: !C
21
- }), T = w?.ggnomadProperty;
22
- return /* @__PURE__ */ v(t, {
23
- title: T?.name ?? b("ggnomad.property.fallbackTitle", "Property details"),
24
- subtitle: b("ggnomad.property.subtitle", "Detailed hospitality listing view"),
25
- children: T ? /* @__PURE__ */ y(_, { children: [
26
- /* @__PURE__ */ v(i, {
27
- image: T.images?.[0],
28
- alt: T.name
20
+ function w() {
21
+ let { t: w } = p(), T = m(), { basePath: E = "/" } = a(), { id: D = "" } = h(), [O, k] = u(!1), { data: A, refetch: j } = g(e, {
22
+ variables: { id: D },
23
+ skip: !D
24
+ }), M = A?.ggnomadProperty;
25
+ return /* @__PURE__ */ S(t, {
26
+ title: M?.name ?? w("ggnomad.property.fallbackTitle", "Property details"),
27
+ subtitle: w("ggnomad.property.subtitle", "Detailed hospitality listing view"),
28
+ children: M ? /* @__PURE__ */ C(x, { children: [
29
+ /* @__PURE__ */ S(i, {
30
+ image: M.images?.[0],
31
+ alt: M.name
29
32
  }),
30
- /* @__PURE__ */ v(g, {
31
- icon: /* @__PURE__ */ v(c, { className: "size-4" }),
32
- children: b("ggnomad.property.purpose", "Everything you need to decide on this stay — its type, description, nightly price, guest capacity, rating and the provider behind it — before you reserve it.")
33
+ /* @__PURE__ */ S(b, {
34
+ icon: /* @__PURE__ */ S(d, { className: "size-4" }),
35
+ children: w("ggnomad.property.purpose", "Everything you need to decide on this stay — its type, description, nightly price, guest capacity, rating and the provider behind it — before you reserve it.")
33
36
  }),
34
- /* @__PURE__ */ v(h, {
37
+ /* @__PURE__ */ S(y, {
35
38
  storageKey: "ggnomad-property-detail",
36
39
  steps: [{
37
40
  id: "browse",
38
- label: b("ggnomad.property.next.browse", "Compare other stays"),
39
- description: b("ggnomad.property.next.browseDesc", "Go back to hospitality listings to compare options."),
40
- icon: /* @__PURE__ */ v(c, { className: "size-4" }),
41
- onClick: () => x(o(S, "hospitality"))
41
+ label: w("ggnomad.property.next.browse", "Compare other stays"),
42
+ description: w("ggnomad.property.next.browseDesc", "Go back to hospitality listings to compare options."),
43
+ icon: /* @__PURE__ */ S(d, { className: "size-4" }),
44
+ onClick: () => T(o(E, "hospitality"))
42
45
  }]
43
46
  }),
44
- /* @__PURE__ */ y("div", {
47
+ /* @__PURE__ */ C("div", {
45
48
  className: "grid gap-4 lg:grid-cols-3",
46
- children: [/* @__PURE__ */ y("div", {
49
+ children: [/* @__PURE__ */ C("div", {
47
50
  className: "lg:col-span-2 space-y-4",
48
- children: [/* @__PURE__ */ y(n, {
49
- title: b("ggnomad.property.about", "About"),
50
- children: [
51
- /* @__PURE__ */ v("p", {
52
- className: "text-sm text-text-secondary",
53
- children: b("ggnomad.property.type", "Type")
54
- }),
55
- /* @__PURE__ */ v("p", {
56
- className: "text-text-primary",
57
- children: T.type
58
- }),
59
- /* @__PURE__ */ v("p", {
60
- className: "mt-3 text-sm text-text-secondary",
61
- children: b("ggnomad.property.description", "Description")
62
- }),
63
- /* @__PURE__ */ v("p", {
64
- className: "text-text-primary",
65
- children: T.description ?? b("ggnomad.property.noDescription", "No description")
66
- })
67
- ]
68
- }), /* @__PURE__ */ y(p, {
69
- treatment: "glass",
70
- glow: !0,
71
- className: "border-border-seam p-5",
72
- children: [/* @__PURE__ */ v("h2", {
73
- className: "mb-4 text-lg font-medium tracking-tight text-text-primary",
74
- children: b("ggnomad.property.details", "Details")
75
- }), /* @__PURE__ */ y("dl", {
76
- className: "space-y-2 text-sm",
51
+ children: [
52
+ /* @__PURE__ */ C(n, {
53
+ title: w("ggnomad.property.about", "About"),
77
54
  children: [
78
- /* @__PURE__ */ v(r, {
79
- label: b("ggnomad.property.price", "Price"),
80
- value: `${T.currency} ${Number(T.pricePerNight).toFixed(2)}`
55
+ /* @__PURE__ */ S("p", {
56
+ className: "text-sm text-text-secondary",
57
+ children: w("ggnomad.property.type", "Type")
81
58
  }),
82
- /* @__PURE__ */ v(r, {
83
- label: b("ggnomad.property.guests", "Guests"),
84
- value: String(T.maxGuests)
59
+ /* @__PURE__ */ S("p", {
60
+ className: "text-text-primary",
61
+ children: M.type
85
62
  }),
86
- /* @__PURE__ */ v(r, {
87
- label: b("ggnomad.property.rating", "Rating"),
88
- value: String(T.rating ?? b("ggnomad.property.noRating", "N/A"))
63
+ /* @__PURE__ */ S("p", {
64
+ className: "mt-3 text-sm text-text-secondary",
65
+ children: w("ggnomad.property.description", "Description")
89
66
  }),
90
- /* @__PURE__ */ v(r, {
91
- label: b("ggnomad.property.provider", "Provider"),
92
- value: T.provider?.name ?? b("ggnomad.property.unassigned", "Unassigned")
67
+ /* @__PURE__ */ S("p", {
68
+ className: "text-text-primary",
69
+ children: M.description ?? w("ggnomad.property.noDescription", "No description")
93
70
  })
94
71
  ]
95
- })]
96
- })]
97
- }), /* @__PURE__ */ v("div", { children: /* @__PURE__ */ v(s, {
72
+ }),
73
+ /* @__PURE__ */ C(_, {
74
+ treatment: "glass",
75
+ glow: !0,
76
+ className: "border-border-seam p-5",
77
+ children: [/* @__PURE__ */ C("div", {
78
+ className: "mb-4 flex items-center justify-between gap-3",
79
+ children: [/* @__PURE__ */ S("h2", {
80
+ className: "text-lg font-medium tracking-tight text-text-primary",
81
+ children: w("ggnomad.property.details", "Details")
82
+ }), /* @__PURE__ */ S("button", {
83
+ onClick: () => k(!0),
84
+ className: "rounded-md p-2 text-text-secondary hover:bg-action-primary-bg hover:text-action-primary-text",
85
+ "aria-label": w("ggnomad.property.editListing", "Edit listing"),
86
+ title: w("ggnomad.property.editListing", "Edit listing"),
87
+ children: /* @__PURE__ */ S(f, { className: "size-4" })
88
+ })]
89
+ }), /* @__PURE__ */ C("dl", {
90
+ className: "space-y-2 text-sm",
91
+ children: [
92
+ /* @__PURE__ */ S(r, {
93
+ label: w("ggnomad.property.price", "Price"),
94
+ value: `${M.currency} ${Number(M.pricePerNight).toFixed(2)}`
95
+ }),
96
+ /* @__PURE__ */ S(r, {
97
+ label: w("ggnomad.property.guests", "Guests"),
98
+ value: String(M.maxGuests)
99
+ }),
100
+ /* @__PURE__ */ S(r, {
101
+ label: w("ggnomad.property.rating", "Rating"),
102
+ value: String(M.rating ?? w("ggnomad.property.noRating", "N/A"))
103
+ }),
104
+ /* @__PURE__ */ S(r, {
105
+ label: w("ggnomad.property.provider", "Provider"),
106
+ value: M.provider?.name ?? w("ggnomad.property.unassigned", "Unassigned")
107
+ })
108
+ ]
109
+ })]
110
+ }),
111
+ /* @__PURE__ */ S(c, {
112
+ targetType: "PROPERTY",
113
+ targetId: M.id ?? D
114
+ })
115
+ ]
116
+ }), /* @__PURE__ */ S("div", { children: /* @__PURE__ */ S(s, {
98
117
  bookingType: "PROPERTY",
99
- itemId: T.id ?? C,
100
- itemName: T.name,
101
- unitPrice: T.pricePerNight ?? 0,
102
- currency: T.currency ?? "USD",
118
+ itemId: M.id ?? D,
119
+ itemName: M.name,
120
+ unitPrice: M.pricePerNight ?? 0,
121
+ currency: M.currency ?? "USD",
103
122
  nights: 1
104
123
  }) })]
124
+ }),
125
+ /* @__PURE__ */ S(l, {
126
+ open: O,
127
+ onOpenChange: k,
128
+ targetType: "PROPERTY",
129
+ id: M.id ?? D,
130
+ initial: {
131
+ name: M.name,
132
+ description: M.description,
133
+ pricePerNight: M.pricePerNight,
134
+ status: M.status,
135
+ images: M.images
136
+ },
137
+ onSaved: () => j()
105
138
  })
106
- ] }) : /* @__PURE__ */ v(m, {
139
+ ] }) : /* @__PURE__ */ S(v, {
107
140
  illustration: "empty-data",
108
- title: b("ggnomad.property.notFoundTitle", "No property found"),
109
- description: b("ggnomad.property.notFoundDescription", "This property is unavailable or may have been removed.")
141
+ title: w("ggnomad.property.notFoundTitle", "No property found"),
142
+ description: w("ggnomad.property.notFoundDescription", "This property is unavailable or may have been removed.")
110
143
  })
111
144
  });
112
145
  }
113
146
  //#endregion
114
- export { b as PropertyDetailsPage };
147
+ export { w as PropertyDetailsPage };
115
148
 
116
149
  //# sourceMappingURL=PropertyDetailsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyDetailsPage.js","names":[],"sources":["../../../src/ggnomad/pages/PropertyDetailsPage.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 { Hotel } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, NextSteps, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_PROPERTY_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 PropertyDetailsPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { basePath = '/' } = useGGNomad();\n const { id = '' } = useParams();\n const { data } = useQuery(\n GGNOMAD_PROPERTY_QUERY as TypedDocumentNode<\n {\n ggnomadProperty: {\n id: string;\n name: string;\n type: string;\n description?: string;\n currency: string;\n pricePerNight: number;\n maxGuests: number;\n rating?: number;\n provider?: { name: string };\n images?: string[];\n } | null;\n },\n { id: string }\n >,\n { variables: { id }, skip: !id }\n );\n const property = data?.ggnomadProperty;\n\n return (\n <PageShell\n title={property?.name ?? t('ggnomad.property.fallbackTitle', 'Property details')}\n subtitle={t('ggnomad.property.subtitle', 'Detailed hospitality listing view')}\n >\n {!property ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.property.notFoundTitle', 'No property found')}\n description={t(\n 'ggnomad.property.notFoundDescription',\n 'This property is unavailable or may have been removed.'\n )}\n />\n ) : (\n <>\n <DetailHero image={property.images?.[0]} alt={property.name} />\n <PagePurpose icon={<Hotel className=\"size-4\" />}>\n {t(\n 'ggnomad.property.purpose',\n 'Everything you need to decide on this stay — its type, description, nightly price, guest capacity, rating and the provider behind it — before you reserve it.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"ggnomad-property-detail\"\n steps={[\n {\n id: 'browse',\n label: t('ggnomad.property.next.browse', 'Compare other stays'),\n description: t(\n 'ggnomad.property.next.browseDesc',\n 'Go back to hospitality listings to compare options.'\n ),\n icon: <Hotel className=\"size-4\" />,\n onClick: () => navigate(joinPath(basePath, 'hospitality')),\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 <SectionCard title={t('ggnomad.property.about', 'About')}>\n <p className=\"text-sm text-text-secondary\">{t('ggnomad.property.type', 'Type')}</p>\n <p className=\"text-text-primary\">{property.type}</p>\n <p className=\"mt-3 text-sm text-text-secondary\">\n {t('ggnomad.property.description', 'Description')}\n </p>\n <p className=\"text-text-primary\">\n {property.description ?? t('ggnomad.property.noDescription', 'No description')}\n </p>\n </SectionCard>\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.property.details', 'Details')}\n </h2>\n <dl className=\"space-y-2 text-sm\">\n <DetailRow\n label={t('ggnomad.property.price', 'Price')}\n value={`${property.currency} ${Number(property.pricePerNight).toFixed(2)}`}\n />\n <DetailRow\n label={t('ggnomad.property.guests', 'Guests')}\n value={String(property.maxGuests)}\n />\n <DetailRow\n label={t('ggnomad.property.rating', 'Rating')}\n value={String(property.rating ?? t('ggnomad.property.noRating', 'N/A'))}\n />\n <DetailRow\n label={t('ggnomad.property.provider', 'Provider')}\n value={\n property.provider?.name ?? t('ggnomad.property.unassigned', 'Unassigned')\n }\n />\n </dl>\n </GlassCard>\n </div>\n <div>\n <BookingPanel\n bookingType=\"PROPERTY\"\n itemId={property.id ?? id}\n itemName={property.name}\n unitPrice={property.pricePerNight ?? 0}\n currency={property.currency ?? 'USD'}\n nights={1}\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,GAiBA;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,oCAAoC;YAE3E,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,EAAO,WAAU,UAAW,CAAA;cAC5C,EACC,4BACA,gKACD;IACW,CAAA;GAEd,kBAAC,GAAD;IACE,YAAW;IACX,OAAO,CACL;KACE,IAAI;KACJ,OAAO,EAAE,gCAAgC,sBAAsB;KAC/D,aAAa,EACX,oCACA,sDACD;KACD,MAAM,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA;KAClC,eAAe,EAAS,EAAS,GAAU,cAAc,CAAC;KAC3D,CACF;IACD,CAAA;GAEF,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAa,OAAO,EAAE,0BAA0B,QAAQ;gBAAxD;OACE,kBAAC,KAAD;QAAG,WAAU;kBAA+B,EAAE,yBAAyB,OAAO;QAAK,CAAA;OACnF,kBAAC,KAAD;QAAG,WAAU;kBAAqB,EAAS;QAAS,CAAA;OACpD,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAE,gCAAgC,cAAc;QAC/C,CAAA;OACJ,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAS,eAAe,EAAE,kCAAkC,iBAAiB;QAC5E,CAAA;OACQ;SACd,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,0BAA0B,QAAQ;SAC3C,OAAO,GAAG,EAAS,SAAS,GAAG,OAAO,EAAS,cAAc,CAAC,QAAQ,EAAE;SACxE,CAAA;QACF,kBAAC,GAAD;SACE,OAAO,EAAE,2BAA2B,SAAS;SAC7C,OAAO,OAAO,EAAS,UAAU;SACjC,CAAA;QACF,kBAAC,GAAD;SACE,OAAO,EAAE,2BAA2B,SAAS;SAC7C,OAAO,OAAO,EAAS,UAAU,EAAE,6BAA6B,MAAM,CAAC;SACvE,CAAA;QACF,kBAAC,GAAD;SACE,OAAO,EAAE,6BAA6B,WAAW;SACjD,OACE,EAAS,UAAU,QAAQ,EAAE,+BAA+B,aAAa;SAE3E,CAAA;QACC;SACK;QACR;QACN,kBAAC,OAAD,EAAA,UACE,kBAAC,GAAD;KACE,aAAY;KACZ,QAAQ,EAAS,MAAM;KACvB,UAAU,EAAS;KACnB,WAAW,EAAS,iBAAiB;KACrC,UAAU,EAAS,YAAY;KAC/B,QAAQ;KACR,CAAA,EACE,CAAA,CACF;;GACL,EAAA,CAAA,GAnFH,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,kCAAkC,oBAAoB;GAC/D,aAAa,EACX,wCACA,yDACD;GACD,CAAA;EA8EM,CAAA"}
1
+ {"version":3,"file":"PropertyDetailsPage.js","names":[],"sources":["../../../src/ggnomad/pages/PropertyDetailsPage.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 { useNavigate, useParams } from 'react-router-dom';\nimport { Hotel, Pencil } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, NextSteps, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_PROPERTY_QUERY } from '../graphql';\nimport { useGGNomad } from '../providers/GGNomadProvider';\nimport { joinPath } from '../utils/navigation';\nimport { PageShell } from './PageShell';\nimport {\n DetailRow,\n SectionCard,\n DetailHero,\n BookingPanel,\n ReviewsSection,\n ListingEditDialog,\n} from '../components';\n\nexport function PropertyDetailsPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { basePath = '/' } = useGGNomad();\n const { id = '' } = useParams();\n const [editDialogOpen, setEditDialogOpen] = useState(false);\n const { data, refetch } = useQuery(\n GGNOMAD_PROPERTY_QUERY as TypedDocumentNode<\n {\n ggnomadProperty: {\n id: string;\n name: string;\n type: string;\n description?: string;\n currency: string;\n pricePerNight: number;\n status?: string;\n maxGuests: number;\n rating?: number;\n provider?: { name: string };\n images?: string[];\n } | null;\n },\n { id: string }\n >,\n { variables: { id }, skip: !id }\n );\n const property = data?.ggnomadProperty;\n\n return (\n <PageShell\n title={property?.name ?? t('ggnomad.property.fallbackTitle', 'Property details')}\n subtitle={t('ggnomad.property.subtitle', 'Detailed hospitality listing view')}\n >\n {!property ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.property.notFoundTitle', 'No property found')}\n description={t(\n 'ggnomad.property.notFoundDescription',\n 'This property is unavailable or may have been removed.'\n )}\n />\n ) : (\n <>\n <DetailHero image={property.images?.[0]} alt={property.name} />\n <PagePurpose icon={<Hotel className=\"size-4\" />}>\n {t(\n 'ggnomad.property.purpose',\n 'Everything you need to decide on this stay — its type, description, nightly price, guest capacity, rating and the provider behind it — before you reserve it.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"ggnomad-property-detail\"\n steps={[\n {\n id: 'browse',\n label: t('ggnomad.property.next.browse', 'Compare other stays'),\n description: t(\n 'ggnomad.property.next.browseDesc',\n 'Go back to hospitality listings to compare options.'\n ),\n icon: <Hotel className=\"size-4\" />,\n onClick: () => navigate(joinPath(basePath, 'hospitality')),\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 <SectionCard title={t('ggnomad.property.about', 'About')}>\n <p className=\"text-sm text-text-secondary\">{t('ggnomad.property.type', 'Type')}</p>\n <p className=\"text-text-primary\">{property.type}</p>\n <p className=\"mt-3 text-sm text-text-secondary\">\n {t('ggnomad.property.description', 'Description')}\n </p>\n <p className=\"text-text-primary\">\n {property.description ?? t('ggnomad.property.noDescription', 'No description')}\n </p>\n </SectionCard>\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-5\">\n <div className=\"mb-4 flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.property.details', 'Details')}\n </h2>\n <button\n onClick={() => setEditDialogOpen(true)}\n className=\"rounded-md p-2 text-text-secondary hover:bg-action-primary-bg hover:text-action-primary-text\"\n aria-label={t('ggnomad.property.editListing', 'Edit listing')}\n title={t('ggnomad.property.editListing', 'Edit listing')}\n >\n <Pencil className=\"size-4\" />\n </button>\n </div>\n <dl className=\"space-y-2 text-sm\">\n <DetailRow\n label={t('ggnomad.property.price', 'Price')}\n value={`${property.currency} ${Number(property.pricePerNight).toFixed(2)}`}\n />\n <DetailRow\n label={t('ggnomad.property.guests', 'Guests')}\n value={String(property.maxGuests)}\n />\n <DetailRow\n label={t('ggnomad.property.rating', 'Rating')}\n value={String(property.rating ?? t('ggnomad.property.noRating', 'N/A'))}\n />\n <DetailRow\n label={t('ggnomad.property.provider', 'Provider')}\n value={\n property.provider?.name ?? t('ggnomad.property.unassigned', 'Unassigned')\n }\n />\n </dl>\n </GlassCard>\n <ReviewsSection targetType=\"PROPERTY\" targetId={property.id ?? id} />\n </div>\n <div>\n <BookingPanel\n bookingType=\"PROPERTY\"\n itemId={property.id ?? id}\n itemName={property.name}\n unitPrice={property.pricePerNight ?? 0}\n currency={property.currency ?? 'USD'}\n nights={1}\n />\n </div>\n </div>\n\n <ListingEditDialog\n open={editDialogOpen}\n onOpenChange={setEditDialogOpen}\n targetType=\"PROPERTY\"\n id={property.id ?? id}\n initial={{\n name: property.name,\n description: property.description,\n pricePerNight: property.pricePerNight,\n status: property.status,\n images: property.images,\n }}\n onSaved={() => refetch()}\n />\n </>\n )}\n </PageShell>\n );\n}\n"],"mappings":"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"}