@burdenoff/microfe-ggnomad 2026.719.1 → 2026.719.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TripsPage.js","names":[],"sources":["../../../src/ggnomad/pages/TripsPage.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 { Calendar, Map, Plus } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n CTAOverflowMenu,\n GlassCard,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\n\nimport { CREATE_GGNOMAD_TRIP_PLAN_MUTATION, GGNOMAD_TRIP_PLANS_QUERY } from '../graphql';\nimport { PageShell } from './PageShell';\nimport { EntityCard, StatusBadge } from '../components';\nimport { notify } from '../utils/notify';\n\ninterface NewTripFormState {\n name: string;\n startDate: string;\n endDate: string;\n}\n\nconst defaultFormState: NewTripFormState = {\n name: '',\n startDate: '',\n endDate: '',\n};\n\nexport function TripsPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const [showNewTripDialog, setShowNewTripDialog] = useState(false);\n const [formState, setFormState] = useState<NewTripFormState>(defaultFormState);\n\n const { data, refetch } = useQuery(\n GGNOMAD_TRIP_PLANS_QUERY as TypedDocumentNode<\n {\n ggnomadTripPlans: Array<{\n id: string;\n name: string;\n description?: string;\n startDate?: string;\n endDate?: string;\n travelers: number;\n status: string;\n total: number;\n itemCount: number;\n createdAt: string;\n }>;\n },\n { first: number; skip: number }\n >,\n { variables: { first: 50, skip: 0 } }\n );\n\n const [createTripPlan, { loading: creating }] = useMutation(\n CREATE_GGNOMAD_TRIP_PLAN_MUTATION as TypedDocumentNode<\n {\n createGgnomadTripPlan: {\n id: string;\n name: string;\n startDate?: string;\n endDate?: string;\n };\n },\n {\n input: {\n name: string;\n description?: string;\n startDate?: string;\n endDate?: string;\n travelers?: number;\n };\n }\n >\n );\n\n const trips = data?.ggnomadTripPlans ?? [];\n\n const handleCreateTrip = async () => {\n if (!formState.name.trim()) {\n notify.warning(\n t('ggnomad.trips.toast.validationTitle', 'Required field missing'),\n t('ggnomad.trips.toast.nameRequired', 'Please enter a trip name')\n );\n return;\n }\n\n try {\n const result = await createTripPlan({\n variables: {\n input: {\n name: formState.name.trim(),\n startDate: formState.startDate\n ? new Date(formState.startDate).toISOString()\n : undefined,\n endDate: formState.endDate ? new Date(formState.endDate).toISOString() : undefined,\n travelers: 1,\n },\n },\n });\n\n if (result.error) {\n notify.error(\n t('ggnomad.trips.toast.createErrorTitle', 'Could not create trip'),\n result.error.message\n );\n return;\n }\n\n const created = result.data?.createGgnomadTripPlan;\n if (!created) return;\n\n notify.success(t('ggnomad.trips.toast.createSuccessTitle', 'Trip created'), created.name);\n\n setShowNewTripDialog(false);\n setFormState(defaultFormState);\n await refetch();\n navigate(`trips/${created.id}`);\n } catch (err) {\n notify.error(\n t('ggnomad.trips.toast.createErrorTitle', 'Could not create trip'),\n err instanceof Error ? err.message : String(err)\n );\n }\n };\n\n const formatDate = (dateStr?: string) => {\n if (!dateStr) return '';\n const date = new Date(dateStr);\n return date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n });\n };\n\n return (\n <PageShell\n title={t('ggnomad.trips.title', 'Trips')}\n titleAccent={t('ggnomad.trips.title.accent', 'Trips')}\n subtitle={t(\n 'ggnomad.trips.subtitle',\n 'Plan complete itineraries with real trip planning API mutations'\n )}\n actions={\n <CTAOverflowMenu\n primary={{\n label: t('ggnomad.trips.actions.newTrip', 'New trip'),\n onSelect: () => setShowNewTripDialog(true),\n disabled: creating,\n icon: <Plus />,\n }}\n actions={[]}\n />\n }\n >\n <PagePurpose icon={<Map className=\"size-4\" />}>\n {t(\n 'ggnomad.trips.purpose',\n 'Organize every aspect of your journey — build itineraries day by day, add activities and accommodations, manage your trip status, and book everything at once. All your trips in one place.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"ggnomad-trips\"\n steps={[\n {\n id: 'add-stays',\n label: t('ggnomad.trips.next.stays', 'Add places to stay'),\n description: t(\n 'ggnomad.trips.next.staysDesc',\n 'Browse accommodations and add them to your itinerary.'\n ),\n icon: <Calendar className=\"size-4\" />,\n onClick: () => navigate('../hospitality'),\n },\n {\n id: 'build-activities',\n label: t('ggnomad.trips.next.activities', 'Plan activities'),\n description: t(\n 'ggnomad.trips.next.activitiesDesc',\n 'Mix in tours, events, and activities by day.'\n ),\n icon: <Map className=\"size-4\" />,\n onClick: () => navigate('../tourism'),\n },\n ]}\n />\n\n {trips.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.trips.emptyTitle', 'No trips yet')}\n description={t(\n 'ggnomad.trips.emptyDescription',\n 'Create your first trip to start building an itinerary.'\n )}\n />\n ) : (\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-5\">\n <h2 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.trips.yourTrips', 'Your trips')}\n </h2>\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {trips.map((trip) => (\n <EntityCard\n key={trip.id}\n to={`trips/${trip.id}`}\n title={trip.name}\n meta={`${trip.travelers} ${\n trip.travelers === 1\n ? t('ggnomad.trips.card.traveler', 'traveler')\n : t('ggnomad.trips.card.travelers', 'travelers')\n } · ${trip.itemCount} ${t('ggnomad.trips.card.items', 'items')}`}\n price={trip.total > 0 ? `USD ${trip.total.toFixed(2)}` : ''}\n badge={<StatusBadge status={trip.status} live={trip.status !== 'CANCELLED'} />}\n footer={\n trip.startDate && trip.endDate\n ? `${formatDate(trip.startDate)} – ${formatDate(trip.endDate)}`\n : t('ggnomad.trips.card.noDates', 'No dates set')\n }\n />\n ))}\n </div>\n </GlassCard>\n )}\n\n <AlertDialog open={showNewTripDialog} onOpenChange={setShowNewTripDialog}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {t('ggnomad.trips.newDialog.title', 'Create a new trip')}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {t(\n 'ggnomad.trips.newDialog.description',\n 'Name your trip and set the dates to get started building your itinerary.'\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n\n <div className=\"space-y-4\">\n <div>\n <label htmlFor=\"trip-name\" className=\"block text-sm font-medium text-text-primary\">\n {t('ggnomad.trips.newDialog.tripName', 'Trip name')}\n </label>\n <input\n id=\"trip-name\"\n type=\"text\"\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-primary focus:outline-none focus:ring-1 focus:ring-primary\"\n placeholder={t(\n 'ggnomad.trips.newDialog.tripNamePlaceholder',\n 'e.g. Summer Europe Adventure'\n )}\n value={formState.name}\n onChange={(e) => setFormState((prev) => ({ ...prev, name: e.target.value }))}\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label\n htmlFor=\"trip-start-date\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n {t('ggnomad.trips.newDialog.startDate', 'Start date')}\n </label>\n <input\n id=\"trip-start-date\"\n type=\"date\"\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-primary focus:outline-none focus:ring-1 focus:ring-primary\"\n value={formState.startDate}\n onChange={(e) => setFormState((prev) => ({ ...prev, startDate: e.target.value }))}\n />\n </div>\n <div>\n <label\n htmlFor=\"trip-end-date\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n {t('ggnomad.trips.newDialog.endDate', 'End date')}\n </label>\n <input\n id=\"trip-end-date\"\n type=\"date\"\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-primary focus:outline-none focus:ring-1 focus:ring-primary\"\n value={formState.endDate}\n onChange={(e) => setFormState((prev) => ({ ...prev, endDate: e.target.value }))}\n />\n </div>\n </div>\n </div>\n\n <AlertDialogFooter>\n <AlertDialogCancel disabled={creating}>\n {t('ggnomad.trips.newDialog.cancel', 'Cancel')}\n </AlertDialogCancel>\n <AlertDialogAction\n disabled={creating || !formState.name.trim()}\n onClick={(event) => {\n event.preventDefault();\n void handleCreateTrip();\n }}\n >\n {creating\n ? t('ggnomad.trips.newDialog.creating', 'Creating…')\n : t('ggnomad.trips.newDialog.create', 'Create trip')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </PageShell>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TripsPage.js","names":[],"sources":["../../../src/ggnomad/pages/TripsPage.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 { Calendar, Map, Plus } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n CTAOverflowMenu,\n GlassCard,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\n\nimport { CREATE_GGNOMAD_TRIP_PLAN_MUTATION, GGNOMAD_TRIP_PLANS_QUERY } from '../graphql';\nimport { PageShell } from './PageShell';\nimport { EntityCard, StatusBadge } from '../components';\nimport { notify } from '../utils/notify';\n\ninterface NewTripFormState {\n name: string;\n startDate: string;\n endDate: string;\n}\n\nconst defaultFormState: NewTripFormState = {\n name: '',\n startDate: '',\n endDate: '',\n};\n\nexport function TripsPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const [showNewTripDialog, setShowNewTripDialog] = useState(false);\n const [formState, setFormState] = useState<NewTripFormState>(defaultFormState);\n\n const { data, refetch } = useQuery(\n GGNOMAD_TRIP_PLANS_QUERY as TypedDocumentNode<\n {\n ggnomadTripPlans: Array<{\n id: string;\n name: string;\n description?: string;\n startDate?: string;\n endDate?: string;\n travelers: number;\n status: string;\n total: number;\n itemCount: number;\n createdAt: string;\n }>;\n },\n { limit: number; offset: number }\n >,\n { variables: { limit: 50, offset: 0 } }\n );\n\n const [createTripPlan, { loading: creating }] = useMutation(\n CREATE_GGNOMAD_TRIP_PLAN_MUTATION as TypedDocumentNode<\n {\n createGgnomadTripPlan: {\n id: string;\n name: string;\n startDate?: string;\n endDate?: string;\n };\n },\n {\n input: {\n name: string;\n description?: string;\n startDate?: string;\n endDate?: string;\n travelers?: number;\n };\n }\n >\n );\n\n const trips = data?.ggnomadTripPlans ?? [];\n\n const handleCreateTrip = async () => {\n if (!formState.name.trim()) {\n notify.warning(\n t('ggnomad.trips.toast.validationTitle', 'Required field missing'),\n t('ggnomad.trips.toast.nameRequired', 'Please enter a trip name')\n );\n return;\n }\n\n try {\n const result = await createTripPlan({\n variables: {\n input: {\n name: formState.name.trim(),\n startDate: formState.startDate\n ? new Date(formState.startDate).toISOString()\n : undefined,\n endDate: formState.endDate ? new Date(formState.endDate).toISOString() : undefined,\n travelers: 1,\n },\n },\n });\n\n if (result.error) {\n notify.error(\n t('ggnomad.trips.toast.createErrorTitle', 'Could not create trip'),\n result.error.message\n );\n return;\n }\n\n const created = result.data?.createGgnomadTripPlan;\n if (!created) return;\n\n notify.success(t('ggnomad.trips.toast.createSuccessTitle', 'Trip created'), created.name);\n\n setShowNewTripDialog(false);\n setFormState(defaultFormState);\n await refetch();\n navigate(`trips/${created.id}`);\n } catch (err) {\n notify.error(\n t('ggnomad.trips.toast.createErrorTitle', 'Could not create trip'),\n err instanceof Error ? err.message : String(err)\n );\n }\n };\n\n const formatDate = (dateStr?: string) => {\n if (!dateStr) return '';\n const date = new Date(dateStr);\n return date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n });\n };\n\n return (\n <PageShell\n title={t('ggnomad.trips.title', 'Trips')}\n titleAccent={t('ggnomad.trips.title.accent', 'Trips')}\n subtitle={t(\n 'ggnomad.trips.subtitle',\n 'Plan complete itineraries with real trip planning API mutations'\n )}\n actions={\n <CTAOverflowMenu\n primary={{\n label: t('ggnomad.trips.actions.newTrip', 'New trip'),\n onSelect: () => setShowNewTripDialog(true),\n disabled: creating,\n icon: <Plus />,\n }}\n actions={[]}\n />\n }\n >\n <PagePurpose icon={<Map className=\"size-4\" />}>\n {t(\n 'ggnomad.trips.purpose',\n 'Organize every aspect of your journey — build itineraries day by day, add activities and accommodations, manage your trip status, and book everything at once. All your trips in one place.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"ggnomad-trips\"\n steps={[\n {\n id: 'add-stays',\n label: t('ggnomad.trips.next.stays', 'Add places to stay'),\n description: t(\n 'ggnomad.trips.next.staysDesc',\n 'Browse accommodations and add them to your itinerary.'\n ),\n icon: <Calendar className=\"size-4\" />,\n onClick: () => navigate('../hospitality'),\n },\n {\n id: 'build-activities',\n label: t('ggnomad.trips.next.activities', 'Plan activities'),\n description: t(\n 'ggnomad.trips.next.activitiesDesc',\n 'Mix in tours, events, and activities by day.'\n ),\n icon: <Map className=\"size-4\" />,\n onClick: () => navigate('../tourism'),\n },\n ]}\n />\n\n {trips.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.trips.emptyTitle', 'No trips yet')}\n description={t(\n 'ggnomad.trips.emptyDescription',\n 'Create your first trip to start building an itinerary.'\n )}\n />\n ) : (\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-5\">\n <h2 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.trips.yourTrips', 'Your trips')}\n </h2>\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {trips.map((trip) => (\n <EntityCard\n key={trip.id}\n to={`trips/${trip.id}`}\n title={trip.name}\n meta={`${trip.travelers} ${\n trip.travelers === 1\n ? t('ggnomad.trips.card.traveler', 'traveler')\n : t('ggnomad.trips.card.travelers', 'travelers')\n } · ${trip.itemCount} ${t('ggnomad.trips.card.items', 'items')}`}\n price={trip.total > 0 ? `USD ${trip.total.toFixed(2)}` : ''}\n badge={<StatusBadge status={trip.status} live={trip.status !== 'CANCELLED'} />}\n footer={\n trip.startDate && trip.endDate\n ? `${formatDate(trip.startDate)} – ${formatDate(trip.endDate)}`\n : t('ggnomad.trips.card.noDates', 'No dates set')\n }\n />\n ))}\n </div>\n </GlassCard>\n )}\n\n <AlertDialog open={showNewTripDialog} onOpenChange={setShowNewTripDialog}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {t('ggnomad.trips.newDialog.title', 'Create a new trip')}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {t(\n 'ggnomad.trips.newDialog.description',\n 'Name your trip and set the dates to get started building your itinerary.'\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n\n <div className=\"space-y-4\">\n <div>\n <label htmlFor=\"trip-name\" className=\"block text-sm font-medium text-text-primary\">\n {t('ggnomad.trips.newDialog.tripName', 'Trip name')}\n </label>\n <input\n id=\"trip-name\"\n type=\"text\"\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-primary focus:outline-none focus:ring-1 focus:ring-primary\"\n placeholder={t(\n 'ggnomad.trips.newDialog.tripNamePlaceholder',\n 'e.g. Summer Europe Adventure'\n )}\n value={formState.name}\n onChange={(e) => setFormState((prev) => ({ ...prev, name: e.target.value }))}\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label\n htmlFor=\"trip-start-date\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n {t('ggnomad.trips.newDialog.startDate', 'Start date')}\n </label>\n <input\n id=\"trip-start-date\"\n type=\"date\"\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-primary focus:outline-none focus:ring-1 focus:ring-primary\"\n value={formState.startDate}\n onChange={(e) => setFormState((prev) => ({ ...prev, startDate: e.target.value }))}\n />\n </div>\n <div>\n <label\n htmlFor=\"trip-end-date\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n {t('ggnomad.trips.newDialog.endDate', 'End date')}\n </label>\n <input\n id=\"trip-end-date\"\n type=\"date\"\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-primary focus:outline-none focus:ring-1 focus:ring-primary\"\n value={formState.endDate}\n onChange={(e) => setFormState((prev) => ({ ...prev, endDate: e.target.value }))}\n />\n </div>\n </div>\n </div>\n\n <AlertDialogFooter>\n <AlertDialogCancel disabled={creating}>\n {t('ggnomad.trips.newDialog.cancel', 'Cancel')}\n </AlertDialogCancel>\n <AlertDialogAction\n disabled={creating || !formState.name.trim()}\n onClick={(event) => {\n event.preventDefault();\n void handleCreateTrip();\n }}\n >\n {creating\n ? t('ggnomad.trips.newDialog.creating', 'Creating…')\n : t('ggnomad.trips.newDialog.create', 'Create trip')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </PageShell>\n );\n}\n"],"mappings":"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"}
|