@burdenoff/microfe-ggnomad 2026.719.1 → 2026.719.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/README.md +32 -0
- package/dist/ggnomad/components/ListingEditDialog.d.ts.map +1 -1
- package/dist/ggnomad/components/ListingEditDialog.js +10 -0
- package/dist/ggnomad/components/ListingEditDialog.js.map +1 -1
- package/dist/ggnomad/components/ReviewsSection.js +2 -2
- package/dist/ggnomad/components/ReviewsSection.js.map +1 -1
- package/dist/ggnomad/graphql.js +27 -27
- package/dist/ggnomad/graphql.js.map +1 -1
- package/dist/ggnomad/pages/BookingsPage.js +2 -2
- package/dist/ggnomad/pages/BookingsPage.js.map +1 -1
- package/dist/ggnomad/pages/DashboardPage.js +8 -8
- package/dist/ggnomad/pages/DashboardPage.js.map +1 -1
- package/dist/ggnomad/pages/EntertainmentPage.js +2 -2
- package/dist/ggnomad/pages/EntertainmentPage.js.map +1 -1
- package/dist/ggnomad/pages/HospitalityPage.js +2 -2
- package/dist/ggnomad/pages/HospitalityPage.js.map +1 -1
- package/dist/ggnomad/pages/ProviderPage.js +2 -2
- package/dist/ggnomad/pages/ProviderPage.js.map +1 -1
- package/dist/ggnomad/pages/SearchPage.js +8 -8
- package/dist/ggnomad/pages/SearchPage.js.map +1 -1
- package/dist/ggnomad/pages/TourismPage.js +4 -4
- package/dist/ggnomad/pages/TourismPage.js.map +1 -1
- package/dist/ggnomad/pages/TravelPage.js +2 -2
- package/dist/ggnomad/pages/TravelPage.js.map +1 -1
- package/dist/ggnomad/pages/TripPlanDetailPage.js +8 -8
- package/dist/ggnomad/pages/TripPlanDetailPage.js.map +1 -1
- package/dist/ggnomad/pages/TripsPage.js +2 -2
- package/dist/ggnomad/pages/TripsPage.js.map +1 -1
- package/dist/stories/BookingPanel.stories.d.ts +27 -0
- package/dist/stories/BookingPanel.stories.d.ts.map +1 -0
- package/dist/stories/DetailHero.stories.d.ts +10 -0
- package/dist/stories/DetailHero.stories.d.ts.map +1 -0
- package/dist/stories/ListingEditDialog.stories.d.ts +26 -0
- package/dist/stories/ListingEditDialog.stories.d.ts.map +1 -0
- package/package.json +21 -9
package/README.md
CHANGED
|
@@ -7,6 +7,38 @@ Part of the [Burdenoff](https://burdenoff.com) platform by
|
|
|
7
7
|
|
|
8
8
|
See `AGENTS.md` for development commands and architecture details.
|
|
9
9
|
|
|
10
|
+
## Storybook
|
|
11
|
+
|
|
12
|
+
Component stories live under `src/stories/*.stories.tsx`. Every story that renders a
|
|
13
|
+
component driving a GraphQL mutation (`BookingPanel`, `ListingEditDialog`) wraps itself
|
|
14
|
+
with `@apollo/client/testing`'s `MockedProvider` — never a live `ApolloClient` — plus
|
|
15
|
+
`MemoryRouter` and `GGNomadProvider` where the component needs routing/context.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bun run storybook # Dev server at http://localhost:6006
|
|
19
|
+
bun run build-storybook # Static build -> storybook-static/ (gitignored; CI uploads it as an artifact)
|
|
20
|
+
bun run test:storybook # Run interaction (play function) tests against an already-running Storybook
|
|
21
|
+
bun run test:storybook:ci # Build, serve, and test in one shot (what CI runs)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`test:storybook` is powered by `@storybook/test-runner`, which drives each story's `play`
|
|
25
|
+
function in a real (Playwright-controlled) browser — this is how interactive components
|
|
26
|
+
(quantity steppers, form saves, dialog cancel) get regression coverage without a full
|
|
27
|
+
app-shell E2E run. `bun run sanity` includes `build-storybook` (catches story build
|
|
28
|
+
breakage); CI (`pr-check.yml`) additionally runs the interaction-test pass via
|
|
29
|
+
`test:storybook:ci` and uploads the static build as a workflow artifact.
|
|
30
|
+
|
|
31
|
+
**Known issue:** `test:storybook` currently fails on every story (old and new) with
|
|
32
|
+
`ReferenceError: Cannot access 'StorybookTestRunnerError' before initialization`, even
|
|
33
|
+
after pinning all `@storybook/*` packages and `test-runner` to matched versions. This
|
|
34
|
+
reproduces identically under Bun and plain Node, so it is a toolchain incompatibility
|
|
35
|
+
between this repo's rolldown-powered Vite build and `@storybook/test-runner`'s injected
|
|
36
|
+
page-context script — not a defect in the stories themselves. The CI step is wired with
|
|
37
|
+
`continue-on-error: true` so it stays visible without blocking merges; `build-storybook`
|
|
38
|
+
still hard-gates real story/build breakage in the meantime. Fixing the interaction-test
|
|
39
|
+
runner itself is fleet-wide (all `microfe-*` repos share this toolchain) and is tracked
|
|
40
|
+
as a follow-up rather than bundled into this change.
|
|
41
|
+
|
|
10
42
|
## License
|
|
11
43
|
|
|
12
44
|
Proprietary — Copyright Burdenoff Consultancy Services Pvt. Ltd.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListingEditDialog.d.ts","sourceRoot":"","sources":["../../../src/ggnomad/components/ListingEditDialog.tsx"],"names":[],"mappings":"AAwBA,KAAK,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAE7D,UAAU,sBAAsB;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,UAAU,EAAE,UAAU,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,EAAE,EACF,OAAO,EACP,OAAO,GACR,EAAE,sBAAsB,+
|
|
1
|
+
{"version":3,"file":"ListingEditDialog.d.ts","sourceRoot":"","sources":["../../../src/ggnomad/components/ListingEditDialog.tsx"],"names":[],"mappings":"AAwBA,KAAK,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAE7D,UAAU,sBAAsB;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,UAAU,EAAE,UAAU,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,EAAE,EACF,OAAO,EACP,OAAO,GACR,EAAE,sBAAsB,+BAgTxB"}
|
|
@@ -60,9 +60,11 @@ function b({ open: b, onOpenChange: x, targetType: S, id: C, initial: w, onSaved
|
|
|
60
60
|
className: "space-y-4",
|
|
61
61
|
children: [
|
|
62
62
|
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
63
|
+
htmlFor: "listing-edit-name",
|
|
63
64
|
className: "block text-sm font-medium text-text-primary",
|
|
64
65
|
children: E("ggnomad.listingEdit.nameLabel", "Name")
|
|
65
66
|
}), /* @__PURE__ */ v("input", {
|
|
67
|
+
id: "listing-edit-name",
|
|
66
68
|
type: "text",
|
|
67
69
|
value: D,
|
|
68
70
|
onChange: (e) => O(e.target.value),
|
|
@@ -71,9 +73,11 @@ function b({ open: b, onOpenChange: x, targetType: S, id: C, initial: w, onSaved
|
|
|
71
73
|
placeholder: E("ggnomad.listingEdit.namePlaceholder", "Enter name")
|
|
72
74
|
})] }),
|
|
73
75
|
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
76
|
+
htmlFor: "listing-edit-description",
|
|
74
77
|
className: "block text-sm font-medium text-text-primary",
|
|
75
78
|
children: E("ggnomad.listingEdit.descriptionLabel", "Description")
|
|
76
79
|
}), /* @__PURE__ */ v("textarea", {
|
|
80
|
+
id: "listing-edit-description",
|
|
77
81
|
value: k,
|
|
78
82
|
onChange: (e) => A(e.target.value),
|
|
79
83
|
disabled: K,
|
|
@@ -82,9 +86,11 @@ function b({ open: b, onOpenChange: x, targetType: S, id: C, initial: w, onSaved
|
|
|
82
86
|
placeholder: E("ggnomad.listingEdit.descriptionPlaceholder", "Enter description")
|
|
83
87
|
})] }),
|
|
84
88
|
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
89
|
+
htmlFor: "listing-edit-price",
|
|
85
90
|
className: "block text-sm font-medium text-text-primary",
|
|
86
91
|
children: E("ggnomad.listingEdit.priceLabel", J)
|
|
87
92
|
}), /* @__PURE__ */ v("input", {
|
|
93
|
+
id: "listing-edit-price",
|
|
88
94
|
type: "number",
|
|
89
95
|
step: "0.01",
|
|
90
96
|
min: "0",
|
|
@@ -95,9 +101,11 @@ function b({ open: b, onOpenChange: x, targetType: S, id: C, initial: w, onSaved
|
|
|
95
101
|
placeholder: "0.00"
|
|
96
102
|
})] }),
|
|
97
103
|
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
104
|
+
htmlFor: "listing-edit-status",
|
|
98
105
|
className: "block text-sm font-medium text-text-primary",
|
|
99
106
|
children: E("ggnomad.listingEdit.statusLabel", "Status")
|
|
100
107
|
}), /* @__PURE__ */ y("select", {
|
|
108
|
+
id: "listing-edit-status",
|
|
101
109
|
value: P,
|
|
102
110
|
onChange: (e) => F(e.target.value),
|
|
103
111
|
disabled: K,
|
|
@@ -118,9 +126,11 @@ function b({ open: b, onOpenChange: x, targetType: S, id: C, initial: w, onSaved
|
|
|
118
126
|
]
|
|
119
127
|
})] }),
|
|
120
128
|
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
129
|
+
htmlFor: "listing-edit-images",
|
|
121
130
|
className: "block text-sm font-medium text-text-primary",
|
|
122
131
|
children: E("ggnomad.listingEdit.imagesLabel", "Images (one URL per line)")
|
|
123
132
|
}), /* @__PURE__ */ v("textarea", {
|
|
133
|
+
id: "listing-edit-images",
|
|
124
134
|
value: I,
|
|
125
135
|
onChange: (e) => L(e.target.value),
|
|
126
136
|
disabled: K,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListingEditDialog.js","names":[],"sources":["../../../src/ggnomad/components/ListingEditDialog.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useMutation } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Pencil } from 'lucide-react';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n UPDATE_GGNOMAD_PROPERTY_MUTATION,\n UPDATE_GGNOMAD_TOUR_MUTATION,\n UPDATE_GGNOMAD_EVENT_MUTATION,\n UPDATE_GGNOMAD_ACTIVITY_MUTATION,\n} from '../graphql';\nimport { notify } from '../utils/notify';\n\ntype TargetType = 'PROPERTY' | 'TOUR' | 'EVENT' | 'ACTIVITY';\n\ninterface ListingEditDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n targetType: TargetType;\n id: string;\n initial: {\n name?: string;\n description?: string;\n price?: number;\n pricePerNight?: number;\n status?: string;\n images?: string[];\n };\n onSaved?: () => void;\n}\n\n/** Edit dialog for listing details (property, tour, event, activity). */\nexport function ListingEditDialog({\n open,\n onOpenChange,\n targetType,\n id,\n initial,\n onSaved,\n}: ListingEditDialogProps) {\n const { t } = useI18n();\n const [name, setName] = useState(initial.name ?? '');\n const [description, setDescription] = useState(initial.description ?? '');\n const priceField = initial.pricePerNight ?? initial.price ?? 0;\n const [price, setPrice] = useState(String(priceField));\n const [status, setStatus] = useState(initial.status ?? 'ACTIVE');\n const [imagesText, setImagesText] = useState((initial.images ?? []).join('\\n'));\n\n const [updateProperty, { loading: updatingProperty }] = useMutation(\n UPDATE_GGNOMAD_PROPERTY_MUTATION as TypedDocumentNode<\n { updateGgnomadProperty: { id: string; name: string } },\n {\n id: string;\n input: {\n name?: string;\n description?: string;\n pricePerNight?: number;\n status?: string;\n images?: string[];\n };\n }\n >\n );\n\n const [updateTour, { loading: updatingTour }] = useMutation(\n UPDATE_GGNOMAD_TOUR_MUTATION as TypedDocumentNode<\n { updateGgnomadTour: { id: string; name: string } },\n {\n id: string;\n input: {\n name?: string;\n description?: string;\n price?: number;\n status?: string;\n images?: string[];\n };\n }\n >\n );\n\n const [updateEvent, { loading: updatingEvent }] = useMutation(\n UPDATE_GGNOMAD_EVENT_MUTATION as TypedDocumentNode<\n { updateGgnomadEvent: { id: string; name: string } },\n {\n id: string;\n input: {\n name?: string;\n description?: string;\n price?: number;\n status?: string;\n images?: string[];\n };\n }\n >\n );\n\n const [updateActivity, { loading: updatingActivity }] = useMutation(\n UPDATE_GGNOMAD_ACTIVITY_MUTATION as TypedDocumentNode<\n { updateGgnomadActivity: { id: string; name: string } },\n {\n id: string;\n input: {\n name?: string;\n description?: string;\n price?: number;\n status?: string;\n images?: string[];\n };\n }\n >\n );\n\n const loading = useMemo(\n () => updatingProperty || updatingTour || updatingEvent || updatingActivity,\n [updatingProperty, updatingTour, updatingEvent, updatingActivity]\n );\n\n const handleSave = async () => {\n try {\n // Build input with only changed fields\n const input: Record<string, unknown> = {};\n\n if (name !== (initial.name ?? '')) {\n input.name = name;\n }\n if (description !== (initial.description ?? '')) {\n input.description = description;\n }\n\n const priceValue = parseFloat(price);\n const initialPrice = initial.pricePerNight ?? initial.price ?? 0;\n if (priceValue !== initialPrice) {\n if (targetType === 'PROPERTY') {\n input.pricePerNight = priceValue;\n } else {\n input.price = priceValue;\n }\n }\n\n if (status !== (initial.status ?? 'ACTIVE')) {\n input.status = status;\n }\n\n const newImages = imagesText\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean);\n const initialImages = initial.images ?? [];\n if (JSON.stringify(newImages) !== JSON.stringify(initialImages)) {\n input.images = newImages;\n }\n\n // If nothing changed, just close\n if (Object.keys(input).length === 0) {\n notify.info(\n t('ggnomad.listingEdit.noChangesTitle', 'No changes'),\n t('ggnomad.listingEdit.noChangesBody', 'Nothing was modified.')\n );\n onOpenChange(false);\n return;\n }\n\n let result;\n if (targetType === 'PROPERTY') {\n result = await updateProperty({\n variables: { id, input },\n });\n } else if (targetType === 'TOUR') {\n result = await updateTour({\n variables: { id, input },\n });\n } else if (targetType === 'EVENT') {\n result = await updateEvent({\n variables: { id, input },\n });\n } else {\n result = await updateActivity({\n variables: { id, input },\n });\n }\n\n if (result?.error) {\n notify.error(\n t('ggnomad.listingEdit.errorTitle', 'Could not update listing'),\n result.error.message\n );\n return;\n }\n\n notify.success(\n t('ggnomad.listingEdit.successTitle', 'Listing updated'),\n t('ggnomad.listingEdit.successBody', 'Your changes have been saved.')\n );\n\n onOpenChange(false);\n onSaved?.();\n } catch (err) {\n notify.error(\n t('ggnomad.listingEdit.errorTitle', 'Could not update listing'),\n err instanceof Error ? err.message : String(err)\n );\n }\n };\n\n const priceLabel = targetType === 'PROPERTY' ? 'Price per night' : 'Price';\n\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent className=\"max-w-2xl\">\n <AlertDialogHeader>\n <AlertDialogTitle className=\"flex items-center gap-2\">\n <Pencil className=\"size-4\" />\n {t('ggnomad.listingEdit.title', 'Edit listing')}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {t('ggnomad.listingEdit.description', 'Update the details for this listing.')}\n </AlertDialogDescription>\n </AlertDialogHeader>\n\n <div className=\"space-y-4\">\n {/* Name */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n {t('ggnomad.listingEdit.nameLabel', 'Name')}\n </label>\n <input\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n disabled={loading}\n className=\"mt-1 w-full rounded-md border border-border-seam bg-bg-canvas px-3 py-2 text-sm text-text-primary placeholder-text-secondary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg disabled:opacity-50\"\n placeholder={t('ggnomad.listingEdit.namePlaceholder', 'Enter name')}\n />\n </div>\n\n {/* Description */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n {t('ggnomad.listingEdit.descriptionLabel', 'Description')}\n </label>\n <textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n disabled={loading}\n rows={3}\n className=\"mt-1 w-full rounded-md border border-border-seam bg-bg-canvas px-3 py-2 text-sm text-text-primary placeholder-text-secondary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg disabled:opacity-50\"\n placeholder={t('ggnomad.listingEdit.descriptionPlaceholder', 'Enter description')}\n />\n </div>\n\n {/* Price */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n {t(`ggnomad.listingEdit.priceLabel`, priceLabel)}\n </label>\n <input\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n value={price}\n onChange={(e) => setPrice(e.target.value)}\n disabled={loading}\n className=\"mt-1 w-full rounded-md border border-border-seam bg-bg-canvas px-3 py-2 text-sm text-text-primary placeholder-text-secondary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg disabled:opacity-50\"\n placeholder=\"0.00\"\n />\n </div>\n\n {/* Status */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n {t('ggnomad.listingEdit.statusLabel', 'Status')}\n </label>\n <select\n value={status}\n onChange={(e) => setStatus(e.target.value)}\n disabled={loading}\n className=\"mt-1 w-full rounded-md border border-border-seam bg-bg-canvas px-3 py-2 text-sm text-text-primary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg disabled:opacity-50\"\n >\n <option value=\"ACTIVE\">{t('ggnomad.listingEdit.statusActive', 'Active')}</option>\n <option value=\"PAUSED\">{t('ggnomad.listingEdit.statusPaused', 'Paused')}</option>\n <option value=\"DRAFT\">{t('ggnomad.listingEdit.statusDraft', 'Draft')}</option>\n </select>\n </div>\n\n {/* Images */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n {t('ggnomad.listingEdit.imagesLabel', 'Images (one URL per line)')}\n </label>\n <textarea\n value={imagesText}\n onChange={(e) => setImagesText(e.target.value)}\n disabled={loading}\n rows={3}\n className=\"mt-1 w-full rounded-md border border-border-seam bg-bg-canvas px-3 py-2 text-sm font-mono text-text-primary placeholder-text-secondary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg disabled:opacity-50\"\n placeholder={t(\n 'ggnomad.listingEdit.imagesPlaceholder',\n 'https://example.com/image1.jpg\\nhttps://example.com/image2.jpg'\n )}\n />\n </div>\n </div>\n\n <AlertDialogFooter>\n <AlertDialogCancel disabled={loading}>\n {t('ggnomad.listingEdit.cancel', 'Cancel')}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={(event) => {\n event.preventDefault();\n void handleSave();\n }}\n disabled={loading}\n className=\"bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bgHover\"\n >\n {loading\n ? t('ggnomad.listingEdit.saving', 'Saving…')\n : t('ggnomad.listingEdit.save', 'Save changes')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ListingEditDialog.js","names":[],"sources":["../../../src/ggnomad/components/ListingEditDialog.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useMutation } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Pencil } from 'lucide-react';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n UPDATE_GGNOMAD_PROPERTY_MUTATION,\n UPDATE_GGNOMAD_TOUR_MUTATION,\n UPDATE_GGNOMAD_EVENT_MUTATION,\n UPDATE_GGNOMAD_ACTIVITY_MUTATION,\n} from '../graphql';\nimport { notify } from '../utils/notify';\n\ntype TargetType = 'PROPERTY' | 'TOUR' | 'EVENT' | 'ACTIVITY';\n\ninterface ListingEditDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n targetType: TargetType;\n id: string;\n initial: {\n name?: string;\n description?: string;\n price?: number;\n pricePerNight?: number;\n status?: string;\n images?: string[];\n };\n onSaved?: () => void;\n}\n\n/** Edit dialog for listing details (property, tour, event, activity). */\nexport function ListingEditDialog({\n open,\n onOpenChange,\n targetType,\n id,\n initial,\n onSaved,\n}: ListingEditDialogProps) {\n const { t } = useI18n();\n const [name, setName] = useState(initial.name ?? '');\n const [description, setDescription] = useState(initial.description ?? '');\n const priceField = initial.pricePerNight ?? initial.price ?? 0;\n const [price, setPrice] = useState(String(priceField));\n const [status, setStatus] = useState(initial.status ?? 'ACTIVE');\n const [imagesText, setImagesText] = useState((initial.images ?? []).join('\\n'));\n\n const [updateProperty, { loading: updatingProperty }] = useMutation(\n UPDATE_GGNOMAD_PROPERTY_MUTATION as TypedDocumentNode<\n { updateGgnomadProperty: { id: string; name: string } },\n {\n id: string;\n input: {\n name?: string;\n description?: string;\n pricePerNight?: number;\n status?: string;\n images?: string[];\n };\n }\n >\n );\n\n const [updateTour, { loading: updatingTour }] = useMutation(\n UPDATE_GGNOMAD_TOUR_MUTATION as TypedDocumentNode<\n { updateGgnomadTour: { id: string; name: string } },\n {\n id: string;\n input: {\n name?: string;\n description?: string;\n price?: number;\n status?: string;\n images?: string[];\n };\n }\n >\n );\n\n const [updateEvent, { loading: updatingEvent }] = useMutation(\n UPDATE_GGNOMAD_EVENT_MUTATION as TypedDocumentNode<\n { updateGgnomadEvent: { id: string; name: string } },\n {\n id: string;\n input: {\n name?: string;\n description?: string;\n price?: number;\n status?: string;\n images?: string[];\n };\n }\n >\n );\n\n const [updateActivity, { loading: updatingActivity }] = useMutation(\n UPDATE_GGNOMAD_ACTIVITY_MUTATION as TypedDocumentNode<\n { updateGgnomadActivity: { id: string; name: string } },\n {\n id: string;\n input: {\n name?: string;\n description?: string;\n price?: number;\n status?: string;\n images?: string[];\n };\n }\n >\n );\n\n const loading = useMemo(\n () => updatingProperty || updatingTour || updatingEvent || updatingActivity,\n [updatingProperty, updatingTour, updatingEvent, updatingActivity]\n );\n\n const handleSave = async () => {\n try {\n // Build input with only changed fields\n const input: Record<string, unknown> = {};\n\n if (name !== (initial.name ?? '')) {\n input.name = name;\n }\n if (description !== (initial.description ?? '')) {\n input.description = description;\n }\n\n const priceValue = parseFloat(price);\n const initialPrice = initial.pricePerNight ?? initial.price ?? 0;\n if (priceValue !== initialPrice) {\n if (targetType === 'PROPERTY') {\n input.pricePerNight = priceValue;\n } else {\n input.price = priceValue;\n }\n }\n\n if (status !== (initial.status ?? 'ACTIVE')) {\n input.status = status;\n }\n\n const newImages = imagesText\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean);\n const initialImages = initial.images ?? [];\n if (JSON.stringify(newImages) !== JSON.stringify(initialImages)) {\n input.images = newImages;\n }\n\n // If nothing changed, just close\n if (Object.keys(input).length === 0) {\n notify.info(\n t('ggnomad.listingEdit.noChangesTitle', 'No changes'),\n t('ggnomad.listingEdit.noChangesBody', 'Nothing was modified.')\n );\n onOpenChange(false);\n return;\n }\n\n let result;\n if (targetType === 'PROPERTY') {\n result = await updateProperty({\n variables: { id, input },\n });\n } else if (targetType === 'TOUR') {\n result = await updateTour({\n variables: { id, input },\n });\n } else if (targetType === 'EVENT') {\n result = await updateEvent({\n variables: { id, input },\n });\n } else {\n result = await updateActivity({\n variables: { id, input },\n });\n }\n\n if (result?.error) {\n notify.error(\n t('ggnomad.listingEdit.errorTitle', 'Could not update listing'),\n result.error.message\n );\n return;\n }\n\n notify.success(\n t('ggnomad.listingEdit.successTitle', 'Listing updated'),\n t('ggnomad.listingEdit.successBody', 'Your changes have been saved.')\n );\n\n onOpenChange(false);\n onSaved?.();\n } catch (err) {\n notify.error(\n t('ggnomad.listingEdit.errorTitle', 'Could not update listing'),\n err instanceof Error ? err.message : String(err)\n );\n }\n };\n\n const priceLabel = targetType === 'PROPERTY' ? 'Price per night' : 'Price';\n\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent className=\"max-w-2xl\">\n <AlertDialogHeader>\n <AlertDialogTitle className=\"flex items-center gap-2\">\n <Pencil className=\"size-4\" />\n {t('ggnomad.listingEdit.title', 'Edit listing')}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {t('ggnomad.listingEdit.description', 'Update the details for this listing.')}\n </AlertDialogDescription>\n </AlertDialogHeader>\n\n <div className=\"space-y-4\">\n {/* Name */}\n <div>\n <label\n htmlFor=\"listing-edit-name\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n {t('ggnomad.listingEdit.nameLabel', 'Name')}\n </label>\n <input\n id=\"listing-edit-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n disabled={loading}\n className=\"mt-1 w-full rounded-md border border-border-seam bg-bg-canvas px-3 py-2 text-sm text-text-primary placeholder-text-secondary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg disabled:opacity-50\"\n placeholder={t('ggnomad.listingEdit.namePlaceholder', 'Enter name')}\n />\n </div>\n\n {/* Description */}\n <div>\n <label\n htmlFor=\"listing-edit-description\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n {t('ggnomad.listingEdit.descriptionLabel', 'Description')}\n </label>\n <textarea\n id=\"listing-edit-description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n disabled={loading}\n rows={3}\n className=\"mt-1 w-full rounded-md border border-border-seam bg-bg-canvas px-3 py-2 text-sm text-text-primary placeholder-text-secondary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg disabled:opacity-50\"\n placeholder={t('ggnomad.listingEdit.descriptionPlaceholder', 'Enter description')}\n />\n </div>\n\n {/* Price */}\n <div>\n <label\n htmlFor=\"listing-edit-price\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n {t(`ggnomad.listingEdit.priceLabel`, priceLabel)}\n </label>\n <input\n id=\"listing-edit-price\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n value={price}\n onChange={(e) => setPrice(e.target.value)}\n disabled={loading}\n className=\"mt-1 w-full rounded-md border border-border-seam bg-bg-canvas px-3 py-2 text-sm text-text-primary placeholder-text-secondary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg disabled:opacity-50\"\n placeholder=\"0.00\"\n />\n </div>\n\n {/* Status */}\n <div>\n <label\n htmlFor=\"listing-edit-status\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n {t('ggnomad.listingEdit.statusLabel', 'Status')}\n </label>\n <select\n id=\"listing-edit-status\"\n value={status}\n onChange={(e) => setStatus(e.target.value)}\n disabled={loading}\n className=\"mt-1 w-full rounded-md border border-border-seam bg-bg-canvas px-3 py-2 text-sm text-text-primary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg disabled:opacity-50\"\n >\n <option value=\"ACTIVE\">{t('ggnomad.listingEdit.statusActive', 'Active')}</option>\n <option value=\"PAUSED\">{t('ggnomad.listingEdit.statusPaused', 'Paused')}</option>\n <option value=\"DRAFT\">{t('ggnomad.listingEdit.statusDraft', 'Draft')}</option>\n </select>\n </div>\n\n {/* Images */}\n <div>\n <label\n htmlFor=\"listing-edit-images\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n {t('ggnomad.listingEdit.imagesLabel', 'Images (one URL per line)')}\n </label>\n <textarea\n id=\"listing-edit-images\"\n value={imagesText}\n onChange={(e) => setImagesText(e.target.value)}\n disabled={loading}\n rows={3}\n className=\"mt-1 w-full rounded-md border border-border-seam bg-bg-canvas px-3 py-2 text-sm font-mono text-text-primary placeholder-text-secondary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg disabled:opacity-50\"\n placeholder={t(\n 'ggnomad.listingEdit.imagesPlaceholder',\n 'https://example.com/image1.jpg\\nhttps://example.com/image2.jpg'\n )}\n />\n </div>\n </div>\n\n <AlertDialogFooter>\n <AlertDialogCancel disabled={loading}>\n {t('ggnomad.listingEdit.cancel', 'Cancel')}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={(event) => {\n event.preventDefault();\n void handleSave();\n }}\n disabled={loading}\n className=\"bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bgHover\"\n >\n {loading\n ? t('ggnomad.listingEdit.saving', 'Saving…')\n : t('ggnomad.listingEdit.save', 'Save changes')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n"],"mappings":"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"}
|
|
@@ -244,8 +244,8 @@ function x({ targetType: e, targetId: i }) {
|
|
|
244
244
|
} }), { data: S, refetch: C } = d(t, { variables: {
|
|
245
245
|
targetType: e,
|
|
246
246
|
targetId: i,
|
|
247
|
-
|
|
248
|
-
|
|
247
|
+
limit: 10,
|
|
248
|
+
offset: 0
|
|
249
249
|
} }), w = h?.ggnomadReviewSummary, T = S?.ggnomadReviews ?? [], E = () => {
|
|
250
250
|
m(!1), x(), C();
|
|
251
251
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReviewsSection.js","names":[],"sources":["../../../src/ggnomad/components/ReviewsSection.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Star, MessageSquare, AlertCircle } from 'lucide-react';\nimport { Button, GlassCard, Input, Textarea } from '@burdenoff/fe-libs/ui';\n\nimport {\n GGNOMAD_REVIEW_SUMMARY_QUERY,\n GGNOMAD_REVIEWS_QUERY,\n CREATE_GGNOMAD_REVIEW_MUTATION,\n} from '../graphql';\nimport { notify } from '../utils/notify';\nimport { cn } from '../utils/cn';\n\ntype GgnomadBookingType = 'PROPERTY' | 'TOUR' | 'EVENT' | 'ACTIVITY';\n\ntype ReviewsSectionProps = {\n targetType: GgnomadBookingType;\n targetId: string;\n};\n\ntype ReviewSummaryData = {\n ggnomadReviewSummary: {\n average: number;\n count: number;\n distribution: number[];\n };\n};\n\ntype ReviewsData = {\n ggnomadReviews: Array<{\n id: string;\n rating: number;\n title?: string;\n content?: string;\n isVerified: boolean;\n helpfulCount: number;\n response?: string;\n respondedAt?: string;\n createdAt: string;\n }>;\n};\n\ntype CreateReviewInput = {\n targetType: GgnomadBookingType;\n targetId: string;\n rating: number;\n title?: string;\n content?: string;\n images?: string[];\n};\n\n/**\n * Star distribution bar chart component.\n * Displays a 5-row breakdown of rating distribution.\n */\nfunction StarDistributionChart({ distribution }: { distribution: number[] }) {\n const total = distribution.reduce((a, b) => a + b, 0);\n\n return (\n <div className=\"space-y-2\">\n {[5, 4, 3, 2, 1].map((stars, idx) => {\n const count = distribution[4 - idx] ?? 0;\n const percentage = total > 0 ? (count / total) * 100 : 0;\n\n return (\n <div key={stars} className=\"flex items-center gap-2\">\n <div className=\"flex items-center gap-1 whitespace-nowrap text-xs text-text-secondary\">\n <span>{stars}</span>\n <Star className=\"size-3 text-status-warning-text\" aria-hidden=\"true\" />\n </div>\n <div className=\"flex-1 h-2 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className=\"h-full bg-status-warning-bg transition-all\"\n style={{ width: `${percentage}%` }}\n role=\"progressbar\"\n aria-label={`${count} reviews with ${stars} stars`}\n aria-valuenow={percentage}\n aria-valuemin={0}\n aria-valuemax={100}\n />\n </div>\n <span className=\"text-xs text-text-secondary tabular-nums w-8 text-right\">{count}</span>\n </div>\n );\n })}\n </div>\n );\n}\n\n/**\n * Individual review card component.\n */\nfunction ReviewCard({ review }: { review: ReviewsData['ggnomadReviews'][0] }) {\n const { t } = useI18n();\n const createdDate = new Date(review.createdAt);\n const formattedDate = createdDate.toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n year: createdDate.getFullYear() !== new Date().getFullYear() ? 'numeric' : undefined,\n });\n\n return (\n <div className=\"rounded-lg border border-border-seam bg-bg-surface/40 p-4 space-y-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex gap-0.5\">\n {[...Array(5)].map((_, i) => (\n <Star\n key={i}\n className={cn(\n 'size-3.5',\n i < review.rating\n ? 'fill-status-warning-text text-status-warning-text'\n : 'text-border-seam'\n )}\n aria-hidden=\"true\"\n />\n ))}\n </div>\n <span className=\"text-xs text-text-secondary font-medium\">{review.rating}/5</span>\n </div>\n {review.isVerified && (\n <span className=\"inline-flex items-center gap-1 text-xs font-medium text-status-success-text bg-status-success-bg-subtle px-2 py-1 rounded-full\">\n <span className=\"size-1.5 bg-status-success-text rounded-full\" aria-hidden=\"true\" />\n {t('ggnomad.reviews.verified', 'Verified')}\n </span>\n )}\n </div>\n\n {review.title && <h4 className=\"font-medium text-text-primary text-sm\">{review.title}</h4>}\n\n {review.content && (\n <p className=\"text-sm text-text-secondary leading-relaxed\">{review.content}</p>\n )}\n\n <div className=\"flex items-center justify-between pt-2 border-t border-border-seam\">\n <span className=\"text-xs text-text-secondary\">{formattedDate}</span>\n {review.helpfulCount > 0 && (\n <span className=\"text-xs text-text-secondary flex items-center gap-1\">\n <MessageSquare className=\"size-3\" aria-hidden=\"true\" />\n {review.helpfulCount}\n </span>\n )}\n </div>\n\n {review.response && (\n <div className=\"mt-3 pt-3 border-t border-border-seam bg-bg-sunken/50 rounded p-3 text-sm\">\n <p className=\"font-medium text-text-primary mb-1\">\n {t('ggnomad.reviews.hostResponse', 'Host response')}\n </p>\n <p className=\"text-text-secondary\">{review.response}</p>\n {review.respondedAt && (\n <p className=\"text-xs text-text-secondary mt-2\">\n {new Date(review.respondedAt).toLocaleDateString()}\n </p>\n )}\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Review composer component.\n */\nfunction ReviewComposer({\n targetType,\n targetId,\n onReviewCreated,\n}: {\n targetType: GgnomadBookingType;\n targetId: string;\n onReviewCreated: () => void;\n}) {\n const { t } = useI18n();\n const [rating, setRating] = useState(5);\n const [title, setTitle] = useState('');\n const [content, setContent] = useState('');\n\n const [createReview, { loading: creating }] = useMutation(\n CREATE_GGNOMAD_REVIEW_MUTATION as TypedDocumentNode<\n {\n createGgnomadReview: {\n id: string;\n rating: number;\n title?: string;\n content?: string;\n };\n },\n { input: CreateReviewInput }\n >\n );\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (rating === 0) {\n notify.warning(\n t('ggnomad.reviews.composer.ratingRequired', 'Rating required'),\n t('ggnomad.reviews.composer.selectRating', 'Please select a rating before submitting.')\n );\n return;\n }\n\n try {\n const result = await createReview({\n variables: {\n input: {\n targetType,\n targetId,\n rating,\n title: title.trim() || undefined,\n content: content.trim() || undefined,\n },\n },\n });\n\n if (result.error) {\n notify.error(\n t('ggnomad.reviews.composer.error', 'Could not post review'),\n result.error.message\n );\n return;\n }\n\n notify.success(\n t('ggnomad.reviews.composer.success', 'Review posted'),\n t('ggnomad.reviews.composer.successDesc', 'Thank you for sharing your experience!')\n );\n\n // Reset form\n setRating(5);\n setTitle('');\n setContent('');\n\n // Trigger refresh\n onReviewCreated();\n } catch (err) {\n notify.error(\n t('ggnomad.reviews.composer.error', 'Could not post review'),\n err instanceof Error ? err.message : String(err)\n );\n }\n };\n\n return (\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-5\">\n <h3 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.reviews.composer.title', 'Share your experience')}\n </h3>\n\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {/* Rating selector */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n {t('ggnomad.reviews.composer.rating', 'Your rating')}\n </label>\n <div className=\"flex gap-2\">\n {[1, 2, 3, 4, 5].map((star) => (\n <button\n key={star}\n type=\"button\"\n onClick={() => setRating(star)}\n className={cn(\n 'p-1.5 rounded-lg transition-all',\n rating >= star\n ? 'bg-status-warning-bg-subtle'\n : 'bg-bg-sunken hover:bg-bg-surface'\n )}\n aria-label={t(\n 'ggnomad.reviews.composer.ratingLabel',\n `Rate {{stars}} out of 5 stars`\n ).replace('{{stars}}', String(star))}\n aria-pressed={rating >= star}\n >\n <Star\n className={cn(\n 'size-5 transition-colors',\n rating >= star\n ? 'fill-status-warning-text text-status-warning-text'\n : 'text-border-seam'\n )}\n aria-hidden=\"true\"\n />\n </button>\n ))}\n </div>\n </div>\n\n {/* Title input */}\n <div>\n <label\n htmlFor=\"review-title\"\n className=\"block text-sm font-medium text-text-primary mb-2\"\n >\n {t('ggnomad.reviews.composer.titleLabel', 'Title (optional)')}\n </label>\n <Input\n id=\"review-title\"\n placeholder={t(\n 'ggnomad.reviews.composer.titlePlaceholder',\n 'e.g., \"Great location, friendly host\"'\n )}\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n maxLength={100}\n disabled={creating}\n className=\"bg-bg-surface border-border-seam\"\n />\n <p className=\"text-xs text-text-secondary mt-1\">{title.length}/100</p>\n </div>\n\n {/* Content textarea */}\n <div>\n <label\n htmlFor=\"review-content\"\n className=\"block text-sm font-medium text-text-primary mb-2\"\n >\n {t('ggnomad.reviews.composer.contentLabel', 'Your review (optional)')}\n </label>\n <Textarea\n id=\"review-content\"\n placeholder={t(\n 'ggnomad.reviews.composer.contentPlaceholder',\n 'Share the details of your experience...'\n )}\n value={content}\n onChange={(e) => setContent(e.target.value)}\n maxLength={1000}\n rows={4}\n disabled={creating}\n className=\"bg-bg-surface border-border-seam resize-none\"\n />\n <p className=\"text-xs text-text-secondary mt-1\">{content.length}/1000</p>\n </div>\n\n {/* Submit button */}\n <Button type=\"submit\" disabled={creating || rating === 0} className=\"w-full\">\n {creating\n ? t('ggnomad.reviews.composer.submitting', 'Posting…')\n : t('ggnomad.reviews.composer.submit', 'Post review')}\n </Button>\n </form>\n </GlassCard>\n );\n}\n\n/**\n * ReviewsSection component.\n * Displays review summary, list, and composition UI for a bookable item.\n */\nexport function ReviewsSection({ targetType, targetId }: ReviewsSectionProps) {\n const { t } = useI18n();\n const [showComposer, setShowComposer] = useState(false);\n\n // Fetch review summary\n const { data: summaryData, refetch: refetchSummary } = useQuery(\n GGNOMAD_REVIEW_SUMMARY_QUERY as TypedDocumentNode<\n ReviewSummaryData,\n { targetType: GgnomadBookingType; targetId: string }\n >,\n { variables: { targetType, targetId } }\n );\n\n // Fetch reviews list\n const { data: reviewsData, refetch: refetchReviews } = useQuery(\n GGNOMAD_REVIEWS_QUERY as TypedDocumentNode<\n ReviewsData,\n { targetType: GgnomadBookingType; targetId: string; first?: number; skip?: number }\n >,\n {\n variables: { targetType, targetId, first: 10, skip: 0 },\n }\n );\n\n const summary = summaryData?.ggnomadReviewSummary;\n const reviews = reviewsData?.ggnomadReviews ?? [];\n\n const handleReviewCreated = () => {\n setShowComposer(false);\n void refetchSummary();\n void refetchReviews();\n };\n\n return (\n <div className=\"space-y-6\">\n {/* Summary Section */}\n {summary && summary.count > 0 && (\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.reviews.summary', 'Ratings & reviews')}\n </h2>\n\n <div className=\"grid gap-6 sm:grid-cols-2\">\n {/* Average Rating */}\n <div className=\"flex flex-col items-center justify-center py-4\">\n <div className=\"text-5xl font-bold text-text-primary tabular-nums\">\n {summary.average.toFixed(1)}\n </div>\n <div className=\"flex gap-0.5 mt-2\">\n {[...Array(5)].map((_, i) => (\n <Star\n key={i}\n className={cn(\n 'size-4',\n i < Math.round(summary.average)\n ? 'fill-status-warning-text text-status-warning-text'\n : 'text-border-seam'\n )}\n aria-hidden=\"true\"\n />\n ))}\n </div>\n <p className=\"text-sm text-text-secondary mt-2\">\n {t('ggnomad.reviews.totalCount', '{{count}} {{plural}}')\n .replace('{{count}}', String(summary.count))\n .replace(\n '{{plural}}',\n summary.count === 1\n ? t('ggnomad.reviews.review', 'review')\n : t('ggnomad.reviews.reviews', 'reviews')\n )}\n </p>\n </div>\n\n {/* Distribution Chart */}\n <div>\n <StarDistributionChart distribution={summary.distribution} />\n </div>\n </div>\n </GlassCard>\n )}\n\n {/* Write Review Composer */}\n {!showComposer && (\n <Button onClick={() => setShowComposer(true)} variant=\"secondary\" className=\"w-full\">\n {t('ggnomad.reviews.writeReview', 'Write a review')}\n </Button>\n )}\n\n {showComposer && (\n <ReviewComposer\n targetType={targetType}\n targetId={targetId}\n onReviewCreated={handleReviewCreated}\n />\n )}\n\n {/* Reviews List */}\n {reviews.length > 0 ? (\n <div>\n <h3 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.reviews.allReviews', 'All reviews')}\n </h3>\n <div className=\"grid gap-3\">\n {reviews.map((review) => (\n <ReviewCard key={review.id} review={review} />\n ))}\n </div>\n </div>\n ) : summary && summary.count === 0 ? (\n <div className=\"text-center py-8 rounded-lg border border-border-seam bg-bg-surface/40\">\n <AlertCircle className=\"size-6 text-text-secondary mx-auto mb-2\" aria-hidden=\"true\" />\n <p className=\"text-sm text-text-secondary\">\n {t('ggnomad.reviews.noReviewsYet', 'Be the first to review')}\n </p>\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ReviewsSection.js","names":[],"sources":["../../../src/ggnomad/components/ReviewsSection.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Star, MessageSquare, AlertCircle } from 'lucide-react';\nimport { Button, GlassCard, Input, Textarea } from '@burdenoff/fe-libs/ui';\n\nimport {\n GGNOMAD_REVIEW_SUMMARY_QUERY,\n GGNOMAD_REVIEWS_QUERY,\n CREATE_GGNOMAD_REVIEW_MUTATION,\n} from '../graphql';\nimport { notify } from '../utils/notify';\nimport { cn } from '../utils/cn';\n\ntype GgnomadBookingType = 'PROPERTY' | 'TOUR' | 'EVENT' | 'ACTIVITY';\n\ntype ReviewsSectionProps = {\n targetType: GgnomadBookingType;\n targetId: string;\n};\n\ntype ReviewSummaryData = {\n ggnomadReviewSummary: {\n average: number;\n count: number;\n distribution: number[];\n };\n};\n\ntype ReviewsData = {\n ggnomadReviews: Array<{\n id: string;\n rating: number;\n title?: string;\n content?: string;\n isVerified: boolean;\n helpfulCount: number;\n response?: string;\n respondedAt?: string;\n createdAt: string;\n }>;\n};\n\ntype CreateReviewInput = {\n targetType: GgnomadBookingType;\n targetId: string;\n rating: number;\n title?: string;\n content?: string;\n images?: string[];\n};\n\n/**\n * Star distribution bar chart component.\n * Displays a 5-row breakdown of rating distribution.\n */\nfunction StarDistributionChart({ distribution }: { distribution: number[] }) {\n const total = distribution.reduce((a, b) => a + b, 0);\n\n return (\n <div className=\"space-y-2\">\n {[5, 4, 3, 2, 1].map((stars, idx) => {\n const count = distribution[4 - idx] ?? 0;\n const percentage = total > 0 ? (count / total) * 100 : 0;\n\n return (\n <div key={stars} className=\"flex items-center gap-2\">\n <div className=\"flex items-center gap-1 whitespace-nowrap text-xs text-text-secondary\">\n <span>{stars}</span>\n <Star className=\"size-3 text-status-warning-text\" aria-hidden=\"true\" />\n </div>\n <div className=\"flex-1 h-2 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className=\"h-full bg-status-warning-bg transition-all\"\n style={{ width: `${percentage}%` }}\n role=\"progressbar\"\n aria-label={`${count} reviews with ${stars} stars`}\n aria-valuenow={percentage}\n aria-valuemin={0}\n aria-valuemax={100}\n />\n </div>\n <span className=\"text-xs text-text-secondary tabular-nums w-8 text-right\">{count}</span>\n </div>\n );\n })}\n </div>\n );\n}\n\n/**\n * Individual review card component.\n */\nfunction ReviewCard({ review }: { review: ReviewsData['ggnomadReviews'][0] }) {\n const { t } = useI18n();\n const createdDate = new Date(review.createdAt);\n const formattedDate = createdDate.toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n year: createdDate.getFullYear() !== new Date().getFullYear() ? 'numeric' : undefined,\n });\n\n return (\n <div className=\"rounded-lg border border-border-seam bg-bg-surface/40 p-4 space-y-3\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex gap-0.5\">\n {[...Array(5)].map((_, i) => (\n <Star\n key={i}\n className={cn(\n 'size-3.5',\n i < review.rating\n ? 'fill-status-warning-text text-status-warning-text'\n : 'text-border-seam'\n )}\n aria-hidden=\"true\"\n />\n ))}\n </div>\n <span className=\"text-xs text-text-secondary font-medium\">{review.rating}/5</span>\n </div>\n {review.isVerified && (\n <span className=\"inline-flex items-center gap-1 text-xs font-medium text-status-success-text bg-status-success-bg-subtle px-2 py-1 rounded-full\">\n <span className=\"size-1.5 bg-status-success-text rounded-full\" aria-hidden=\"true\" />\n {t('ggnomad.reviews.verified', 'Verified')}\n </span>\n )}\n </div>\n\n {review.title && <h4 className=\"font-medium text-text-primary text-sm\">{review.title}</h4>}\n\n {review.content && (\n <p className=\"text-sm text-text-secondary leading-relaxed\">{review.content}</p>\n )}\n\n <div className=\"flex items-center justify-between pt-2 border-t border-border-seam\">\n <span className=\"text-xs text-text-secondary\">{formattedDate}</span>\n {review.helpfulCount > 0 && (\n <span className=\"text-xs text-text-secondary flex items-center gap-1\">\n <MessageSquare className=\"size-3\" aria-hidden=\"true\" />\n {review.helpfulCount}\n </span>\n )}\n </div>\n\n {review.response && (\n <div className=\"mt-3 pt-3 border-t border-border-seam bg-bg-sunken/50 rounded p-3 text-sm\">\n <p className=\"font-medium text-text-primary mb-1\">\n {t('ggnomad.reviews.hostResponse', 'Host response')}\n </p>\n <p className=\"text-text-secondary\">{review.response}</p>\n {review.respondedAt && (\n <p className=\"text-xs text-text-secondary mt-2\">\n {new Date(review.respondedAt).toLocaleDateString()}\n </p>\n )}\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Review composer component.\n */\nfunction ReviewComposer({\n targetType,\n targetId,\n onReviewCreated,\n}: {\n targetType: GgnomadBookingType;\n targetId: string;\n onReviewCreated: () => void;\n}) {\n const { t } = useI18n();\n const [rating, setRating] = useState(5);\n const [title, setTitle] = useState('');\n const [content, setContent] = useState('');\n\n const [createReview, { loading: creating }] = useMutation(\n CREATE_GGNOMAD_REVIEW_MUTATION as TypedDocumentNode<\n {\n createGgnomadReview: {\n id: string;\n rating: number;\n title?: string;\n content?: string;\n };\n },\n { input: CreateReviewInput }\n >\n );\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (rating === 0) {\n notify.warning(\n t('ggnomad.reviews.composer.ratingRequired', 'Rating required'),\n t('ggnomad.reviews.composer.selectRating', 'Please select a rating before submitting.')\n );\n return;\n }\n\n try {\n const result = await createReview({\n variables: {\n input: {\n targetType,\n targetId,\n rating,\n title: title.trim() || undefined,\n content: content.trim() || undefined,\n },\n },\n });\n\n if (result.error) {\n notify.error(\n t('ggnomad.reviews.composer.error', 'Could not post review'),\n result.error.message\n );\n return;\n }\n\n notify.success(\n t('ggnomad.reviews.composer.success', 'Review posted'),\n t('ggnomad.reviews.composer.successDesc', 'Thank you for sharing your experience!')\n );\n\n // Reset form\n setRating(5);\n setTitle('');\n setContent('');\n\n // Trigger refresh\n onReviewCreated();\n } catch (err) {\n notify.error(\n t('ggnomad.reviews.composer.error', 'Could not post review'),\n err instanceof Error ? err.message : String(err)\n );\n }\n };\n\n return (\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-5\">\n <h3 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.reviews.composer.title', 'Share your experience')}\n </h3>\n\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {/* Rating selector */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n {t('ggnomad.reviews.composer.rating', 'Your rating')}\n </label>\n <div className=\"flex gap-2\">\n {[1, 2, 3, 4, 5].map((star) => (\n <button\n key={star}\n type=\"button\"\n onClick={() => setRating(star)}\n className={cn(\n 'p-1.5 rounded-lg transition-all',\n rating >= star\n ? 'bg-status-warning-bg-subtle'\n : 'bg-bg-sunken hover:bg-bg-surface'\n )}\n aria-label={t(\n 'ggnomad.reviews.composer.ratingLabel',\n `Rate {{stars}} out of 5 stars`\n ).replace('{{stars}}', String(star))}\n aria-pressed={rating >= star}\n >\n <Star\n className={cn(\n 'size-5 transition-colors',\n rating >= star\n ? 'fill-status-warning-text text-status-warning-text'\n : 'text-border-seam'\n )}\n aria-hidden=\"true\"\n />\n </button>\n ))}\n </div>\n </div>\n\n {/* Title input */}\n <div>\n <label\n htmlFor=\"review-title\"\n className=\"block text-sm font-medium text-text-primary mb-2\"\n >\n {t('ggnomad.reviews.composer.titleLabel', 'Title (optional)')}\n </label>\n <Input\n id=\"review-title\"\n placeholder={t(\n 'ggnomad.reviews.composer.titlePlaceholder',\n 'e.g., \"Great location, friendly host\"'\n )}\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n maxLength={100}\n disabled={creating}\n className=\"bg-bg-surface border-border-seam\"\n />\n <p className=\"text-xs text-text-secondary mt-1\">{title.length}/100</p>\n </div>\n\n {/* Content textarea */}\n <div>\n <label\n htmlFor=\"review-content\"\n className=\"block text-sm font-medium text-text-primary mb-2\"\n >\n {t('ggnomad.reviews.composer.contentLabel', 'Your review (optional)')}\n </label>\n <Textarea\n id=\"review-content\"\n placeholder={t(\n 'ggnomad.reviews.composer.contentPlaceholder',\n 'Share the details of your experience...'\n )}\n value={content}\n onChange={(e) => setContent(e.target.value)}\n maxLength={1000}\n rows={4}\n disabled={creating}\n className=\"bg-bg-surface border-border-seam resize-none\"\n />\n <p className=\"text-xs text-text-secondary mt-1\">{content.length}/1000</p>\n </div>\n\n {/* Submit button */}\n <Button type=\"submit\" disabled={creating || rating === 0} className=\"w-full\">\n {creating\n ? t('ggnomad.reviews.composer.submitting', 'Posting…')\n : t('ggnomad.reviews.composer.submit', 'Post review')}\n </Button>\n </form>\n </GlassCard>\n );\n}\n\n/**\n * ReviewsSection component.\n * Displays review summary, list, and composition UI for a bookable item.\n */\nexport function ReviewsSection({ targetType, targetId }: ReviewsSectionProps) {\n const { t } = useI18n();\n const [showComposer, setShowComposer] = useState(false);\n\n // Fetch review summary\n const { data: summaryData, refetch: refetchSummary } = useQuery(\n GGNOMAD_REVIEW_SUMMARY_QUERY as TypedDocumentNode<\n ReviewSummaryData,\n { targetType: GgnomadBookingType; targetId: string }\n >,\n { variables: { targetType, targetId } }\n );\n\n // Fetch reviews list\n const { data: reviewsData, refetch: refetchReviews } = useQuery(\n GGNOMAD_REVIEWS_QUERY as TypedDocumentNode<\n ReviewsData,\n { targetType: GgnomadBookingType; targetId: string; limit?: number; offset?: number }\n >,\n {\n variables: { targetType, targetId, limit: 10, offset: 0 },\n }\n );\n\n const summary = summaryData?.ggnomadReviewSummary;\n const reviews = reviewsData?.ggnomadReviews ?? [];\n\n const handleReviewCreated = () => {\n setShowComposer(false);\n void refetchSummary();\n void refetchReviews();\n };\n\n return (\n <div className=\"space-y-6\">\n {/* Summary Section */}\n {summary && summary.count > 0 && (\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.reviews.summary', 'Ratings & reviews')}\n </h2>\n\n <div className=\"grid gap-6 sm:grid-cols-2\">\n {/* Average Rating */}\n <div className=\"flex flex-col items-center justify-center py-4\">\n <div className=\"text-5xl font-bold text-text-primary tabular-nums\">\n {summary.average.toFixed(1)}\n </div>\n <div className=\"flex gap-0.5 mt-2\">\n {[...Array(5)].map((_, i) => (\n <Star\n key={i}\n className={cn(\n 'size-4',\n i < Math.round(summary.average)\n ? 'fill-status-warning-text text-status-warning-text'\n : 'text-border-seam'\n )}\n aria-hidden=\"true\"\n />\n ))}\n </div>\n <p className=\"text-sm text-text-secondary mt-2\">\n {t('ggnomad.reviews.totalCount', '{{count}} {{plural}}')\n .replace('{{count}}', String(summary.count))\n .replace(\n '{{plural}}',\n summary.count === 1\n ? t('ggnomad.reviews.review', 'review')\n : t('ggnomad.reviews.reviews', 'reviews')\n )}\n </p>\n </div>\n\n {/* Distribution Chart */}\n <div>\n <StarDistributionChart distribution={summary.distribution} />\n </div>\n </div>\n </GlassCard>\n )}\n\n {/* Write Review Composer */}\n {!showComposer && (\n <Button onClick={() => setShowComposer(true)} variant=\"secondary\" className=\"w-full\">\n {t('ggnomad.reviews.writeReview', 'Write a review')}\n </Button>\n )}\n\n {showComposer && (\n <ReviewComposer\n targetType={targetType}\n targetId={targetId}\n onReviewCreated={handleReviewCreated}\n />\n )}\n\n {/* Reviews List */}\n {reviews.length > 0 ? (\n <div>\n <h3 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.reviews.allReviews', 'All reviews')}\n </h3>\n <div className=\"grid gap-3\">\n {reviews.map((review) => (\n <ReviewCard key={review.id} review={review} />\n ))}\n </div>\n </div>\n ) : summary && summary.count === 0 ? (\n <div className=\"text-center py-8 rounded-lg border border-border-seam bg-bg-surface/40\">\n <AlertCircle className=\"size-6 text-text-secondary mx-auto mb-2\" aria-hidden=\"true\" />\n <p className=\"text-sm text-text-secondary\">\n {t('ggnomad.reviews.noReviewsYet', 'Be the first to review')}\n </p>\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
|
package/dist/ggnomad/graphql.js
CHANGED
|
@@ -18,25 +18,25 @@ var t = e`
|
|
|
18
18
|
}
|
|
19
19
|
`, n = e`
|
|
20
20
|
query GGNomadBookableSample {
|
|
21
|
-
ggnomadProperties(pagination: {
|
|
21
|
+
ggnomadProperties(pagination: { limit: 1, offset: 0 }) {
|
|
22
22
|
id
|
|
23
23
|
name
|
|
24
24
|
pricePerNight
|
|
25
25
|
currency
|
|
26
26
|
}
|
|
27
|
-
ggnomadTours(pagination: {
|
|
27
|
+
ggnomadTours(pagination: { limit: 1, offset: 0 }) {
|
|
28
28
|
id
|
|
29
29
|
name
|
|
30
30
|
price
|
|
31
31
|
currency
|
|
32
32
|
}
|
|
33
|
-
ggnomadEvents(pagination: {
|
|
33
|
+
ggnomadEvents(pagination: { limit: 1, offset: 0 }) {
|
|
34
34
|
id
|
|
35
35
|
name
|
|
36
36
|
price
|
|
37
37
|
currency
|
|
38
38
|
}
|
|
39
|
-
ggnomadActivities(pagination: {
|
|
39
|
+
ggnomadActivities(pagination: { limit: 1, offset: 0 }) {
|
|
40
40
|
id
|
|
41
41
|
name
|
|
42
42
|
price
|
|
@@ -45,26 +45,26 @@ var t = e`
|
|
|
45
45
|
}
|
|
46
46
|
`, r = e`
|
|
47
47
|
query GGNomadFavoriteTargets {
|
|
48
|
-
ggnomadProperties(pagination: {
|
|
48
|
+
ggnomadProperties(pagination: { limit: 100, offset: 0 }) {
|
|
49
49
|
id
|
|
50
50
|
name
|
|
51
51
|
}
|
|
52
|
-
ggnomadTours(pagination: {
|
|
52
|
+
ggnomadTours(pagination: { limit: 100, offset: 0 }) {
|
|
53
53
|
id
|
|
54
54
|
name
|
|
55
55
|
}
|
|
56
|
-
ggnomadEvents(pagination: {
|
|
56
|
+
ggnomadEvents(pagination: { limit: 100, offset: 0 }) {
|
|
57
57
|
id
|
|
58
58
|
name
|
|
59
59
|
}
|
|
60
|
-
ggnomadActivities(pagination: {
|
|
60
|
+
ggnomadActivities(pagination: { limit: 100, offset: 0 }) {
|
|
61
61
|
id
|
|
62
62
|
name
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
`, i = e`
|
|
66
|
-
query GGNomadProviders($
|
|
67
|
-
ggnomadProviders(pagination: {
|
|
66
|
+
query GGNomadProviders($limit: Int, $offset: Int) {
|
|
67
|
+
ggnomadProviders(pagination: { limit: $limit, offset: $offset }) {
|
|
68
68
|
id
|
|
69
69
|
name
|
|
70
70
|
type
|
|
@@ -78,8 +78,8 @@ var t = e`
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
`, a = e`
|
|
81
|
-
query GGNomadProperties($
|
|
82
|
-
ggnomadProperties(pagination: {
|
|
81
|
+
query GGNomadProperties($limit: Int, $offset: Int) {
|
|
82
|
+
ggnomadProperties(pagination: { limit: $limit, offset: $offset }) {
|
|
83
83
|
id
|
|
84
84
|
name
|
|
85
85
|
type
|
|
@@ -135,8 +135,8 @@ e`
|
|
|
135
135
|
}
|
|
136
136
|
`;
|
|
137
137
|
var s = e`
|
|
138
|
-
query GGNomadTours($
|
|
139
|
-
ggnomadTours(pagination: {
|
|
138
|
+
query GGNomadTours($limit: Int, $offset: Int) {
|
|
139
|
+
ggnomadTours(pagination: { limit: $limit, offset: $offset }) {
|
|
140
140
|
id
|
|
141
141
|
name
|
|
142
142
|
description
|
|
@@ -177,8 +177,8 @@ var s = e`
|
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
`, l = e`
|
|
180
|
-
query GGNomadEvents($
|
|
181
|
-
ggnomadEvents(pagination: {
|
|
180
|
+
query GGNomadEvents($limit: Int, $offset: Int) {
|
|
181
|
+
ggnomadEvents(pagination: { limit: $limit, offset: $offset }) {
|
|
182
182
|
id
|
|
183
183
|
name
|
|
184
184
|
description
|
|
@@ -217,8 +217,8 @@ var s = e`
|
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
219
|
`, d = e`
|
|
220
|
-
query GGNomadActivities($
|
|
221
|
-
ggnomadActivities(pagination: {
|
|
220
|
+
query GGNomadActivities($limit: Int, $offset: Int) {
|
|
221
|
+
ggnomadActivities(pagination: { limit: $limit, offset: $offset }) {
|
|
222
222
|
id
|
|
223
223
|
name
|
|
224
224
|
description
|
|
@@ -263,8 +263,8 @@ var s = e`
|
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
`, p = e`
|
|
266
|
-
query GGNomadTrips($
|
|
267
|
-
ggnomadTrips(pagination: {
|
|
266
|
+
query GGNomadTrips($limit: Int, $offset: Int) {
|
|
267
|
+
ggnomadTrips(pagination: { limit: $limit, offset: $offset }) {
|
|
268
268
|
id
|
|
269
269
|
name
|
|
270
270
|
transportMode
|
|
@@ -283,8 +283,8 @@ var s = e`
|
|
|
283
283
|
}
|
|
284
284
|
}
|
|
285
285
|
`, m = e`
|
|
286
|
-
query GGNomadBookings($
|
|
287
|
-
ggnomadBookings(pagination: {
|
|
286
|
+
query GGNomadBookings($limit: Int, $offset: Int) {
|
|
287
|
+
ggnomadBookings(pagination: { limit: $limit, offset: $offset }) {
|
|
288
288
|
id
|
|
289
289
|
referenceCode
|
|
290
290
|
bookingType
|
|
@@ -337,8 +337,8 @@ var s = e`
|
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
339
|
`, y = e`
|
|
340
|
-
query GGNomadTripPlans($
|
|
341
|
-
ggnomadTripPlans(pagination: {
|
|
340
|
+
query GGNomadTripPlans($limit: Int, $offset: Int) {
|
|
341
|
+
ggnomadTripPlans(pagination: { limit: $limit, offset: $offset }) {
|
|
342
342
|
id
|
|
343
343
|
name
|
|
344
344
|
description
|
|
@@ -444,13 +444,13 @@ var C = e`
|
|
|
444
444
|
query GGNomadReviews(
|
|
445
445
|
$targetType: GgnomadBookingType!
|
|
446
446
|
$targetId: String!
|
|
447
|
-
$
|
|
448
|
-
$
|
|
447
|
+
$limit: Int
|
|
448
|
+
$offset: Int
|
|
449
449
|
) {
|
|
450
450
|
ggnomadReviews(
|
|
451
451
|
targetType: $targetType
|
|
452
452
|
targetId: $targetId
|
|
453
|
-
pagination: {
|
|
453
|
+
pagination: { limit: $limit, offset: $offset }
|
|
454
454
|
) {
|
|
455
455
|
id
|
|
456
456
|
rating
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql.js","names":[],"sources":["../../src/ggnomad/graphql.ts"],"sourcesContent":["import { gql } from '@apollo/client/core';\n\nexport const GGNOMAD_OVERVIEW_QUERY = gql`\n query GGNomadOverview {\n ggnomadOverviewStats {\n users\n listings\n bookings\n monthlyRevenue\n }\n ggnomadAnalytics {\n totalRevenue\n totalBookings\n totalUsers\n conversionRate\n revenueByCategory\n }\n }\n`;\n\n/**\n * One bookable item of each type (properties are priced per night, the rest\n * carry a flat price). Used to seed the Bookings \"create demo booking\" action\n * with a REAL listing id so the mutation passes the backend's\n * assertTargetInWorkspace check instead of failing on a synthetic id.\n */\nexport const GGNOMAD_BOOKABLE_SAMPLE_QUERY = gql`\n query GGNomadBookableSample {\n ggnomadProperties(pagination: { first: 1, skip: 0 }) {\n id\n name\n pricePerNight\n currency\n }\n ggnomadTours(pagination: { first: 1, skip: 0 }) {\n id\n name\n price\n currency\n }\n ggnomadEvents(pagination: { first: 1, skip: 0 }) {\n id\n name\n price\n currency\n }\n ggnomadActivities(pagination: { first: 1, skip: 0 }) {\n id\n name\n price\n currency\n }\n }\n`;\n\n/**\n * id + name for every favouritable listing type, used to (a) resolve the real\n * entity name for a saved favorite (which the backend only exposes as\n * targetType + targetId) and (b) seed the \"toggle demo favorite\" action with a\n * real target id.\n */\nexport const GGNOMAD_FAVORITE_TARGETS_QUERY = gql`\n query GGNomadFavoriteTargets {\n ggnomadProperties(pagination: { first: 100, skip: 0 }) {\n id\n name\n }\n ggnomadTours(pagination: { first: 100, skip: 0 }) {\n id\n name\n }\n ggnomadEvents(pagination: { first: 100, skip: 0 }) {\n id\n name\n }\n ggnomadActivities(pagination: { first: 100, skip: 0 }) {\n id\n name\n }\n }\n`;\n\nexport const GGNOMAD_PROVIDERS_QUERY = gql`\n query GGNomadProviders($first: Int, $skip: Int) {\n ggnomadProviders(pagination: { first: $first, skip: $skip }) {\n id\n name\n type\n status\n listingCount\n totalRevenue\n rating\n reviewCount\n contactEmail\n website\n }\n }\n`;\n\nexport const GGNOMAD_PROPERTIES_QUERY = gql`\n query GGNomadProperties($first: Int, $skip: Int) {\n ggnomadProperties(pagination: { first: $first, skip: $skip }) {\n id\n name\n type\n status\n description\n pricePerNight\n currency\n rating\n reviewCount\n maxGuests\n amenities\n images\n providerId\n }\n }\n`;\n\nexport const GGNOMAD_PROPERTY_QUERY = gql`\n query GGNomadProperty($id: ID!) {\n ggnomadProperty(id: $id) {\n id\n name\n type\n status\n description\n address\n pricePerNight\n currency\n rating\n reviewCount\n bedrooms\n bathrooms\n maxGuests\n checkInTime\n checkOutTime\n amenities\n images\n provider {\n id\n name\n type\n rating\n }\n }\n }\n`;\n\n// Query to get property details for booking - ensures id is included\nexport const GGNOMAD_PROPERTY_FOR_BOOKING_QUERY = gql`\n query GGNomadPropertyForBooking($id: ID!) {\n ggnomadProperty(id: $id) {\n id\n name\n pricePerNight\n currency\n }\n }\n`;\n\nexport const GGNOMAD_TOURS_QUERY = gql`\n query GGNomadTours($first: Int, $skip: Int) {\n ggnomadTours(pagination: { first: $first, skip: $skip }) {\n id\n name\n description\n type\n status\n duration\n difficulty\n price\n currency\n rating\n reviewCount\n highlights\n images\n }\n }\n`;\n\nexport const GGNOMAD_TOUR_QUERY = gql`\n query GGNomadTour($id: ID!) {\n ggnomadTour(id: $id) {\n id\n name\n description\n type\n status\n duration\n difficulty\n price\n currency\n rating\n reviewCount\n highlights\n images\n languages\n guideName\n provider {\n id\n name\n }\n }\n }\n`;\n\nexport const GGNOMAD_EVENTS_QUERY = gql`\n query GGNomadEvents($first: Int, $skip: Int) {\n ggnomadEvents(pagination: { first: $first, skip: $skip }) {\n id\n name\n description\n category\n status\n startsAt\n price\n currency\n rating\n reviewCount\n performers\n images\n }\n }\n`;\n\nexport const GGNOMAD_EVENT_QUERY = gql`\n query GGNomadEvent($id: ID!) {\n ggnomadEvent(id: $id) {\n id\n name\n description\n category\n status\n startsAt\n endsAt\n venue\n price\n currency\n rating\n reviewCount\n performers\n images\n provider {\n id\n name\n }\n }\n }\n`;\n\nexport const GGNOMAD_ACTIVITIES_QUERY = gql`\n query GGNomadActivities($first: Int, $skip: Int) {\n ggnomadActivities(pagination: { first: $first, skip: $skip }) {\n id\n name\n description\n category\n status\n duration\n difficulty\n price\n currency\n rating\n reviewCount\n maxParticipants\n includes\n requirements\n images\n }\n }\n`;\n\nexport const GGNOMAD_ACTIVITY_QUERY = gql`\n query GGNomadActivity($id: ID!) {\n ggnomadActivity(id: $id) {\n id\n name\n description\n category\n status\n location\n duration\n difficulty\n price\n currency\n rating\n reviewCount\n maxParticipants\n includes\n requirements\n safetyInfo\n images\n provider {\n id\n name\n }\n }\n }\n`;\n\nexport const GGNOMAD_TRIPS_QUERY = gql`\n query GGNomadTrips($first: Int, $skip: Int) {\n ggnomadTrips(pagination: { first: $first, skip: $skip }) {\n id\n name\n transportMode\n status\n origin\n destination\n departureAt\n arrivalAt\n isRoundTrip\n carrier\n class\n price\n currency\n passengers\n ecoFriendly\n }\n }\n`;\n\nexport const GGNOMAD_BOOKINGS_QUERY = gql`\n query GGNomadBookings($first: Int, $skip: Int) {\n ggnomadBookings(pagination: { first: $first, skip: $skip }) {\n id\n referenceCode\n bookingType\n status\n itemId\n itemName\n guestName\n guestEmail\n guestPhone\n guests\n checkIn\n checkOut\n eventDate\n totalPrice\n currency\n paymentStatus\n paymentMethod\n specialRequests\n createdAt\n }\n }\n`;\n\nexport const GGNOMAD_FAVORITES_QUERY = gql`\n query GGNomadFavorites {\n ggnomadFavorites\n }\n`;\n\nexport const CREATE_GGNOMAD_BOOKING_MUTATION = gql`\n mutation CreateGGNomadBooking($input: CreateGgnomadBookingInput!) {\n createGgnomadBooking(input: $input) {\n id\n referenceCode\n bookingType\n status\n itemId\n itemName\n guestName\n totalPrice\n currency\n createdAt\n }\n }\n`;\n\nexport const TOGGLE_GGNOMAD_FAVORITE_MUTATION = gql`\n mutation ToggleGGNomadFavorite($input: ToggleGgnomadFavoriteInput!) {\n toggleGgnomadFavorite(input: $input)\n }\n`;\n\nexport const CANCEL_GGNOMAD_BOOKING_MUTATION = gql`\n mutation CancelGGNomadBooking($id: ID!, $reason: String) {\n cancelGgnomadBooking(id: $id, reason: $reason) {\n id\n status\n }\n }\n`;\n\n// Trip Plan Queries\nexport const GGNOMAD_TRIP_PLANS_QUERY = gql`\n query GGNomadTripPlans($first: Int, $skip: Int) {\n ggnomadTripPlans(pagination: { first: $first, skip: $skip }) {\n id\n name\n description\n startDate\n endDate\n travelers\n status\n total\n itemCount\n createdAt\n }\n }\n`;\n\nexport const GGNOMAD_TRIP_PLAN_QUERY = gql`\n query GGNomadTripPlan($id: ID!) {\n ggnomadTripPlan(id: $id) {\n id\n name\n description\n startDate\n endDate\n travelers\n status\n total\n itemCount\n items {\n id\n itemType\n itemId\n itemName\n day\n scheduledAt\n price\n currency\n notes\n }\n createdAt\n updatedAt\n }\n }\n`;\n\n// Trip Plan Mutations\nexport const CREATE_GGNOMAD_TRIP_PLAN_MUTATION = gql`\n mutation CreateGGNomadTripPlan($input: CreateGgnomadTripPlanInput!) {\n createGgnomadTripPlan(input: $input) {\n id\n name\n description\n startDate\n endDate\n travelers\n status\n total\n itemCount\n createdAt\n }\n }\n`;\n\nexport const UPDATE_GGNOMAD_TRIP_PLAN_MUTATION = gql`\n mutation UpdateGGNomadTripPlan($id: ID!, $input: UpdateGgnomadTripPlanInput!) {\n updateGgnomadTripPlan(id: $id, input: $input) {\n id\n name\n description\n startDate\n endDate\n travelers\n status\n total\n itemCount\n updatedAt\n }\n }\n`;\n\nexport const DELETE_GGNOMAD_TRIP_PLAN_MUTATION = gql`\n mutation DeleteGGNomadTripPlan($id: ID!) {\n deleteGgnomadTripPlan(id: $id)\n }\n`;\n\nexport const ADD_GGNOMAD_TRIP_PLAN_ITEM_MUTATION = gql`\n mutation AddGGNomadTripPlanItem($tripPlanId: ID!, $input: AddGgnomadTripPlanItemInput!) {\n addGgnomadTripPlanItem(tripPlanId: $tripPlanId, input: $input) {\n id\n itemType\n itemId\n itemName\n day\n scheduledAt\n price\n currency\n notes\n }\n }\n`;\n\nexport const REMOVE_GGNOMAD_TRIP_PLAN_ITEM_MUTATION = gql`\n mutation RemoveGGNomadTripPlanItem($id: ID!) {\n removeGgnomadTripPlanItem(id: $id)\n }\n`;\n\n// Review Queries\nexport const GGNOMAD_REVIEW_SUMMARY_QUERY = gql`\n query GGNomadReviewSummary($targetType: GgnomadBookingType!, $targetId: String!) {\n ggnomadReviewSummary(targetType: $targetType, targetId: $targetId) {\n average\n count\n distribution\n }\n }\n`;\n\nexport const GGNOMAD_REVIEWS_QUERY = gql`\n query GGNomadReviews(\n $targetType: GgnomadBookingType!\n $targetId: String!\n $first: Int\n $skip: Int\n ) {\n ggnomadReviews(\n targetType: $targetType\n targetId: $targetId\n pagination: { first: $first, skip: $skip }\n ) {\n id\n rating\n title\n content\n images\n isVerified\n helpfulCount\n response\n respondedAt\n createdAt\n }\n }\n`;\n\n// Review Mutations\nexport const CREATE_GGNOMAD_REVIEW_MUTATION = gql`\n mutation CreateGGNomadReview($input: CreateGgnomadReviewInput!) {\n createGgnomadReview(input: $input) {\n id\n rating\n title\n content\n }\n }\n`;\n\nexport const RESPOND_GGNOMAD_REVIEW_MUTATION = gql`\n mutation RespondGGNomadReview($id: ID!, $response: String!) {\n respondGgnomadReview(id: $id, response: $response) {\n id\n response\n respondedAt\n }\n }\n`;\n\n// Listing Edit Mutations\nexport const UPDATE_GGNOMAD_PROPERTY_MUTATION = gql`\n mutation UpdateGGNomadProperty($id: ID!, $input: UpdateGgnomadPropertyInput!) {\n updateGgnomadProperty(id: $id, input: $input) {\n id\n name\n description\n pricePerNight\n status\n images\n }\n }\n`;\n\nexport const UPDATE_GGNOMAD_TOUR_MUTATION = gql`\n mutation UpdateGGNomadTour($id: ID!, $input: UpdateGgnomadTourInput!) {\n updateGgnomadTour(id: $id, input: $input) {\n id\n name\n description\n price\n status\n images\n }\n }\n`;\n\nexport const UPDATE_GGNOMAD_EVENT_MUTATION = gql`\n mutation UpdateGGNomadEvent($id: ID!, $input: UpdateGgnomadEventInput!) {\n updateGgnomadEvent(id: $id, input: $input) {\n id\n name\n description\n price\n status\n images\n }\n }\n`;\n\nexport const UPDATE_GGNOMAD_ACTIVITY_MUTATION = gql`\n mutation UpdateGGNomadActivity($id: ID!, $input: UpdateGgnomadActivityInput!) {\n updateGgnomadActivity(id: $id, input: $input) {\n id\n name\n description\n price\n status\n images\n }\n }\n`;\n"],"mappings":";;AAEA,IAAa,IAAyB,CAAG;;;;;;;;;;;;;;;;GAwB5B,IAAgC,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCnC,IAAiC,CAAG;;;;;;;;;;;;;;;;;;;GAqBpC,IAA0B,CAAG;;;;;;;;;;;;;;;GAiB7B,IAA2B,CAAG;;;;;;;;;;;;;;;;;;GAoB9B,IAAyB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BS,CAAG;;;;;;;;;;AAWrD,IAAa,IAAsB,CAAG;;;;;;;;;;;;;;;;;;GAoBzB,IAAqB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;GA0BxB,IAAuB,CAAG;;;;;;;;;;;;;;;;;GAmB1B,IAAsB,CAAG;;;;;;;;;;;;;;;;;;;;;;;GAyBzB,IAA2B,CAAG;;;;;;;;;;;;;;;;;;;;GAsB9B,IAAyB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;GA4B5B,IAAsB,CAAG;;;;;;;;;;;;;;;;;;;;GAsBzB,IAAyB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;GA0B5B,IAA0B,CAAG;;;;GAM7B,IAAkC,CAAG;;;;;;;;;;;;;;;GAiBrC,IAAmC,CAAG;;;;GAMtC,IAAkC,CAAG;;;;;;;GAUrC,IAA2B,CAAG;;;;;;;;;;;;;;;GAiB9B,IAA0B,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8B7B,IAAoC,CAAG;;;;;;;;;;;;;;;GAiBvC,IAAoC,CAAG;;;;;;;;;;;;;;;;AAiBH,CAAG;;;;;AAMpD,IAAa,IAAsC,CAAG;;;;;;;;;;;;;;GAgBzC,IAAyC,CAAG;;;;GAO5C,IAA+B,CAAG;;;;;;;;GAUlC,IAAwB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;GA2B3B,IAAiC,CAAG;;;;;;;;;;AAWF,CAAG;;;;;;;;;AAWlD,IAAa,IAAmC,CAAG;;;;;;;;;;;GAatC,IAA+B,CAAG;;;;;;;;;;;GAalC,IAAgC,CAAG;;;;;;;;;;;GAanC,IAAmC,CAAG"}
|
|
1
|
+
{"version":3,"file":"graphql.js","names":[],"sources":["../../src/ggnomad/graphql.ts"],"sourcesContent":["import { gql } from '@apollo/client/core';\n\nexport const GGNOMAD_OVERVIEW_QUERY = gql`\n query GGNomadOverview {\n ggnomadOverviewStats {\n users\n listings\n bookings\n monthlyRevenue\n }\n ggnomadAnalytics {\n totalRevenue\n totalBookings\n totalUsers\n conversionRate\n revenueByCategory\n }\n }\n`;\n\n/**\n * One bookable item of each type (properties are priced per night, the rest\n * carry a flat price). Used to seed the Bookings \"create demo booking\" action\n * with a REAL listing id so the mutation passes the backend's\n * assertTargetInWorkspace check instead of failing on a synthetic id.\n */\nexport const GGNOMAD_BOOKABLE_SAMPLE_QUERY = gql`\n query GGNomadBookableSample {\n ggnomadProperties(pagination: { limit: 1, offset: 0 }) {\n id\n name\n pricePerNight\n currency\n }\n ggnomadTours(pagination: { limit: 1, offset: 0 }) {\n id\n name\n price\n currency\n }\n ggnomadEvents(pagination: { limit: 1, offset: 0 }) {\n id\n name\n price\n currency\n }\n ggnomadActivities(pagination: { limit: 1, offset: 0 }) {\n id\n name\n price\n currency\n }\n }\n`;\n\n/**\n * id + name for every favouritable listing type, used to (a) resolve the real\n * entity name for a saved favorite (which the backend only exposes as\n * targetType + targetId) and (b) seed the \"toggle demo favorite\" action with a\n * real target id.\n */\nexport const GGNOMAD_FAVORITE_TARGETS_QUERY = gql`\n query GGNomadFavoriteTargets {\n ggnomadProperties(pagination: { limit: 100, offset: 0 }) {\n id\n name\n }\n ggnomadTours(pagination: { limit: 100, offset: 0 }) {\n id\n name\n }\n ggnomadEvents(pagination: { limit: 100, offset: 0 }) {\n id\n name\n }\n ggnomadActivities(pagination: { limit: 100, offset: 0 }) {\n id\n name\n }\n }\n`;\n\nexport const GGNOMAD_PROVIDERS_QUERY = gql`\n query GGNomadProviders($limit: Int, $offset: Int) {\n ggnomadProviders(pagination: { limit: $limit, offset: $offset }) {\n id\n name\n type\n status\n listingCount\n totalRevenue\n rating\n reviewCount\n contactEmail\n website\n }\n }\n`;\n\nexport const GGNOMAD_PROPERTIES_QUERY = gql`\n query GGNomadProperties($limit: Int, $offset: Int) {\n ggnomadProperties(pagination: { limit: $limit, offset: $offset }) {\n id\n name\n type\n status\n description\n pricePerNight\n currency\n rating\n reviewCount\n maxGuests\n amenities\n images\n providerId\n }\n }\n`;\n\nexport const GGNOMAD_PROPERTY_QUERY = gql`\n query GGNomadProperty($id: ID!) {\n ggnomadProperty(id: $id) {\n id\n name\n type\n status\n description\n address\n pricePerNight\n currency\n rating\n reviewCount\n bedrooms\n bathrooms\n maxGuests\n checkInTime\n checkOutTime\n amenities\n images\n provider {\n id\n name\n type\n rating\n }\n }\n }\n`;\n\n// Query to get property details for booking - ensures id is included\nexport const GGNOMAD_PROPERTY_FOR_BOOKING_QUERY = gql`\n query GGNomadPropertyForBooking($id: ID!) {\n ggnomadProperty(id: $id) {\n id\n name\n pricePerNight\n currency\n }\n }\n`;\n\nexport const GGNOMAD_TOURS_QUERY = gql`\n query GGNomadTours($limit: Int, $offset: Int) {\n ggnomadTours(pagination: { limit: $limit, offset: $offset }) {\n id\n name\n description\n type\n status\n duration\n difficulty\n price\n currency\n rating\n reviewCount\n highlights\n images\n }\n }\n`;\n\nexport const GGNOMAD_TOUR_QUERY = gql`\n query GGNomadTour($id: ID!) {\n ggnomadTour(id: $id) {\n id\n name\n description\n type\n status\n duration\n difficulty\n price\n currency\n rating\n reviewCount\n highlights\n images\n languages\n guideName\n provider {\n id\n name\n }\n }\n }\n`;\n\nexport const GGNOMAD_EVENTS_QUERY = gql`\n query GGNomadEvents($limit: Int, $offset: Int) {\n ggnomadEvents(pagination: { limit: $limit, offset: $offset }) {\n id\n name\n description\n category\n status\n startsAt\n price\n currency\n rating\n reviewCount\n performers\n images\n }\n }\n`;\n\nexport const GGNOMAD_EVENT_QUERY = gql`\n query GGNomadEvent($id: ID!) {\n ggnomadEvent(id: $id) {\n id\n name\n description\n category\n status\n startsAt\n endsAt\n venue\n price\n currency\n rating\n reviewCount\n performers\n images\n provider {\n id\n name\n }\n }\n }\n`;\n\nexport const GGNOMAD_ACTIVITIES_QUERY = gql`\n query GGNomadActivities($limit: Int, $offset: Int) {\n ggnomadActivities(pagination: { limit: $limit, offset: $offset }) {\n id\n name\n description\n category\n status\n duration\n difficulty\n price\n currency\n rating\n reviewCount\n maxParticipants\n includes\n requirements\n images\n }\n }\n`;\n\nexport const GGNOMAD_ACTIVITY_QUERY = gql`\n query GGNomadActivity($id: ID!) {\n ggnomadActivity(id: $id) {\n id\n name\n description\n category\n status\n location\n duration\n difficulty\n price\n currency\n rating\n reviewCount\n maxParticipants\n includes\n requirements\n safetyInfo\n images\n provider {\n id\n name\n }\n }\n }\n`;\n\nexport const GGNOMAD_TRIPS_QUERY = gql`\n query GGNomadTrips($limit: Int, $offset: Int) {\n ggnomadTrips(pagination: { limit: $limit, offset: $offset }) {\n id\n name\n transportMode\n status\n origin\n destination\n departureAt\n arrivalAt\n isRoundTrip\n carrier\n class\n price\n currency\n passengers\n ecoFriendly\n }\n }\n`;\n\nexport const GGNOMAD_BOOKINGS_QUERY = gql`\n query GGNomadBookings($limit: Int, $offset: Int) {\n ggnomadBookings(pagination: { limit: $limit, offset: $offset }) {\n id\n referenceCode\n bookingType\n status\n itemId\n itemName\n guestName\n guestEmail\n guestPhone\n guests\n checkIn\n checkOut\n eventDate\n totalPrice\n currency\n paymentStatus\n paymentMethod\n specialRequests\n createdAt\n }\n }\n`;\n\nexport const GGNOMAD_FAVORITES_QUERY = gql`\n query GGNomadFavorites {\n ggnomadFavorites\n }\n`;\n\nexport const CREATE_GGNOMAD_BOOKING_MUTATION = gql`\n mutation CreateGGNomadBooking($input: CreateGgnomadBookingInput!) {\n createGgnomadBooking(input: $input) {\n id\n referenceCode\n bookingType\n status\n itemId\n itemName\n guestName\n totalPrice\n currency\n createdAt\n }\n }\n`;\n\nexport const TOGGLE_GGNOMAD_FAVORITE_MUTATION = gql`\n mutation ToggleGGNomadFavorite($input: ToggleGgnomadFavoriteInput!) {\n toggleGgnomadFavorite(input: $input)\n }\n`;\n\nexport const CANCEL_GGNOMAD_BOOKING_MUTATION = gql`\n mutation CancelGGNomadBooking($id: ID!, $reason: String) {\n cancelGgnomadBooking(id: $id, reason: $reason) {\n id\n status\n }\n }\n`;\n\n// Trip Plan Queries\nexport const GGNOMAD_TRIP_PLANS_QUERY = gql`\n query GGNomadTripPlans($limit: Int, $offset: Int) {\n ggnomadTripPlans(pagination: { limit: $limit, offset: $offset }) {\n id\n name\n description\n startDate\n endDate\n travelers\n status\n total\n itemCount\n createdAt\n }\n }\n`;\n\nexport const GGNOMAD_TRIP_PLAN_QUERY = gql`\n query GGNomadTripPlan($id: ID!) {\n ggnomadTripPlan(id: $id) {\n id\n name\n description\n startDate\n endDate\n travelers\n status\n total\n itemCount\n items {\n id\n itemType\n itemId\n itemName\n day\n scheduledAt\n price\n currency\n notes\n }\n createdAt\n updatedAt\n }\n }\n`;\n\n// Trip Plan Mutations\nexport const CREATE_GGNOMAD_TRIP_PLAN_MUTATION = gql`\n mutation CreateGGNomadTripPlan($input: CreateGgnomadTripPlanInput!) {\n createGgnomadTripPlan(input: $input) {\n id\n name\n description\n startDate\n endDate\n travelers\n status\n total\n itemCount\n createdAt\n }\n }\n`;\n\nexport const UPDATE_GGNOMAD_TRIP_PLAN_MUTATION = gql`\n mutation UpdateGGNomadTripPlan($id: ID!, $input: UpdateGgnomadTripPlanInput!) {\n updateGgnomadTripPlan(id: $id, input: $input) {\n id\n name\n description\n startDate\n endDate\n travelers\n status\n total\n itemCount\n updatedAt\n }\n }\n`;\n\nexport const DELETE_GGNOMAD_TRIP_PLAN_MUTATION = gql`\n mutation DeleteGGNomadTripPlan($id: ID!) {\n deleteGgnomadTripPlan(id: $id)\n }\n`;\n\nexport const ADD_GGNOMAD_TRIP_PLAN_ITEM_MUTATION = gql`\n mutation AddGGNomadTripPlanItem($tripPlanId: ID!, $input: AddGgnomadTripPlanItemInput!) {\n addGgnomadTripPlanItem(tripPlanId: $tripPlanId, input: $input) {\n id\n itemType\n itemId\n itemName\n day\n scheduledAt\n price\n currency\n notes\n }\n }\n`;\n\nexport const REMOVE_GGNOMAD_TRIP_PLAN_ITEM_MUTATION = gql`\n mutation RemoveGGNomadTripPlanItem($id: ID!) {\n removeGgnomadTripPlanItem(id: $id)\n }\n`;\n\n// Review Queries\nexport const GGNOMAD_REVIEW_SUMMARY_QUERY = gql`\n query GGNomadReviewSummary($targetType: GgnomadBookingType!, $targetId: String!) {\n ggnomadReviewSummary(targetType: $targetType, targetId: $targetId) {\n average\n count\n distribution\n }\n }\n`;\n\nexport const GGNOMAD_REVIEWS_QUERY = gql`\n query GGNomadReviews(\n $targetType: GgnomadBookingType!\n $targetId: String!\n $limit: Int\n $offset: Int\n ) {\n ggnomadReviews(\n targetType: $targetType\n targetId: $targetId\n pagination: { limit: $limit, offset: $offset }\n ) {\n id\n rating\n title\n content\n images\n isVerified\n helpfulCount\n response\n respondedAt\n createdAt\n }\n }\n`;\n\n// Review Mutations\nexport const CREATE_GGNOMAD_REVIEW_MUTATION = gql`\n mutation CreateGGNomadReview($input: CreateGgnomadReviewInput!) {\n createGgnomadReview(input: $input) {\n id\n rating\n title\n content\n }\n }\n`;\n\nexport const RESPOND_GGNOMAD_REVIEW_MUTATION = gql`\n mutation RespondGGNomadReview($id: ID!, $response: String!) {\n respondGgnomadReview(id: $id, response: $response) {\n id\n response\n respondedAt\n }\n }\n`;\n\n// Listing Edit Mutations\nexport const UPDATE_GGNOMAD_PROPERTY_MUTATION = gql`\n mutation UpdateGGNomadProperty($id: ID!, $input: UpdateGgnomadPropertyInput!) {\n updateGgnomadProperty(id: $id, input: $input) {\n id\n name\n description\n pricePerNight\n status\n images\n }\n }\n`;\n\nexport const UPDATE_GGNOMAD_TOUR_MUTATION = gql`\n mutation UpdateGGNomadTour($id: ID!, $input: UpdateGgnomadTourInput!) {\n updateGgnomadTour(id: $id, input: $input) {\n id\n name\n description\n price\n status\n images\n }\n }\n`;\n\nexport const UPDATE_GGNOMAD_EVENT_MUTATION = gql`\n mutation UpdateGGNomadEvent($id: ID!, $input: UpdateGgnomadEventInput!) {\n updateGgnomadEvent(id: $id, input: $input) {\n id\n name\n description\n price\n status\n images\n }\n }\n`;\n\nexport const UPDATE_GGNOMAD_ACTIVITY_MUTATION = gql`\n mutation UpdateGGNomadActivity($id: ID!, $input: UpdateGgnomadActivityInput!) {\n updateGgnomadActivity(id: $id, input: $input) {\n id\n name\n description\n price\n status\n images\n }\n }\n`;\n"],"mappings":";;AAEA,IAAa,IAAyB,CAAG;;;;;;;;;;;;;;;;GAwB5B,IAAgC,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCnC,IAAiC,CAAG;;;;;;;;;;;;;;;;;;;GAqBpC,IAA0B,CAAG;;;;;;;;;;;;;;;GAiB7B,IAA2B,CAAG;;;;;;;;;;;;;;;;;;GAoB9B,IAAyB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BS,CAAG;;;;;;;;;;AAWrD,IAAa,IAAsB,CAAG;;;;;;;;;;;;;;;;;;GAoBzB,IAAqB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;GA0BxB,IAAuB,CAAG;;;;;;;;;;;;;;;;;GAmB1B,IAAsB,CAAG;;;;;;;;;;;;;;;;;;;;;;;GAyBzB,IAA2B,CAAG;;;;;;;;;;;;;;;;;;;;GAsB9B,IAAyB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;GA4B5B,IAAsB,CAAG;;;;;;;;;;;;;;;;;;;;GAsBzB,IAAyB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;GA0B5B,IAA0B,CAAG;;;;GAM7B,IAAkC,CAAG;;;;;;;;;;;;;;;GAiBrC,IAAmC,CAAG;;;;GAMtC,IAAkC,CAAG;;;;;;;GAUrC,IAA2B,CAAG;;;;;;;;;;;;;;;GAiB9B,IAA0B,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8B7B,IAAoC,CAAG;;;;;;;;;;;;;;;GAiBvC,IAAoC,CAAG;;;;;;;;;;;;;;;;AAiBH,CAAG;;;;;AAMpD,IAAa,IAAsC,CAAG;;;;;;;;;;;;;;GAgBzC,IAAyC,CAAG;;;;GAO5C,IAA+B,CAAG;;;;;;;;GAUlC,IAAwB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;GA2B3B,IAAiC,CAAG;;;;;;;;;;AAWF,CAAG;;;;;;;;;AAWlD,IAAa,IAAmC,CAAG;;;;;;;;;;;GAatC,IAA+B,CAAG;;;;;;;;;;;GAalC,IAAgC,CAAG;;;;;;;;;;;GAanC,IAAmC,CAAG"}
|
|
@@ -14,8 +14,8 @@ import { jsx as N, jsxs as P } from "react/jsx-runtime";
|
|
|
14
14
|
//#region src/ggnomad/pages/BookingsPage.tsx
|
|
15
15
|
function F() {
|
|
16
16
|
let { t: F } = g(), I = _(), [L, R] = l(null), { data: z, refetch: B } = y(r, { variables: {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
limit: 20,
|
|
18
|
+
offset: 0
|
|
19
19
|
} }), { data: V } = y(n), [H, { loading: U }] = v(t), [W, { loading: G }] = v(e), K = c(() => z?.ggnomadBookings ?? [], [z?.ggnomadBookings]), q = c(() => {
|
|
20
20
|
let e = {
|
|
21
21
|
CONFIRMED: 0,
|