@burdenoff/microfe-ggnomad 2026.825.1 → 2026.828.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/ggnomad/components/AvailabilityPanel.d.ts +15 -0
  2. package/dist/ggnomad/components/AvailabilityPanel.d.ts.map +1 -0
  3. package/dist/ggnomad/components/AvailabilityPanel.js +91 -0
  4. package/dist/ggnomad/components/AvailabilityPanel.js.map +1 -0
  5. package/dist/ggnomad/components/BookingPanel.d.ts +1 -3
  6. package/dist/ggnomad/components/BookingPanel.d.ts.map +1 -1
  7. package/dist/ggnomad/components/BookingPanel.js +91 -82
  8. package/dist/ggnomad/components/BookingPanel.js.map +1 -1
  9. package/dist/ggnomad/components/EcoAccessPanel.d.ts +17 -0
  10. package/dist/ggnomad/components/EcoAccessPanel.d.ts.map +1 -0
  11. package/dist/ggnomad/components/EcoAccessPanel.js +68 -0
  12. package/dist/ggnomad/components/EcoAccessPanel.js.map +1 -0
  13. package/dist/ggnomad/components/FactGrid.d.ts +18 -0
  14. package/dist/ggnomad/components/FactGrid.d.ts.map +1 -0
  15. package/dist/ggnomad/components/FactGrid.js +29 -0
  16. package/dist/ggnomad/components/FactGrid.js.map +1 -0
  17. package/dist/ggnomad/components/GroupTripPanel.d.ts +22 -0
  18. package/dist/ggnomad/components/GroupTripPanel.d.ts.map +1 -0
  19. package/dist/ggnomad/components/GroupTripPanel.js +350 -0
  20. package/dist/ggnomad/components/GroupTripPanel.js.map +1 -0
  21. package/dist/ggnomad/components/ListingFilters.d.ts +29 -0
  22. package/dist/ggnomad/components/ListingFilters.d.ts.map +1 -0
  23. package/dist/ggnomad/components/ListingFilters.js +164 -0
  24. package/dist/ggnomad/components/ListingFilters.js.map +1 -0
  25. package/dist/ggnomad/components/PhotoGallery.d.ts +15 -0
  26. package/dist/ggnomad/components/PhotoGallery.d.ts.map +1 -0
  27. package/dist/ggnomad/components/PhotoGallery.js +54 -0
  28. package/dist/ggnomad/components/PhotoGallery.js.map +1 -0
  29. package/dist/ggnomad/components/ProviderCard.d.ts +19 -0
  30. package/dist/ggnomad/components/ProviderCard.d.ts.map +1 -0
  31. package/dist/ggnomad/components/ProviderCard.js +66 -0
  32. package/dist/ggnomad/components/ProviderCard.js.map +1 -0
  33. package/dist/ggnomad/components/RatingSummary.d.ts +14 -0
  34. package/dist/ggnomad/components/RatingSummary.d.ts.map +1 -0
  35. package/dist/ggnomad/components/RatingSummary.js +32 -0
  36. package/dist/ggnomad/components/RatingSummary.js.map +1 -0
  37. package/dist/ggnomad/components/TagChips.d.ts +16 -0
  38. package/dist/ggnomad/components/TagChips.d.ts.map +1 -0
  39. package/dist/ggnomad/components/TagChips.js +20 -0
  40. package/dist/ggnomad/components/TagChips.js.map +1 -0
  41. package/dist/ggnomad/components/index.d.ts +13 -0
  42. package/dist/ggnomad/components/index.d.ts.map +1 -1
  43. package/dist/ggnomad/components/index.js +9 -0
  44. package/dist/ggnomad/graphql.d.ts +10 -0
  45. package/dist/ggnomad/graphql.d.ts.map +1 -1
  46. package/dist/ggnomad/graphql.js +308 -20
  47. package/dist/ggnomad/graphql.js.map +1 -1
  48. package/dist/ggnomad/pages/ActivityDetailsPage.d.ts.map +1 -1
  49. package/dist/ggnomad/pages/ActivityDetailsPage.js +174 -86
  50. package/dist/ggnomad/pages/ActivityDetailsPage.js.map +1 -1
  51. package/dist/ggnomad/pages/AnalyticsPage.d.ts.map +1 -1
  52. package/dist/ggnomad/pages/AnalyticsPage.js +109 -77
  53. package/dist/ggnomad/pages/AnalyticsPage.js.map +1 -1
  54. package/dist/ggnomad/pages/BookingsPage.d.ts.map +1 -1
  55. package/dist/ggnomad/pages/BookingsPage.js +188 -137
  56. package/dist/ggnomad/pages/BookingsPage.js.map +1 -1
  57. package/dist/ggnomad/pages/DashboardPage.d.ts.map +1 -1
  58. package/dist/ggnomad/pages/DashboardPage.js +245 -128
  59. package/dist/ggnomad/pages/DashboardPage.js.map +1 -1
  60. package/dist/ggnomad/pages/EntertainmentPage.d.ts.map +1 -1
  61. package/dist/ggnomad/pages/EntertainmentPage.js +115 -53
  62. package/dist/ggnomad/pages/EntertainmentPage.js.map +1 -1
  63. package/dist/ggnomad/pages/EventDetailsPage.d.ts.map +1 -1
  64. package/dist/ggnomad/pages/EventDetailsPage.js +170 -87
  65. package/dist/ggnomad/pages/EventDetailsPage.js.map +1 -1
  66. package/dist/ggnomad/pages/FavoritesPage.d.ts.map +1 -1
  67. package/dist/ggnomad/pages/FavoritesPage.js +201 -84
  68. package/dist/ggnomad/pages/FavoritesPage.js.map +1 -1
  69. package/dist/ggnomad/pages/HospitalityPage.d.ts.map +1 -1
  70. package/dist/ggnomad/pages/HospitalityPage.js +99 -56
  71. package/dist/ggnomad/pages/HospitalityPage.js.map +1 -1
  72. package/dist/ggnomad/pages/PropertyDetailsPage.d.ts.map +1 -1
  73. package/dist/ggnomad/pages/PropertyDetailsPage.js +177 -93
  74. package/dist/ggnomad/pages/PropertyDetailsPage.js.map +1 -1
  75. package/dist/ggnomad/pages/ProviderPage.d.ts.map +1 -1
  76. package/dist/ggnomad/pages/ProviderPage.js +112 -63
  77. package/dist/ggnomad/pages/ProviderPage.js.map +1 -1
  78. package/dist/ggnomad/pages/SearchPage.d.ts.map +1 -1
  79. package/dist/ggnomad/pages/SearchPage.js +236 -65
  80. package/dist/ggnomad/pages/SearchPage.js.map +1 -1
  81. package/dist/ggnomad/pages/TourDetailsPage.d.ts.map +1 -1
  82. package/dist/ggnomad/pages/TourDetailsPage.js +171 -86
  83. package/dist/ggnomad/pages/TourDetailsPage.js.map +1 -1
  84. package/dist/ggnomad/pages/TourismPage.d.ts.map +1 -1
  85. package/dist/ggnomad/pages/TourismPage.js +108 -54
  86. package/dist/ggnomad/pages/TourismPage.js.map +1 -1
  87. package/dist/ggnomad/pages/TravelPage.d.ts.map +1 -1
  88. package/dist/ggnomad/pages/TravelPage.js +406 -43
  89. package/dist/ggnomad/pages/TravelPage.js.map +1 -1
  90. package/dist/ggnomad/pages/TripPlanDetailPage.d.ts.map +1 -1
  91. package/dist/ggnomad/pages/TripPlanDetailPage.js +93 -70
  92. package/dist/ggnomad/pages/TripPlanDetailPage.js.map +1 -1
  93. package/dist/ggnomad/utils/format.d.ts +47 -0
  94. package/dist/ggnomad/utils/format.d.ts.map +1 -0
  95. package/dist/ggnomad/utils/format.js +125 -0
  96. package/dist/ggnomad/utils/format.js.map +1 -0
  97. package/dist/stories/BookingPanel.stories.d.ts.map +1 -1
  98. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ProviderPage.js","names":[],"sources":["../../../src/ggnomad/pages/ProviderPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { Link } from 'react-router';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Briefcase, Store } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_PROVIDERS_QUERY } from '../graphql';\nimport { PageShell } from './PageShell';\nimport { EntityCard, LoadMoreButton, StatusBadge } from '../components';\n\nexport function ProviderPage() {\n const { t } = useI18n();\n const [limit, setLimit] = useState(12);\n const { data } = useQuery(\n GGNOMAD_PROVIDERS_QUERY as TypedDocumentNode<\n {\n ggnomadProviders: Array<{\n id: string;\n name: string;\n type: string;\n status: string;\n listingCount: number;\n totalRevenue: number;\n rating?: number;\n }>;\n },\n { limit: number; offset: number }\n >,\n { variables: { limit, offset: 0 } }\n );\n const providers = data?.ggnomadProviders ?? [];\n\n return (\n <PageShell\n title={t('ggnomad.provider.title', 'Provider Dashboard')}\n titleAccent={t('ggnomad.provider.title.accent', 'Provider')}\n subtitle={t('ggnomad.provider.subtitle', 'B2B provider operations and onboarding metrics')}\n >\n <PagePurpose icon={<Briefcase className=\"size-4\" />}>\n {t(\n 'ggnomad.provider.purpose',\n 'Track the supply side of the marketplace — the hotels, tour operators and venues that publish inventory. Use it to monitor each provider’s status, listing count, revenue and rating, and to spot who needs onboarding attention.'\n )}\n </PagePurpose>\n\n {providers.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title={t('ggnomad.provider.emptyTitle', 'No providers onboarded')}\n description={t(\n 'ggnomad.provider.emptyDescription',\n 'Onboarded B2B providers and their performance will be tracked here.'\n )}\n />\n ) : (\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-5\">\n <h2 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.provider.onboardedProviders', 'Onboarded providers')}\n </h2>\n <div className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {providers.map((provider) => (\n <EntityCard\n key={provider.id}\n title={provider.name}\n meta={provider.type}\n badge={<StatusBadge status={provider.status} live={provider.status === 'ACTIVE'} />}\n footer={\n <dl className=\"grid grid-cols-3 gap-2 text-xs\">\n <div>\n <dt className=\"text-text-secondary\">\n {t('ggnomad.provider.listings', 'Listings')}\n </dt>\n <dd className=\"mt-0.5 font-medium tabular-nums text-text-primary\">\n {provider.listingCount}\n </dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('ggnomad.provider.revenue', 'Revenue')}\n </dt>\n <dd className=\"mt-0.5 font-medium tabular-nums text-text-primary\">\n ${Number(provider.totalRevenue).toLocaleString()}\n </dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('ggnomad.provider.rating', 'Rating')}\n </dt>\n <dd className=\"mt-0.5 font-medium tabular-nums text-text-primary\">\n {provider.rating ?? t('ggnomad.provider.noRating', 'N/A')}\n </dd>\n </div>\n <div className=\"col-span-3 mt-1 border-t border-border-seam pt-2\">\n <Link\n to={`${provider.id}/storefront`}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-action-primary-bg hover:underline\"\n >\n <Store className=\"size-3.5\" />\n {t('ggnomad.provider.manageStorefront', 'Manage storefront')}\n </Link>\n </div>\n </dl>\n }\n />\n ))}\n </div>\n <LoadMoreButton\n visible={providers.length >= limit}\n onLoadMore={() => setLimit((l) => l + 12)}\n />\n </GlassCard>\n )}\n </PageShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAYA,SAAgB,IAAe;CAC7B,IAAM,EAAE,SAAM,EAAQ,GAChB,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,EAAE,YAAS,EACf,GAcA,EAAE,WAAW;EAAE;EAAO,QAAQ;CAAE,EAAE,CACpC,GACM,IAAY,GAAM,oBAAoB,CAAC;CAE7C,OACE,kBAAC,GAAD;EACE,OAAO,EAAE,0BAA0B,oBAAoB;EACvD,aAAa,EAAE,iCAAiC,UAAU;EAC1D,UAAU,EAAE,6BAA6B,gDAAgD;YAH3F,CAKE,kBAAC,GAAD;GAAa,MAAM,kBAAC,GAAD,EAAW,WAAU,SAAU,CAAA;aAC/C,EACC,4BACA,mOACF;EACW,CAAA,GAEZ,EAAU,WAAW,IACpB,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,+BAA+B,wBAAwB;GAChE,aAAa,EACX,qCACA,qEACF;EACD,CAAA,IAED,kBAAC,GAAD;GAAW,WAAU;GAAQ,MAAA;GAAK,WAAU;aAA5C;IACE,kBAAC,MAAD;KAAI,WAAU;eACX,EAAE,uCAAuC,qBAAqB;IAC7D,CAAA;IACJ,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAU,KAAK,MACd,kBAAC,GAAD;MAEE,OAAO,EAAS;MAChB,MAAM,EAAS;MACf,OAAO,kBAAC,GAAD;OAAa,QAAQ,EAAS;OAAQ,MAAM,EAAS,WAAW;MAAW,CAAA;MAClF,QACE,kBAAC,MAAD;OAAI,WAAU;iBAAd;QACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAE,6BAA6B,UAAU;QACxC,CAAA,GACJ,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAS;QACR,CAAA,CACD,EAAA,CAAA;QACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAE,4BAA4B,SAAS;QACtC,CAAA,GACJ,kBAAC,MAAD;SAAI,WAAU;mBAAd,CAAkE,KAC9D,OAAO,EAAS,YAAY,EAAE,eAAe,CAC7C;UACD,EAAA,CAAA;QACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAE,2BAA2B,QAAQ;QACpC,CAAA,GACJ,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAS,UAAU,EAAE,6BAA6B,KAAK;QACtD,CAAA,CACD,EAAA,CAAA;QACL,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD;UACE,IAAI,GAAG,EAAS,GAAG;UACnB,WAAU;oBAFZ,CAIE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,GAC5B,EAAE,qCAAqC,mBAAmB,CACvD;;QACH,CAAA;OACH;;KAEP,GAzCM,EAAS,EAyCf,CACF;IACE,CAAA;IACL,kBAAC,GAAD;KACE,SAAS,EAAU,UAAU;KAC7B,kBAAkB,GAAU,MAAM,IAAI,EAAE;IACzC,CAAA;GACQ;IAEJ;;AAEf"}
1
+ {"version":3,"file":"ProviderPage.js","names":[],"sources":["../../../src/ggnomad/pages/ProviderPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { Link } from 'react-router';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Briefcase, CalendarPlus, Globe, Mail, Phone, Store } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport { GGNOMAD_PROVIDERS_QUERY } from '../graphql';\nimport { formatDate } from '../utils/format';\nimport { PageShell } from './PageShell';\nimport { EntityCard, LoadMoreButton, RatingSummary, StatusBadge } from '../components';\n\nexport function ProviderPage() {\n const { t } = useI18n();\n const [limit, setLimit] = useState(12);\n const { data } = useQuery(\n GGNOMAD_PROVIDERS_QUERY as TypedDocumentNode<\n {\n ggnomadProviders: Array<{\n id: string;\n name: string;\n type: string;\n status: string;\n listingCount: number;\n totalRevenue: number;\n rating?: number | null;\n reviewCount: number;\n description?: string | null;\n contactEmail?: string | null;\n contactPhone?: string | null;\n website?: string | null;\n createdAt: string;\n }>;\n },\n { limit: number; offset: number }\n >,\n { variables: { limit, offset: 0 } }\n );\n const providers = data?.ggnomadProviders ?? [];\n\n return (\n <PageShell\n title={t('ggnomad.provider.title', 'Provider Dashboard')}\n titleAccent={t('ggnomad.provider.title.accent', 'Provider')}\n subtitle={t('ggnomad.provider.subtitle', 'B2B provider operations and onboarding metrics')}\n >\n <PagePurpose icon={<Briefcase className=\"size-4\" />}>\n {t(\n 'ggnomad.provider.purpose',\n 'Track the supply side of the marketplace — the hotels, tour operators and venues that publish inventory. Use it to monitor each provider’s status, listing count, revenue and rating, and to spot who needs onboarding attention.'\n )}\n </PagePurpose>\n\n {providers.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title={t('ggnomad.provider.emptyTitle', 'No providers onboarded')}\n description={t(\n 'ggnomad.provider.emptyDescription',\n 'Onboarded B2B providers and their performance will be tracked here.'\n )}\n />\n ) : (\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-5\">\n <h2 className=\"mb-4 text-lg font-medium tracking-tight text-text-primary\">\n {t('ggnomad.provider.onboardedProviders', 'Onboarded providers')}\n </h2>\n <div className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {providers.map((provider) => (\n <EntityCard\n key={provider.id}\n title={provider.name}\n meta={provider.description ?? provider.type}\n badge={<StatusBadge status={provider.status} live={provider.status === 'ACTIVE'} />}\n footer={\n <div className=\"space-y-2 text-xs\">\n <RatingSummary rating={provider.rating} reviewCount={provider.reviewCount} />\n <dl className=\"grid grid-cols-3 gap-2\">\n <div>\n <dt className=\"text-text-secondary\">\n {t('ggnomad.provider.listings', 'Listings')}\n </dt>\n <dd className=\"mt-0.5 font-medium tabular-nums text-text-primary\">\n {provider.listingCount}\n </dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('ggnomad.provider.revenue', 'Revenue')}\n </dt>\n <dd className=\"mt-0.5 font-medium tabular-nums text-text-primary\">\n ${Number(provider.totalRevenue).toLocaleString()}\n </dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {t('ggnomad.provider.type', 'Type')}\n </dt>\n <dd className=\"mt-0.5 font-medium text-text-primary\">{provider.type}</dd>\n </div>\n </dl>\n <p className=\"inline-flex items-center gap-1 text-text-secondary\">\n <CalendarPlus className=\"size-3.5\" aria-hidden=\"true\" />\n {t('ggnomad.provider.joined', 'Joined {{date}}').replace(\n '{{date}}',\n formatDate(provider.createdAt) ?? '—'\n )}\n </p>\n {provider.contactEmail || provider.contactPhone || provider.website ? (\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1\">\n {provider.contactEmail ? (\n <a\n href={`mailto:${provider.contactEmail}`}\n className=\"inline-flex items-center gap-1 text-action-primary-bg hover:underline\"\n >\n <Mail className=\"size-3.5\" aria-hidden=\"true\" />\n {provider.contactEmail}\n </a>\n ) : null}\n {provider.contactPhone ? (\n <a\n href={`tel:${provider.contactPhone}`}\n className=\"inline-flex items-center gap-1 text-action-primary-bg hover:underline\"\n >\n <Phone className=\"size-3.5\" aria-hidden=\"true\" />\n {provider.contactPhone}\n </a>\n ) : null}\n {provider.website ? (\n <a\n href={provider.website}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n className=\"inline-flex items-center gap-1 text-action-primary-bg hover:underline\"\n >\n <Globe className=\"size-3.5\" aria-hidden=\"true\" />\n {t('ggnomad.provider.website', 'Website')}\n </a>\n ) : null}\n </div>\n ) : null}\n <div className=\"mt-1 border-t border-border-seam pt-2\">\n <Link\n to={`${provider.id}/storefront`}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-action-primary-bg hover:underline\"\n >\n <Store className=\"size-3.5\" />\n {t('ggnomad.provider.manageStorefront', 'Manage storefront')}\n </Link>\n </div>\n </div>\n }\n />\n ))}\n </div>\n <LoadMoreButton\n visible={providers.length >= limit}\n onLoadMore={() => setLimit((l) => l + 12)}\n />\n </GlassCard>\n )}\n </PageShell>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SearchPage.d.ts","sourceRoot":"","sources":["../../../src/ggnomad/pages/SearchPage.tsx"],"names":[],"mappings":"AAeA,wBAAgB,UAAU,gCA0GzB"}
1
+ {"version":3,"file":"SearchPage.d.ts","sourceRoot":"","sources":["../../../src/ggnomad/pages/SearchPage.tsx"],"names":[],"mappings":"AA8EA,wBAAgB,UAAU,gCA+RzB"}
@@ -1,79 +1,250 @@
1
1
  import { GGNOMAD_ACTIVITIES_QUERY as e, GGNOMAD_EVENTS_QUERY as t, GGNOMAD_PROPERTIES_QUERY as n, GGNOMAD_TOURS_QUERY as r } from "../graphql.js";
2
- import { PageShell as i } from "./PageShell.js";
3
- import { StatCard as a } from "../components/StatCard.js";
2
+ import { humanizeEnum as i } from "../utils/format.js";
3
+ import { PageShell as a } from "./PageShell.js";
4
+ import { StatCard as o } from "../components/StatCard.js";
5
+ import { cn as s } from "../utils/cn.js";
6
+ import { SectionCard as c } from "../components/SectionCard.js";
7
+ import { EntityCard as l } from "../components/EntityCard.js";
8
+ import { LoadMoreButton as u } from "../components/LoadMoreButton.js";
9
+ import { RatingSummary as d } from "../components/RatingSummary.js";
4
10
  import "../components/index.js";
5
- import { Activity as o, Building as s, Compass as c, Search as l, Ticket as u } from "lucide-react";
6
- import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
7
- import { useQuery as f } from "@apollo/client/react";
8
- import { EmphasisPanel as p, IllustratedEmptyState as m, PagePurpose as h } from "@burdenoff/fe-libs/ui";
9
- import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
11
+ import { useMemo as f, useState as p } from "react";
12
+ import { Activity as m, Building as h, Compass as g, Search as _, Ticket as v, X as y } from "lucide-react";
13
+ import { useI18n as b } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
14
+ import { useQuery as x } from "@apollo/client/react";
15
+ import { EmphasisPanel as S, IllustratedEmptyState as C, PagePurpose as w } from "@burdenoff/fe-libs/ui";
16
+ import { jsx as T, jsxs as E } from "react/jsx-runtime";
10
17
  //#region src/ggnomad/pages/SearchPage.tsx
11
- function y() {
12
- let { t: y } = d(), b = f(n, { variables: {
13
- limit: 5,
14
- offset: 0
15
- } }), x = f(r, { variables: {
16
- limit: 5,
17
- offset: 0
18
- } }), S = f(t, { variables: {
19
- limit: 5,
20
- offset: 0
21
- } }), C = f(e, { variables: {
22
- limit: 5,
18
+ var D = 24, O = {
19
+ PROPERTY: "../hospitality",
20
+ TOUR: "../tourism/tours",
21
+ EVENT: "../entertainment",
22
+ ACTIVITY: "../tourism/activities"
23
+ };
24
+ function k(e, t) {
25
+ return {
26
+ key: `${e}-${t.id}`,
27
+ domain: e,
28
+ id: t.id,
29
+ name: t.name,
30
+ kind: t.kind,
31
+ price: t.price,
32
+ currency: t.currency,
33
+ rating: t.rating,
34
+ reviewCount: t.reviewCount,
35
+ image: t.images?.[0],
36
+ haystack: [
37
+ t.name,
38
+ t.kind,
39
+ t.description ?? ""
40
+ ].join(" ").toLowerCase(),
41
+ path: `${O[e]}/${t.id}`
42
+ };
43
+ }
44
+ function A() {
45
+ let { t: O } = b(), [A, j] = p(""), [M, N] = p("ALL"), [P, F] = p(D), I = {
46
+ limit: P,
23
47
  offset: 0
24
- } }), w = b.data?.ggnomadProperties?.length ?? 0, T = x.data?.ggnomadTours?.length ?? 0, E = S.data?.ggnomadEvents?.length ?? 0, D = C.data?.ggnomadActivities?.length ?? 0, O = w + T + E + D;
25
- return /* @__PURE__ */ v(i, {
26
- title: y("ggnomad.search.title", "Global Search"),
27
- titleAccent: y("ggnomad.search.title.accent", "Search"),
28
- subtitle: y("ggnomad.search.subtitle", "Cross-domain search across all GGNomad inventory"),
29
- children: [/* @__PURE__ */ _(h, {
30
- icon: /* @__PURE__ */ _(l, { className: "size-4" }),
31
- children: y("ggnomad.search.purpose", "One search across the entire GGNomad catalogue — properties, tours, events and activities at once — so you can see everything available for a destination in a single view instead of checking each domain separately.")
32
- }), O === 0 ? /* @__PURE__ */ _(m, {
33
- illustration: "empty-search",
34
- title: y("ggnomad.search.emptyTitle", "No matching inventory"),
35
- description: y("ggnomad.search.emptyDescription", "Nothing matched across properties, tours, events and activities yet.")
36
- }) : /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ v(p, { children: [
37
- /* @__PURE__ */ _("p", {
38
- className: "text-sm text-text-secondary",
39
- children: y("ggnomad.search.totalMatches", "Total matches across all domains")
40
- }),
41
- /* @__PURE__ */ _("p", {
42
- className: "mt-1 text-3xl font-semibold tabular-nums text-text-primary",
43
- children: O.toLocaleString()
48
+ }, L = x(n, { variables: I }), R = x(r, { variables: I }), z = x(t, { variables: I }), B = x(e, { variables: I }), V = L.loading || R.loading || z.loading || B.loading, H = f(() => {
49
+ let e = [];
50
+ for (let t of L.data?.ggnomadProperties ?? []) e.push(k("PROPERTY", {
51
+ ...t,
52
+ price: t.pricePerNight,
53
+ kind: t.type
54
+ }));
55
+ for (let t of R.data?.ggnomadTours ?? []) e.push(k("TOUR", {
56
+ ...t,
57
+ kind: t.type
58
+ }));
59
+ for (let t of z.data?.ggnomadEvents ?? []) e.push(k("EVENT", {
60
+ ...t,
61
+ kind: t.category
62
+ }));
63
+ for (let t of B.data?.ggnomadActivities ?? []) e.push(k("ACTIVITY", {
64
+ ...t,
65
+ kind: t.category
66
+ }));
67
+ return e;
68
+ }, [
69
+ L.data?.ggnomadProperties,
70
+ R.data?.ggnomadTours,
71
+ z.data?.ggnomadEvents,
72
+ B.data?.ggnomadActivities
73
+ ]), U = f(() => {
74
+ let e = A.trim().toLowerCase();
75
+ return H.filter((t) => M !== "ALL" && t.domain !== M ? !1 : e ? t.haystack.includes(e) : !0);
76
+ }, [
77
+ H,
78
+ A,
79
+ M
80
+ ]), W = (e) => H.filter((t) => t.domain === e && (!A.trim() || t.haystack.includes(A.trim().toLowerCase()))).length, G = W("PROPERTY"), K = W("TOUR"), q = W("EVENT"), J = W("ACTIVITY"), Y = G + K + q + J, X = [
81
+ L.data?.ggnomadProperties,
82
+ R.data?.ggnomadTours,
83
+ z.data?.ggnomadEvents,
84
+ B.data?.ggnomadActivities
85
+ ].some((e) => (e?.length ?? 0) >= P), Z = (e) => {
86
+ switch (e) {
87
+ case "PROPERTY": return O("ggnomad.search.domain.property", "Property");
88
+ case "TOUR": return O("ggnomad.search.domain.tour", "Tour");
89
+ case "EVENT": return O("ggnomad.search.domain.event", "Event");
90
+ case "ACTIVITY": return O("ggnomad.search.domain.activity", "Activity");
91
+ }
92
+ }, Q = [
93
+ {
94
+ value: "ALL",
95
+ label: O("ggnomad.search.domain.all", "All"),
96
+ count: Y
97
+ },
98
+ {
99
+ value: "PROPERTY",
100
+ label: O("ggnomad.search.results.properties", "Properties"),
101
+ count: G
102
+ },
103
+ {
104
+ value: "TOUR",
105
+ label: O("ggnomad.search.results.tours", "Tours"),
106
+ count: K
107
+ },
108
+ {
109
+ value: "EVENT",
110
+ label: O("ggnomad.search.results.events", "Events"),
111
+ count: q
112
+ },
113
+ {
114
+ value: "ACTIVITY",
115
+ label: O("ggnomad.search.results.activities", "Activities"),
116
+ count: J
117
+ }
118
+ ];
119
+ return /* @__PURE__ */ E(a, {
120
+ title: O("ggnomad.search.title", "Global Search"),
121
+ titleAccent: O("ggnomad.search.title.accent", "Search"),
122
+ subtitle: O("ggnomad.search.subtitle", "Cross-domain search across all GGNomad inventory"),
123
+ children: [
124
+ /* @__PURE__ */ T(w, {
125
+ icon: /* @__PURE__ */ T(_, { className: "size-4" }),
126
+ children: O("ggnomad.search.purpose", "One search across the entire GGNomad catalogue — properties, tours, events and activities at once — so you can see everything available for a destination in a single view instead of checking each domain separately.")
44
127
  }),
45
- /* @__PURE__ */ _("p", {
46
- className: "mt-2 text-sm text-text-secondary",
47
- children: y("ggnomad.search.totalMatchesNote", "Combined inventory from properties, tours, events and activities — open a domain below to drill in.")
48
- })
49
- ] }), /* @__PURE__ */ v("section", {
50
- className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4",
51
- children: [
52
- /* @__PURE__ */ _(a, {
53
- label: y("ggnomad.search.results.propertiesFound", "Properties found"),
54
- value: w,
55
- icon: /* @__PURE__ */ _(s, {})
128
+ /* @__PURE__ */ E("div", { children: [
129
+ /* @__PURE__ */ T("label", {
130
+ htmlFor: "ggnomad-search-term",
131
+ className: "sr-only",
132
+ children: O("ggnomad.search.inputLabel", "Search the catalogue")
56
133
  }),
57
- /* @__PURE__ */ _(a, {
58
- label: y("ggnomad.search.results.toursFound", "Tours found"),
59
- value: T,
60
- icon: /* @__PURE__ */ _(c, {})
134
+ /* @__PURE__ */ E("div", {
135
+ className: "relative",
136
+ children: [
137
+ /* @__PURE__ */ T(_, {
138
+ className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-text-secondary",
139
+ "aria-hidden": "true"
140
+ }),
141
+ /* @__PURE__ */ T("input", {
142
+ id: "ggnomad-search-term",
143
+ type: "search",
144
+ value: A,
145
+ onChange: (e) => j(e.target.value),
146
+ placeholder: O("ggnomad.search.placeholder", "Search names, categories and descriptions…"),
147
+ className: "w-full rounded-lg border border-border-seam bg-bg-canvas py-2.5 pl-9 pr-10 text-sm text-text-primary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg"
148
+ }),
149
+ A ? /* @__PURE__ */ T("button", {
150
+ type: "button",
151
+ onClick: () => j(""),
152
+ "aria-label": O("ggnomad.search.clear", "Clear search"),
153
+ className: "absolute right-2 top-1/2 -translate-y-1/2 rounded-md p-1.5 text-text-secondary hover:bg-bg-sunken hover:text-text-primary",
154
+ children: /* @__PURE__ */ T(y, { className: "size-4" })
155
+ }) : null
156
+ ]
61
157
  }),
62
- /* @__PURE__ */ _(a, {
63
- label: y("ggnomad.search.results.eventsFound", "Events found"),
64
- value: E,
65
- icon: /* @__PURE__ */ _(u, {})
158
+ /* @__PURE__ */ T("p", {
159
+ className: "mt-2 text-xs text-text-secondary",
160
+ children: O("ggnomad.search.scopeNote", "Matches against the catalogue loaded on this page. Use “Load more” to pull further inventory into the search.")
161
+ })
162
+ ] }),
163
+ /* @__PURE__ */ T("ul", {
164
+ className: "flex flex-wrap gap-2",
165
+ children: Q.map((e) => /* @__PURE__ */ T("li", { children: /* @__PURE__ */ E("button", {
166
+ type: "button",
167
+ "aria-pressed": M === e.value,
168
+ onClick: () => N(e.value),
169
+ className: s("rounded-full border px-3 py-1 text-sm transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-action-primary-bg", M === e.value ? "border-action-primary-bg bg-action-primary-bg text-action-primary-text" : "border-border-seam bg-bg-sunken text-text-primary hover:border-border-default"),
170
+ children: [e.label, /* @__PURE__ */ T("span", {
171
+ className: "ml-1.5 tabular-nums opacity-80",
172
+ children: e.count
173
+ })]
174
+ }) }, e.value))
175
+ }),
176
+ /* @__PURE__ */ E(S, { children: [
177
+ /* @__PURE__ */ T("p", {
178
+ className: "text-sm text-text-secondary",
179
+ children: O("ggnomad.search.totalMatches", "Total matches across all domains")
180
+ }),
181
+ /* @__PURE__ */ T("p", {
182
+ className: "mt-1 text-3xl font-semibold tabular-nums text-text-primary",
183
+ children: Y.toLocaleString()
66
184
  }),
67
- /* @__PURE__ */ _(a, {
68
- label: y("ggnomad.search.results.activitiesFound", "Activities found"),
69
- value: D,
70
- icon: /* @__PURE__ */ _(o, {})
185
+ /* @__PURE__ */ T("p", {
186
+ className: "mt-2 text-sm text-text-secondary",
187
+ children: O("ggnomad.search.totalMatchesNote", "Combined inventory from properties, tours, events and activities — open a domain below to drill in.")
71
188
  })
72
- ]
73
- })] })]
189
+ ] }),
190
+ /* @__PURE__ */ E("section", {
191
+ className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-4",
192
+ children: [
193
+ /* @__PURE__ */ T(o, {
194
+ label: O("ggnomad.search.results.propertiesFound", "Properties found"),
195
+ value: G,
196
+ icon: /* @__PURE__ */ T(h, {})
197
+ }),
198
+ /* @__PURE__ */ T(o, {
199
+ label: O("ggnomad.search.results.toursFound", "Tours found"),
200
+ value: K,
201
+ icon: /* @__PURE__ */ T(g, {})
202
+ }),
203
+ /* @__PURE__ */ T(o, {
204
+ label: O("ggnomad.search.results.eventsFound", "Events found"),
205
+ value: q,
206
+ icon: /* @__PURE__ */ T(v, {})
207
+ }),
208
+ /* @__PURE__ */ T(o, {
209
+ label: O("ggnomad.search.results.activitiesFound", "Activities found"),
210
+ value: J,
211
+ icon: /* @__PURE__ */ T(m, {})
212
+ })
213
+ ]
214
+ }),
215
+ U.length === 0 ? /* @__PURE__ */ T(C, {
216
+ illustration: "empty-search",
217
+ title: V ? O("ggnomad.search.loadingTitle", "Searching the catalogue…") : O("ggnomad.search.emptyTitle", "No matching inventory"),
218
+ description: V ? O("ggnomad.search.loadingDescription", "Fetching properties, tours, events and activities.") : A.trim() ? O("ggnomad.search.noTermMatch", "Nothing matched “{{term}}”. Try a shorter term or another domain.").replace("{{term}}", A.trim()) : O("ggnomad.search.emptyDescription", "Nothing matched across properties, tours, events and activities yet.")
219
+ }) : /* @__PURE__ */ E(c, {
220
+ title: O("ggnomad.search.resultsTitle", "Results"),
221
+ children: [/* @__PURE__ */ T("div", {
222
+ className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-3",
223
+ children: U.map((e) => /* @__PURE__ */ T(l, {
224
+ to: e.path,
225
+ image: e.image,
226
+ imageAlt: e.name,
227
+ title: e.name,
228
+ meta: i(e.kind),
229
+ badge: /* @__PURE__ */ T("span", {
230
+ className: "rounded-full bg-bg-surface/90 px-2.5 py-0.5 text-xs font-medium text-text-primary",
231
+ children: Z(e.domain)
232
+ }),
233
+ price: `${e.currency} ${Number(e.price).toFixed(2)}`,
234
+ footer: /* @__PURE__ */ T(d, {
235
+ rating: e.rating,
236
+ reviewCount: e.reviewCount
237
+ })
238
+ }, e.key))
239
+ }), /* @__PURE__ */ T(u, {
240
+ visible: X,
241
+ onLoadMore: () => F((e) => e + D)
242
+ })]
243
+ })
244
+ ]
74
245
  });
75
246
  }
76
247
  //#endregion
77
- export { y as SearchPage };
248
+ export { A as SearchPage };
78
249
 
79
250
  //# sourceMappingURL=SearchPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SearchPage.js","names":[],"sources":["../../../src/ggnomad/pages/SearchPage.tsx"],"sourcesContent":["import { useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Activity, Building, Compass, Search, Ticket } from 'lucide-react';\nimport { EmphasisPanel, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport {\n GGNOMAD_PROPERTIES_QUERY,\n GGNOMAD_TOURS_QUERY,\n GGNOMAD_EVENTS_QUERY,\n GGNOMAD_ACTIVITIES_QUERY,\n} from '../graphql';\nimport { PageShell } from './PageShell';\nimport { StatCard } from '../components';\n\nexport function SearchPage() {\n const { t } = useI18n();\n const properties = useQuery(\n GGNOMAD_PROPERTIES_QUERY as TypedDocumentNode<\n { ggnomadProperties: Array<{ id: string }> },\n { limit: number; offset: number }\n >,\n { variables: { limit: 5, offset: 0 } }\n );\n const tours = useQuery(\n GGNOMAD_TOURS_QUERY as TypedDocumentNode<\n { ggnomadTours: Array<{ id: string }> },\n { limit: number; offset: number }\n >,\n {\n variables: { limit: 5, offset: 0 },\n }\n );\n const events = useQuery(\n GGNOMAD_EVENTS_QUERY as TypedDocumentNode<\n { ggnomadEvents: Array<{ id: string }> },\n { limit: number; offset: number }\n >,\n {\n variables: { limit: 5, offset: 0 },\n }\n );\n const activities = useQuery(\n GGNOMAD_ACTIVITIES_QUERY as TypedDocumentNode<\n { ggnomadActivities: Array<{ id: string }> },\n { limit: number; offset: number }\n >,\n { variables: { limit: 5, offset: 0 } }\n );\n\n const propertyCount = properties.data?.ggnomadProperties?.length ?? 0;\n const tourCount = tours.data?.ggnomadTours?.length ?? 0;\n const eventCount = events.data?.ggnomadEvents?.length ?? 0;\n const activityCount = activities.data?.ggnomadActivities?.length ?? 0;\n const total = propertyCount + tourCount + eventCount + activityCount;\n\n return (\n <PageShell\n title={t('ggnomad.search.title', 'Global Search')}\n titleAccent={t('ggnomad.search.title.accent', 'Search')}\n subtitle={t('ggnomad.search.subtitle', 'Cross-domain search across all GGNomad inventory')}\n >\n <PagePurpose icon={<Search className=\"size-4\" />}>\n {t(\n 'ggnomad.search.purpose',\n 'One search across the entire GGNomad catalogue — properties, tours, events and activities at once — so you can see everything available for a destination in a single view instead of checking each domain separately.'\n )}\n </PagePurpose>\n\n {total === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={t('ggnomad.search.emptyTitle', 'No matching inventory')}\n description={t(\n 'ggnomad.search.emptyDescription',\n 'Nothing matched across properties, tours, events and activities yet.'\n )}\n />\n ) : (\n <>\n <EmphasisPanel>\n <p className=\"text-sm text-text-secondary\">\n {t('ggnomad.search.totalMatches', 'Total matches across all domains')}\n </p>\n <p className=\"mt-1 text-3xl font-semibold tabular-nums text-text-primary\">\n {total.toLocaleString()}\n </p>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {t(\n 'ggnomad.search.totalMatchesNote',\n 'Combined inventory from properties, tours, events and activities — open a domain below to drill in.'\n )}\n </p>\n </EmphasisPanel>\n\n <section className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n <StatCard\n label={t('ggnomad.search.results.propertiesFound', 'Properties found')}\n value={propertyCount}\n icon={<Building />}\n />\n <StatCard\n label={t('ggnomad.search.results.toursFound', 'Tours found')}\n value={tourCount}\n icon={<Compass />}\n />\n <StatCard\n label={t('ggnomad.search.results.eventsFound', 'Events found')}\n value={eventCount}\n icon={<Ticket />}\n />\n <StatCard\n label={t('ggnomad.search.results.activitiesFound', 'Activities found')}\n value={activityCount}\n icon={<Activity />}\n />\n </section>\n </>\n )}\n </PageShell>\n );\n}\n"],"mappings":";;;;;;;;;;AAeA,SAAgB,IAAa;CAC3B,IAAM,EAAE,SAAM,EAAQ,GAChB,IAAa,EACjB,GAIA,EAAE,WAAW;EAAE,OAAO;EAAG,QAAQ;CAAE,EAAE,CACvC,GACM,IAAQ,EACZ,GAIA,EACE,WAAW;EAAE,OAAO;EAAG,QAAQ;CAAE,EACnC,CACF,GACM,IAAS,EACb,GAIA,EACE,WAAW;EAAE,OAAO;EAAG,QAAQ;CAAE,EACnC,CACF,GACM,IAAa,EACjB,GAIA,EAAE,WAAW;EAAE,OAAO;EAAG,QAAQ;CAAE,EAAE,CACvC,GAEM,IAAgB,EAAW,MAAM,mBAAmB,UAAU,GAC9D,IAAY,EAAM,MAAM,cAAc,UAAU,GAChD,IAAa,EAAO,MAAM,eAAe,UAAU,GACnD,IAAgB,EAAW,MAAM,mBAAmB,UAAU,GAC9D,IAAQ,IAAgB,IAAY,IAAa;CAEvD,OACE,kBAAC,GAAD;EACE,OAAO,EAAE,wBAAwB,eAAe;EAChD,aAAa,EAAE,+BAA+B,QAAQ;EACtD,UAAU,EAAE,2BAA2B,kDAAkD;YAH3F,CAKE,kBAAC,GAAD;GAAa,MAAM,kBAAC,GAAD,EAAQ,WAAU,SAAU,CAAA;aAC5C,EACC,0BACA,wNACF;EACW,CAAA,GAEZ,MAAU,IACT,kBAAC,GAAD;GACE,cAAa;GACb,OAAO,EAAE,6BAA6B,uBAAuB;GAC7D,aAAa,EACX,mCACA,sEACF;EACD,CAAA,IAED,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA;GACE,kBAAC,KAAD;IAAG,WAAU;cACV,EAAE,+BAA+B,kCAAkC;GACnE,CAAA;GACH,kBAAC,KAAD;IAAG,WAAU;cACV,EAAM,eAAe;GACrB,CAAA;GACH,kBAAC,KAAD;IAAG,WAAU;cACV,EACC,mCACA,qGACF;GACC,CAAA;EACU,EAAA,CAAA,GAEf,kBAAC,WAAD;GAAS,WAAU;aAAnB;IACE,kBAAC,GAAD;KACE,OAAO,EAAE,0CAA0C,kBAAkB;KACrE,OAAO;KACP,MAAM,kBAAC,GAAD,CAAW,CAAA;IAClB,CAAA;IACD,kBAAC,GAAD;KACE,OAAO,EAAE,qCAAqC,aAAa;KAC3D,OAAO;KACP,MAAM,kBAAC,GAAD,CAAU,CAAA;IACjB,CAAA;IACD,kBAAC,GAAD;KACE,OAAO,EAAE,sCAAsC,cAAc;KAC7D,OAAO;KACP,MAAM,kBAAC,GAAD,CAAS,CAAA;IAChB,CAAA;IACD,kBAAC,GAAD;KACE,OAAO,EAAE,0CAA0C,kBAAkB;KACrE,OAAO;KACP,MAAM,kBAAC,GAAD,CAAW,CAAA;IAClB,CAAA;GACM;IACT,EAAA,CAAA,CAEK;;AAEf"}
1
+ {"version":3,"file":"SearchPage.js","names":[],"sources":["../../../src/ggnomad/pages/SearchPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Activity, Building, Compass, Search, Ticket, X } from 'lucide-react';\nimport { EmphasisPanel, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\n\nimport {\n GGNOMAD_PROPERTIES_QUERY,\n GGNOMAD_TOURS_QUERY,\n GGNOMAD_EVENTS_QUERY,\n GGNOMAD_ACTIVITIES_QUERY,\n} from '../graphql';\nimport { humanizeEnum } from '../utils/format';\nimport { cn } from '../utils/cn';\nimport { PageShell } from './PageShell';\nimport { EntityCard, LoadMoreButton, RatingSummary, SectionCard, StatCard } from '../components';\n\ntype Domain = 'PROPERTY' | 'TOUR' | 'EVENT' | 'ACTIVITY';\n\ntype CatalogueRow = {\n id: string;\n name: string;\n description?: string | null;\n currency: string;\n rating?: number | null;\n reviewCount: number;\n images?: string[];\n};\n\ntype PropertyRow = CatalogueRow & { type: string; pricePerNight: number };\ntype TourRow = CatalogueRow & { type: string; price: number; duration: string };\ntype EventRow = CatalogueRow & { category: string; price: number };\ntype ActivityRow = CatalogueRow & { category: string; price: number; duration: string };\n\ntype Result = {\n key: string;\n domain: Domain;\n id: string;\n name: string;\n /** The listing's own category / type label, used both for display and matching. */\n kind: string;\n price: number;\n currency: string;\n rating?: number | null;\n reviewCount: number;\n image?: string;\n haystack: string;\n /** Route relative to the GGNomad base path. */\n path: string;\n};\n\nconst PAGE_SIZE = 24;\n\nconst DOMAIN_ROUTE: Record<Domain, string> = {\n PROPERTY: '../hospitality',\n TOUR: '../tourism/tours',\n EVENT: '../entertainment',\n ACTIVITY: '../tourism/activities',\n};\n\nfunction toResult(domain: Domain, row: CatalogueRow & { price: number; kind: string }): Result {\n return {\n key: `${domain}-${row.id}`,\n domain,\n id: row.id,\n name: row.name,\n kind: row.kind,\n price: row.price,\n currency: row.currency,\n rating: row.rating,\n reviewCount: row.reviewCount,\n image: row.images?.[0],\n haystack: [row.name, row.kind, row.description ?? ''].join(' ').toLowerCase(),\n path: `${DOMAIN_ROUTE[domain]}/${row.id}`,\n };\n}\n\nexport function SearchPage() {\n const { t } = useI18n();\n const [term, setTerm] = useState('');\n const [domain, setDomain] = useState<Domain | 'ALL'>('ALL');\n const [limit, setLimit] = useState(PAGE_SIZE);\n\n const variables = { limit, offset: 0 };\n const properties = useQuery(\n GGNOMAD_PROPERTIES_QUERY as TypedDocumentNode<\n { ggnomadProperties: PropertyRow[] },\n { limit: number; offset: number }\n >,\n { variables }\n );\n const tours = useQuery(\n GGNOMAD_TOURS_QUERY as TypedDocumentNode<\n { ggnomadTours: TourRow[] },\n { limit: number; offset: number }\n >,\n { variables }\n );\n const events = useQuery(\n GGNOMAD_EVENTS_QUERY as TypedDocumentNode<\n { ggnomadEvents: EventRow[] },\n { limit: number; offset: number }\n >,\n { variables }\n );\n const activities = useQuery(\n GGNOMAD_ACTIVITIES_QUERY as TypedDocumentNode<\n { ggnomadActivities: ActivityRow[] },\n { limit: number; offset: number }\n >,\n { variables }\n );\n\n const loading = properties.loading || tours.loading || events.loading || activities.loading;\n\n const allResults = useMemo<Result[]>(() => {\n const rows: Result[] = [];\n for (const property of properties.data?.ggnomadProperties ?? []) {\n rows.push(\n toResult('PROPERTY', { ...property, price: property.pricePerNight, kind: property.type })\n );\n }\n for (const tour of tours.data?.ggnomadTours ?? []) {\n rows.push(toResult('TOUR', { ...tour, kind: tour.type }));\n }\n for (const event of events.data?.ggnomadEvents ?? []) {\n rows.push(toResult('EVENT', { ...event, kind: event.category }));\n }\n for (const activity of activities.data?.ggnomadActivities ?? []) {\n rows.push(toResult('ACTIVITY', { ...activity, kind: activity.category }));\n }\n return rows;\n }, [\n properties.data?.ggnomadProperties,\n tours.data?.ggnomadTours,\n events.data?.ggnomadEvents,\n activities.data?.ggnomadActivities,\n ]);\n\n const matches = useMemo(() => {\n const needle = term.trim().toLowerCase();\n return allResults.filter((result) => {\n if (domain !== 'ALL' && result.domain !== domain) return false;\n if (!needle) return true;\n return result.haystack.includes(needle);\n });\n }, [allResults, term, domain]);\n\n const countFor = (target: Domain) =>\n allResults.filter(\n (result) =>\n result.domain === target &&\n (!term.trim() || result.haystack.includes(term.trim().toLowerCase()))\n ).length;\n\n const propertyCount = countFor('PROPERTY');\n const tourCount = countFor('TOUR');\n const eventCount = countFor('EVENT');\n const activityCount = countFor('ACTIVITY');\n const total = propertyCount + tourCount + eventCount + activityCount;\n\n // Every domain query asks for the same page size, so any list that came back\n // full may have more behind it.\n const mayHaveMore = [\n properties.data?.ggnomadProperties,\n tours.data?.ggnomadTours,\n events.data?.ggnomadEvents,\n activities.data?.ggnomadActivities,\n ].some((rows) => (rows?.length ?? 0) >= limit);\n\n const domainLabel = (value: Domain): string => {\n switch (value) {\n case 'PROPERTY':\n return t('ggnomad.search.domain.property', 'Property');\n case 'TOUR':\n return t('ggnomad.search.domain.tour', 'Tour');\n case 'EVENT':\n return t('ggnomad.search.domain.event', 'Event');\n case 'ACTIVITY':\n return t('ggnomad.search.domain.activity', 'Activity');\n }\n };\n\n const domainChips: Array<{ value: Domain | 'ALL'; label: string; count: number }> = [\n { value: 'ALL', label: t('ggnomad.search.domain.all', 'All'), count: total },\n {\n value: 'PROPERTY',\n label: t('ggnomad.search.results.properties', 'Properties'),\n count: propertyCount,\n },\n { value: 'TOUR', label: t('ggnomad.search.results.tours', 'Tours'), count: tourCount },\n { value: 'EVENT', label: t('ggnomad.search.results.events', 'Events'), count: eventCount },\n {\n value: 'ACTIVITY',\n label: t('ggnomad.search.results.activities', 'Activities'),\n count: activityCount,\n },\n ];\n\n return (\n <PageShell\n title={t('ggnomad.search.title', 'Global Search')}\n titleAccent={t('ggnomad.search.title.accent', 'Search')}\n subtitle={t('ggnomad.search.subtitle', 'Cross-domain search across all GGNomad inventory')}\n >\n <PagePurpose icon={<Search className=\"size-4\" />}>\n {t(\n 'ggnomad.search.purpose',\n 'One search across the entire GGNomad catalogue — properties, tours, events and activities at once — so you can see everything available for a destination in a single view instead of checking each domain separately.'\n )}\n </PagePurpose>\n\n <div>\n <label htmlFor=\"ggnomad-search-term\" className=\"sr-only\">\n {t('ggnomad.search.inputLabel', 'Search the catalogue')}\n </label>\n <div className=\"relative\">\n <Search\n className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-text-secondary\"\n aria-hidden=\"true\"\n />\n <input\n id=\"ggnomad-search-term\"\n type=\"search\"\n value={term}\n onChange={(event) => setTerm(event.target.value)}\n placeholder={t(\n 'ggnomad.search.placeholder',\n 'Search names, categories and descriptions…'\n )}\n className=\"w-full rounded-lg border border-border-seam bg-bg-canvas py-2.5 pl-9 pr-10 text-sm text-text-primary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg\"\n />\n {term ? (\n <button\n type=\"button\"\n onClick={() => setTerm('')}\n aria-label={t('ggnomad.search.clear', 'Clear search')}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 rounded-md p-1.5 text-text-secondary hover:bg-bg-sunken hover:text-text-primary\"\n >\n <X className=\"size-4\" />\n </button>\n ) : null}\n </div>\n <p className=\"mt-2 text-xs text-text-secondary\">\n {t(\n 'ggnomad.search.scopeNote',\n 'Matches against the catalogue loaded on this page. Use “Load more” to pull further inventory into the search.'\n )}\n </p>\n </div>\n\n <ul className=\"flex flex-wrap gap-2\">\n {domainChips.map((chip) => (\n <li key={chip.value}>\n <button\n type=\"button\"\n aria-pressed={domain === chip.value}\n onClick={() => setDomain(chip.value)}\n className={cn(\n 'rounded-full border px-3 py-1 text-sm transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-action-primary-bg',\n domain === chip.value\n ? 'border-action-primary-bg bg-action-primary-bg text-action-primary-text'\n : 'border-border-seam bg-bg-sunken text-text-primary hover:border-border-default'\n )}\n >\n {chip.label}\n <span className=\"ml-1.5 tabular-nums opacity-80\">{chip.count}</span>\n </button>\n </li>\n ))}\n </ul>\n\n <EmphasisPanel>\n <p className=\"text-sm text-text-secondary\">\n {t('ggnomad.search.totalMatches', 'Total matches across all domains')}\n </p>\n <p className=\"mt-1 text-3xl font-semibold tabular-nums text-text-primary\">\n {total.toLocaleString()}\n </p>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {t(\n 'ggnomad.search.totalMatchesNote',\n 'Combined inventory from properties, tours, events and activities — open a domain below to drill in.'\n )}\n </p>\n </EmphasisPanel>\n\n <section className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n <StatCard\n label={t('ggnomad.search.results.propertiesFound', 'Properties found')}\n value={propertyCount}\n icon={<Building />}\n />\n <StatCard\n label={t('ggnomad.search.results.toursFound', 'Tours found')}\n value={tourCount}\n icon={<Compass />}\n />\n <StatCard\n label={t('ggnomad.search.results.eventsFound', 'Events found')}\n value={eventCount}\n icon={<Ticket />}\n />\n <StatCard\n label={t('ggnomad.search.results.activitiesFound', 'Activities found')}\n value={activityCount}\n icon={<Activity />}\n />\n </section>\n\n {matches.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={\n loading\n ? t('ggnomad.search.loadingTitle', 'Searching the catalogue…')\n : t('ggnomad.search.emptyTitle', 'No matching inventory')\n }\n description={\n loading\n ? t(\n 'ggnomad.search.loadingDescription',\n 'Fetching properties, tours, events and activities.'\n )\n : term.trim()\n ? t(\n 'ggnomad.search.noTermMatch',\n 'Nothing matched “{{term}}”. Try a shorter term or another domain.'\n ).replace('{{term}}', term.trim())\n : t(\n 'ggnomad.search.emptyDescription',\n 'Nothing matched across properties, tours, events and activities yet.'\n )\n }\n />\n ) : (\n <SectionCard title={t('ggnomad.search.resultsTitle', 'Results')}>\n <div className=\"grid gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {matches.map((result) => (\n <EntityCard\n key={result.key}\n to={result.path}\n image={result.image}\n imageAlt={result.name}\n title={result.name}\n meta={humanizeEnum(result.kind)}\n badge={\n <span className=\"rounded-full bg-bg-surface/90 px-2.5 py-0.5 text-xs font-medium text-text-primary\">\n {domainLabel(result.domain)}\n </span>\n }\n price={`${result.currency} ${Number(result.price).toFixed(2)}`}\n footer={<RatingSummary rating={result.rating} reviewCount={result.reviewCount} />}\n />\n ))}\n </div>\n <LoadMoreButton\n visible={mayHaveMore}\n onLoadMore={() => setLimit((current) => current + PAGE_SIZE)}\n />\n </SectionCard>\n )}\n </PageShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAoDA,IAAM,IAAY,IAEZ,IAAuC;CAC3C,UAAU;CACV,MAAM;CACN,OAAO;CACP,UAAU;AACZ;AAEA,SAAS,EAAS,GAAgB,GAA6D;CAC7F,OAAO;EACL,KAAK,GAAG,EAAO,GAAG,EAAI;EACtB;EACA,IAAI,EAAI;EACR,MAAM,EAAI;EACV,MAAM,EAAI;EACV,OAAO,EAAI;EACX,UAAU,EAAI;EACd,QAAQ,EAAI;EACZ,aAAa,EAAI;EACjB,OAAO,EAAI,SAAS;EACpB,UAAU;GAAC,EAAI;GAAM,EAAI;GAAM,EAAI,eAAe;EAAE,EAAE,KAAK,GAAG,EAAE,YAAY;EAC5E,MAAM,GAAG,EAAa,GAAQ,GAAG,EAAI;CACvC;AACF;AAEA,SAAgB,IAAa;CAC3B,IAAM,EAAE,SAAM,EAAQ,GAChB,CAAC,GAAM,KAAW,EAAS,EAAE,GAC7B,CAAC,GAAQ,KAAa,EAAyB,KAAK,GACpD,CAAC,GAAO,KAAY,EAAS,CAAS,GAEtC,IAAY;EAAE;EAAO,QAAQ;CAAE,GAC/B,IAAa,EACjB,GAIA,EAAE,aAAU,CACd,GACM,IAAQ,EACZ,GAIA,EAAE,aAAU,CACd,GACM,IAAS,EACb,GAIA,EAAE,aAAU,CACd,GACM,IAAa,EACjB,GAIA,EAAE,aAAU,CACd,GAEM,IAAU,EAAW,WAAW,EAAM,WAAW,EAAO,WAAW,EAAW,SAE9E,IAAa,QAAwB;EACzC,IAAM,IAAiB,CAAC;EACxB,KAAK,IAAM,KAAY,EAAW,MAAM,qBAAqB,CAAC,GAC5D,EAAK,KACH,EAAS,YAAY;GAAE,GAAG;GAAU,OAAO,EAAS;GAAe,MAAM,EAAS;EAAK,CAAC,CAC1F;EAEF,KAAK,IAAM,KAAQ,EAAM,MAAM,gBAAgB,CAAC,GAC9C,EAAK,KAAK,EAAS,QAAQ;GAAE,GAAG;GAAM,MAAM,EAAK;EAAK,CAAC,CAAC;EAE1D,KAAK,IAAM,KAAS,EAAO,MAAM,iBAAiB,CAAC,GACjD,EAAK,KAAK,EAAS,SAAS;GAAE,GAAG;GAAO,MAAM,EAAM;EAAS,CAAC,CAAC;EAEjE,KAAK,IAAM,KAAY,EAAW,MAAM,qBAAqB,CAAC,GAC5D,EAAK,KAAK,EAAS,YAAY;GAAE,GAAG;GAAU,MAAM,EAAS;EAAS,CAAC,CAAC;EAE1E,OAAO;CACT,GAAG;EACD,EAAW,MAAM;EACjB,EAAM,MAAM;EACZ,EAAO,MAAM;EACb,EAAW,MAAM;CACnB,CAAC,GAEK,IAAU,QAAc;EAC5B,IAAM,IAAS,EAAK,KAAK,EAAE,YAAY;EACvC,OAAO,EAAW,QAAQ,MACpB,MAAW,SAAS,EAAO,WAAW,IAAe,KACpD,IACE,EAAO,SAAS,SAAS,CAAM,IADlB,EAErB;CACH,GAAG;EAAC;EAAY;EAAM;CAAM,CAAC,GAEvB,KAAY,MAChB,EAAW,QACR,MACC,EAAO,WAAW,MACjB,CAAC,EAAK,KAAK,KAAK,EAAO,SAAS,SAAS,EAAK,KAAK,EAAE,YAAY,CAAC,EACvE,EAAE,QAEE,IAAgB,EAAS,UAAU,GACnC,IAAY,EAAS,MAAM,GAC3B,IAAa,EAAS,OAAO,GAC7B,IAAgB,EAAS,UAAU,GACnC,IAAQ,IAAgB,IAAY,IAAa,GAIjD,IAAc;EAClB,EAAW,MAAM;EACjB,EAAM,MAAM;EACZ,EAAO,MAAM;EACb,EAAW,MAAM;CACnB,EAAE,MAAM,OAAU,GAAM,UAAU,MAAM,CAAK,GAEvC,KAAe,MAA0B;EAC7C,QAAQ,GAAR;GACE,KAAK,YACH,OAAO,EAAE,kCAAkC,UAAU;GACvD,KAAK,QACH,OAAO,EAAE,8BAA8B,MAAM;GAC/C,KAAK,SACH,OAAO,EAAE,+BAA+B,OAAO;GACjD,KAAK,YACH,OAAO,EAAE,kCAAkC,UAAU;EACzD;CACF,GAEM,IAA8E;EAClF;GAAE,OAAO;GAAO,OAAO,EAAE,6BAA6B,KAAK;GAAG,OAAO;EAAM;EAC3E;GACE,OAAO;GACP,OAAO,EAAE,qCAAqC,YAAY;GAC1D,OAAO;EACT;EACA;GAAE,OAAO;GAAQ,OAAO,EAAE,gCAAgC,OAAO;GAAG,OAAO;EAAU;EACrF;GAAE,OAAO;GAAS,OAAO,EAAE,iCAAiC,QAAQ;GAAG,OAAO;EAAW;EACzF;GACE,OAAO;GACP,OAAO,EAAE,qCAAqC,YAAY;GAC1D,OAAO;EACT;CACF;CAEA,OACE,kBAAC,GAAD;EACE,OAAO,EAAE,wBAAwB,eAAe;EAChD,aAAa,EAAE,+BAA+B,QAAQ;EACtD,UAAU,EAAE,2BAA2B,kDAAkD;YAH3F;GAKE,kBAAC,GAAD;IAAa,MAAM,kBAAC,GAAD,EAAQ,WAAU,SAAU,CAAA;cAC5C,EACC,0BACA,wNACF;GACW,CAAA;GAEb,kBAAC,OAAD,EAAA,UAAA;IACE,kBAAC,SAAD;KAAO,SAAQ;KAAsB,WAAU;eAC5C,EAAE,6BAA6B,sBAAsB;IACjD,CAAA;IACP,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OACE,WAAU;OACV,eAAY;MACb,CAAA;MACD,kBAAC,SAAD;OACE,IAAG;OACH,MAAK;OACL,OAAO;OACP,WAAW,MAAU,EAAQ,EAAM,OAAO,KAAK;OAC/C,aAAa,EACX,8BACA,4CACF;OACA,WAAU;MACX,CAAA;MACA,IACC,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAQ,EAAE;OACzB,cAAY,EAAE,wBAAwB,cAAc;OACpD,WAAU;iBAEV,kBAAC,GAAD,EAAG,WAAU,SAAU,CAAA;MACjB,CAAA,IACN;KACD;;IACL,kBAAC,KAAD;KAAG,WAAU;eACV,EACC,4BACA,+GACF;IACC,CAAA;GACA,EAAA,CAAA;GAEL,kBAAC,MAAD;IAAI,WAAU;cACX,EAAY,KAAK,MAChB,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;KACE,MAAK;KACL,gBAAc,MAAW,EAAK;KAC9B,eAAe,EAAU,EAAK,KAAK;KACnC,WAAW,EACT,gLACA,MAAW,EAAK,QACZ,2EACA,+EACN;eATF,CAWG,EAAK,OACN,kBAAC,QAAD;MAAM,WAAU;gBAAkC,EAAK;KAAY,CAAA,CAC7D;OACN,GAfK,EAAK,KAeV,CACL;GACC,CAAA;GAEJ,kBAAC,GAAD,EAAA,UAAA;IACE,kBAAC,KAAD;KAAG,WAAU;eACV,EAAE,+BAA+B,kCAAkC;IACnE,CAAA;IACH,kBAAC,KAAD;KAAG,WAAU;eACV,EAAM,eAAe;IACrB,CAAA;IACH,kBAAC,KAAD;KAAG,WAAU;eACV,EACC,mCACA,qGACF;IACC,CAAA;GACU,EAAA,CAAA;GAEf,kBAAC,WAAD;IAAS,WAAU;cAAnB;KACE,kBAAC,GAAD;MACE,OAAO,EAAE,0CAA0C,kBAAkB;MACrE,OAAO;MACP,MAAM,kBAAC,GAAD,CAAW,CAAA;KAClB,CAAA;KACD,kBAAC,GAAD;MACE,OAAO,EAAE,qCAAqC,aAAa;MAC3D,OAAO;MACP,MAAM,kBAAC,GAAD,CAAU,CAAA;KACjB,CAAA;KACD,kBAAC,GAAD;MACE,OAAO,EAAE,sCAAsC,cAAc;MAC7D,OAAO;MACP,MAAM,kBAAC,GAAD,CAAS,CAAA;KAChB,CAAA;KACD,kBAAC,GAAD;MACE,OAAO,EAAE,0CAA0C,kBAAkB;MACrE,OAAO;MACP,MAAM,kBAAC,GAAD,CAAW,CAAA;KAClB,CAAA;IACM;;GAER,EAAQ,WAAW,IAClB,kBAAC,GAAD;IACE,cAAa;IACb,OACE,IACI,EAAE,+BAA+B,0BAA0B,IAC3D,EAAE,6BAA6B,uBAAuB;IAE5D,aACE,IACI,EACE,qCACA,oDACF,IACA,EAAK,KAAK,IACR,EACE,8BACA,mEACF,EAAE,QAAQ,YAAY,EAAK,KAAK,CAAC,IACjC,EACE,mCACA,sEACF;GAET,CAAA,IAED,kBAAC,GAAD;IAAa,OAAO,EAAE,+BAA+B,SAAS;cAA9D,CACE,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAQ,KAAK,MACZ,kBAAC,GAAD;MAEE,IAAI,EAAO;MACX,OAAO,EAAO;MACd,UAAU,EAAO;MACjB,OAAO,EAAO;MACd,MAAM,EAAa,EAAO,IAAI;MAC9B,OACE,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAY,EAAO,MAAM;MACtB,CAAA;MAER,OAAO,GAAG,EAAO,SAAS,GAAG,OAAO,EAAO,KAAK,EAAE,QAAQ,CAAC;MAC3D,QAAQ,kBAAC,GAAD;OAAe,QAAQ,EAAO;OAAQ,aAAa,EAAO;MAAc,CAAA;KACjF,GAbM,EAAO,GAab,CACF;IACE,CAAA,GACL,kBAAC,GAAD;KACE,SAAS;KACT,kBAAkB,GAAU,MAAY,IAAU,CAAS;IAC5D,CAAA,CACU;;EAEN;;AAEf"}
@@ -1 +1 @@
1
- {"version":3,"file":"TourDetailsPage.d.ts","sourceRoot":"","sources":["../../../src/ggnomad/pages/TourDetailsPage.tsx"],"names":[],"mappings":"AAqBA,wBAAgB,eAAe,gCAiJ9B"}
1
+ {"version":3,"file":"TourDetailsPage.d.ts","sourceRoot":"","sources":["../../../src/ggnomad/pages/TourDetailsPage.tsx"],"names":[],"mappings":"AA4EA,wBAAgB,eAAe,gCAkO9B"}