@sonordev/site-kit 3.0.5 → 3.2.0

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 (215) hide show
  1. package/AGENTS.md +107 -0
  2. package/agent-manifest.json +377 -0
  3. package/dist/AnalyticsProvider-CD635CHQ.mjs +8 -0
  4. package/dist/{AnalyticsProvider-MLT26JRP.mjs.map → AnalyticsProvider-CD635CHQ.mjs.map} +1 -1
  5. package/dist/AnalyticsProvider-WK2Z6AIN.js +29 -0
  6. package/dist/{AnalyticsProvider-WTOGN7LV.js.map → AnalyticsProvider-WK2Z6AIN.js.map} +1 -1
  7. package/dist/BlogPostFaqSection-4AD2NIGG.js +13 -0
  8. package/dist/{BlogPostFaqSection-H556RV62.js.map → BlogPostFaqSection-4AD2NIGG.js.map} +1 -1
  9. package/dist/{BlogPostFaqSection-VSHOKKUD.mjs → BlogPostFaqSection-TU6YEC7P.mjs} +3 -3
  10. package/dist/{BlogPostFaqSection-VSHOKKUD.mjs.map → BlogPostFaqSection-TU6YEC7P.mjs.map} +1 -1
  11. package/dist/ChatWidget-AIOOZY6H.js +17 -0
  12. package/dist/{ChatWidget-MAL7FB4M.js.map → ChatWidget-AIOOZY6H.js.map} +1 -1
  13. package/dist/ChatWidget-UAAWDBNS.mjs +8 -0
  14. package/dist/{ChatWidget-QPZTPSPE.mjs.map → ChatWidget-UAAWDBNS.mjs.map} +1 -1
  15. package/dist/EngageWidget-EZ5T6H3K.mjs +7 -0
  16. package/dist/{EngageWidget-IPBUA4DW.mjs.map → EngageWidget-EZ5T6H3K.mjs.map} +1 -1
  17. package/dist/EngageWidget-RWVWW56C.js +16 -0
  18. package/dist/{EngageWidget-N3CABK3L.js.map → EngageWidget-RWVWW56C.js.map} +1 -1
  19. package/dist/{SignalCore-4MDIJUAP.mjs → SignalCore-4B4RNYLV.mjs} +60 -47
  20. package/dist/SignalCore-4B4RNYLV.mjs.map +1 -0
  21. package/dist/{SignalCore-ZMFUE3N4.js → SignalCore-AECW2JFP.js} +60 -47
  22. package/dist/SignalCore-AECW2JFP.js.map +1 -0
  23. package/dist/SitemapSync-AICU4SSV.js +15 -0
  24. package/dist/{SitemapSync-FUCH6Y6J.js.map → SitemapSync-AICU4SSV.js.map} +1 -1
  25. package/dist/SitemapSync-CIZCAZXK.mjs +6 -0
  26. package/dist/{SitemapSync-LCSPRAWU.mjs.map → SitemapSync-CIZCAZXK.mjs.map} +1 -1
  27. package/dist/analytics/index.js +11 -9
  28. package/dist/analytics/index.mjs +4 -2
  29. package/dist/blog/index.js +12 -12
  30. package/dist/blog/index.mjs +2 -2
  31. package/dist/blog/server-ui.js +5 -5
  32. package/dist/blog/server-ui.mjs +1 -1
  33. package/dist/brand.css +8 -3
  34. package/dist/{chunk-QTWA44S3.mjs → chunk-2WYEJOGA.mjs} +7 -8
  35. package/dist/chunk-2WYEJOGA.mjs.map +1 -0
  36. package/dist/{chunk-AN4ATCYQ.mjs → chunk-45QHDA7Q.mjs} +3 -3
  37. package/dist/{chunk-AN4ATCYQ.mjs.map → chunk-45QHDA7Q.mjs.map} +1 -1
  38. package/dist/{chunk-RI6JZUAE.js → chunk-4FBV5BJW.js} +7 -8
  39. package/dist/chunk-4FBV5BJW.js.map +1 -0
  40. package/dist/{chunk-YJWKHCOB.js → chunk-4NTMIU6V.js} +13 -11
  41. package/dist/chunk-4NTMIU6V.js.map +1 -0
  42. package/dist/{chunk-YFGKIKXA.mjs → chunk-57QV6NIY.mjs} +3 -3
  43. package/dist/{chunk-YFGKIKXA.mjs.map → chunk-57QV6NIY.mjs.map} +1 -1
  44. package/dist/chunk-5OWZUNNE.js +102 -0
  45. package/dist/chunk-5OWZUNNE.js.map +1 -0
  46. package/dist/{chunk-EUDTPXUI.mjs → chunk-6HPNFWSC.mjs} +3 -3
  47. package/dist/{chunk-EUDTPXUI.mjs.map → chunk-6HPNFWSC.mjs.map} +1 -1
  48. package/dist/{chunk-FT5JNCD4.mjs → chunk-AB2VYIYU.mjs} +11 -11
  49. package/dist/{chunk-FT5JNCD4.mjs.map → chunk-AB2VYIYU.mjs.map} +1 -1
  50. package/dist/{chunk-I5TJIESQ.js → chunk-BMKZHXWQ.js} +11 -11
  51. package/dist/{chunk-I5TJIESQ.js.map → chunk-BMKZHXWQ.js.map} +1 -1
  52. package/dist/{chunk-KHFNPPOX.mjs → chunk-DSRPKUQI.mjs} +6 -6
  53. package/dist/{chunk-KHFNPPOX.mjs.map → chunk-DSRPKUQI.mjs.map} +1 -1
  54. package/dist/chunk-EAASMIWX.js +258 -0
  55. package/dist/chunk-EAASMIWX.js.map +1 -0
  56. package/dist/{chunk-T4QBSRA4.mjs → chunk-EIWRPGOK.mjs} +37 -60
  57. package/dist/chunk-EIWRPGOK.mjs.map +1 -0
  58. package/dist/{chunk-O7E6QVK3.js → chunk-GCDVKOSM.js} +3 -3
  59. package/dist/{chunk-O7E6QVK3.js.map → chunk-GCDVKOSM.js.map} +1 -1
  60. package/dist/{chunk-KMZ527EM.mjs → chunk-GN62H6EG.mjs} +34 -8
  61. package/dist/chunk-GN62H6EG.mjs.map +1 -0
  62. package/dist/{chunk-UJQYSVYV.js → chunk-GQF6QAQS.js} +4 -4
  63. package/dist/{chunk-UJQYSVYV.js.map → chunk-GQF6QAQS.js.map} +1 -1
  64. package/dist/{chunk-MLJXELPA.js → chunk-HAZN43I6.js} +60 -94
  65. package/dist/chunk-HAZN43I6.js.map +1 -0
  66. package/dist/chunk-LZSCCJ4O.mjs +253 -0
  67. package/dist/chunk-LZSCCJ4O.mjs.map +1 -0
  68. package/dist/{chunk-TCVHI3JP.mjs → chunk-N2HR2E4Z.mjs} +60 -92
  69. package/dist/chunk-N2HR2E4Z.mjs.map +1 -0
  70. package/dist/{chunk-VCWSSGCU.js → chunk-NAVDN4AE.js} +7 -7
  71. package/dist/{chunk-VCWSSGCU.js.map → chunk-NAVDN4AE.js.map} +1 -1
  72. package/dist/chunk-NDHFU4HV.mjs +97 -0
  73. package/dist/chunk-NDHFU4HV.mjs.map +1 -0
  74. package/dist/{chunk-PST3NOEM.mjs → chunk-O237KKCX.mjs} +4 -4
  75. package/dist/{chunk-PST3NOEM.mjs.map → chunk-O237KKCX.mjs.map} +1 -1
  76. package/dist/{chunk-5AESOLXS.mjs → chunk-OTY7EWET.mjs} +13 -11
  77. package/dist/chunk-OTY7EWET.mjs.map +1 -0
  78. package/dist/chunk-Q2NBD54V.js +69 -0
  79. package/dist/chunk-Q2NBD54V.js.map +1 -0
  80. package/dist/{chunk-DGHPOWLU.js → chunk-R5A64DCX.js} +8 -8
  81. package/dist/{chunk-DGHPOWLU.js.map → chunk-R5A64DCX.js.map} +1 -1
  82. package/dist/{chunk-3YQCPLGP.mjs → chunk-RFIWVH3D.mjs} +41 -79
  83. package/dist/chunk-RFIWVH3D.mjs.map +1 -0
  84. package/dist/{chunk-NNZDHLXN.js → chunk-S3YQGTBF.js} +35 -9
  85. package/dist/chunk-S3YQGTBF.js.map +1 -0
  86. package/dist/{chunk-IBDVZ6BF.js → chunk-SLWTG2LJ.js} +69 -74
  87. package/dist/chunk-SLWTG2LJ.js.map +1 -0
  88. package/dist/chunk-SN2O72UF.mjs +6 -0
  89. package/dist/chunk-SN2O72UF.mjs.map +1 -0
  90. package/dist/{chunk-65SMJBHW.mjs → chunk-T2DEEKVQ.mjs} +69 -74
  91. package/dist/chunk-T2DEEKVQ.mjs.map +1 -0
  92. package/dist/{chunk-3GCEFS73.js → chunk-TE3W5REY.js} +39 -62
  93. package/dist/chunk-TE3W5REY.js.map +1 -0
  94. package/dist/{chunk-IFVMZFNT.js → chunk-TVCCZ7NR.js} +41 -79
  95. package/dist/chunk-TVCCZ7NR.js.map +1 -0
  96. package/dist/{chunk-EBJ4S5DU.js → chunk-UT2CF4FC.js} +4 -4
  97. package/dist/{chunk-EBJ4S5DU.js.map → chunk-UT2CF4FC.js.map} +1 -1
  98. package/dist/chunk-V6NVBFEP.js +54 -0
  99. package/dist/chunk-V6NVBFEP.js.map +1 -0
  100. package/dist/chunk-WRZQS7O4.js +8 -0
  101. package/dist/chunk-WRZQS7O4.js.map +1 -0
  102. package/dist/chunk-WZHWWOUC.js +51 -0
  103. package/dist/chunk-WZHWWOUC.js.map +1 -0
  104. package/dist/chunk-X3S6KXAP.mjs +47 -0
  105. package/dist/chunk-X3S6KXAP.mjs.map +1 -0
  106. package/dist/chunk-X4OPM3SK.mjs +43 -0
  107. package/dist/chunk-X4OPM3SK.mjs.map +1 -0
  108. package/dist/chunk-ZPLN537Q.mjs +57 -0
  109. package/dist/chunk-ZPLN537Q.mjs.map +1 -0
  110. package/dist/cli/index.js +8986 -1276
  111. package/dist/cli/index.js.map +1 -1
  112. package/dist/cli/index.mjs +8972 -1280
  113. package/dist/cli/index.mjs.map +1 -1
  114. package/dist/commerce/index.js +50 -48
  115. package/dist/commerce/index.mjs +5 -3
  116. package/dist/engage/index.js +11 -8
  117. package/dist/engage/index.js.map +1 -1
  118. package/dist/engage/index.mjs +8 -5
  119. package/dist/engage/index.mjs.map +1 -1
  120. package/dist/fleet/contract.d.mts +99 -0
  121. package/dist/fleet/contract.d.ts +99 -0
  122. package/dist/fleet/contract.js +53 -0
  123. package/dist/fleet/contract.js.map +1 -0
  124. package/dist/fleet/contract.mjs +4 -0
  125. package/dist/fleet/contract.mjs.map +1 -0
  126. package/dist/fleet/index.d.mts +89 -0
  127. package/dist/fleet/index.d.ts +89 -0
  128. package/dist/fleet/index.js +74 -0
  129. package/dist/fleet/index.js.map +1 -0
  130. package/dist/fleet/index.mjs +9 -0
  131. package/dist/fleet/index.mjs.map +1 -0
  132. package/dist/forms/contract.d.mts +69 -0
  133. package/dist/forms/contract.d.ts +69 -0
  134. package/dist/forms/contract.js +33 -0
  135. package/dist/forms/contract.js.map +1 -0
  136. package/dist/forms/contract.mjs +4 -0
  137. package/dist/forms/contract.mjs.map +1 -0
  138. package/dist/forms/index.js +21 -17
  139. package/dist/forms/index.js.map +1 -1
  140. package/dist/forms/index.mjs +14 -10
  141. package/dist/forms/index.mjs.map +1 -1
  142. package/dist/forms/styles.css +10 -8
  143. package/dist/images/index.js +10 -8
  144. package/dist/images/index.mjs +3 -1
  145. package/dist/index.js +98 -96
  146. package/dist/index.js.map +1 -1
  147. package/dist/index.mjs +9 -7
  148. package/dist/index.mjs.map +1 -1
  149. package/dist/layout/client.d.mts +8 -1
  150. package/dist/layout/client.d.ts +8 -1
  151. package/dist/layout/client.js +8 -3
  152. package/dist/layout/client.mjs +7 -2
  153. package/dist/layout/index.d.mts +7 -1
  154. package/dist/layout/index.d.ts +7 -1
  155. package/dist/layout/index.js +57 -4
  156. package/dist/layout/index.js.map +1 -1
  157. package/dist/layout/index.mjs +56 -3
  158. package/dist/layout/index.mjs.map +1 -1
  159. package/dist/maps/index.js +9 -18
  160. package/dist/maps/index.js.map +1 -1
  161. package/dist/maps/index.mjs +9 -18
  162. package/dist/maps/index.mjs.map +1 -1
  163. package/dist/portfolio/contract.d.mts +61 -0
  164. package/dist/portfolio/contract.d.ts +61 -0
  165. package/dist/portfolio/contract.js +43 -0
  166. package/dist/portfolio/contract.js.map +1 -0
  167. package/dist/portfolio/contract.mjs +38 -0
  168. package/dist/portfolio/contract.mjs.map +1 -0
  169. package/dist/seo/client.js +4 -2
  170. package/dist/seo/client.mjs +3 -1
  171. package/dist/seo/index.js +4 -2
  172. package/dist/seo/index.js.map +1 -1
  173. package/dist/seo/index.mjs +3 -1
  174. package/dist/seo/index.mjs.map +1 -1
  175. package/dist/seo-pages/contract.d.mts +62 -0
  176. package/dist/seo-pages/contract.d.ts +62 -0
  177. package/dist/seo-pages/contract.js +48 -0
  178. package/dist/seo-pages/contract.js.map +1 -0
  179. package/dist/seo-pages/contract.mjs +44 -0
  180. package/dist/seo-pages/contract.mjs.map +1 -0
  181. package/dist/signal/index.js +11 -11
  182. package/dist/signal/index.mjs +2 -2
  183. package/dist/sites/contract.d.mts +57 -0
  184. package/dist/sites/contract.d.ts +57 -0
  185. package/dist/sites/contract.js +37 -0
  186. package/dist/sites/contract.js.map +1 -0
  187. package/dist/sites/contract.mjs +4 -0
  188. package/dist/sites/contract.mjs.map +1 -0
  189. package/package.json +44 -4
  190. package/skills/site-kit/SKILL.md +66 -0
  191. package/dist/AnalyticsProvider-MLT26JRP.mjs +0 -6
  192. package/dist/AnalyticsProvider-WTOGN7LV.js +0 -27
  193. package/dist/BlogPostFaqSection-H556RV62.js +0 -13
  194. package/dist/ChatWidget-MAL7FB4M.js +0 -14
  195. package/dist/ChatWidget-QPZTPSPE.mjs +0 -5
  196. package/dist/EngageWidget-IPBUA4DW.mjs +0 -5
  197. package/dist/EngageWidget-N3CABK3L.js +0 -14
  198. package/dist/SignalCore-4MDIJUAP.mjs.map +0 -1
  199. package/dist/SignalCore-ZMFUE3N4.js.map +0 -1
  200. package/dist/SitemapSync-FUCH6Y6J.js +0 -13
  201. package/dist/SitemapSync-LCSPRAWU.mjs +0 -4
  202. package/dist/chunk-3GCEFS73.js.map +0 -1
  203. package/dist/chunk-3YQCPLGP.mjs.map +0 -1
  204. package/dist/chunk-5AESOLXS.mjs.map +0 -1
  205. package/dist/chunk-65SMJBHW.mjs.map +0 -1
  206. package/dist/chunk-IBDVZ6BF.js.map +0 -1
  207. package/dist/chunk-IFVMZFNT.js.map +0 -1
  208. package/dist/chunk-KMZ527EM.mjs.map +0 -1
  209. package/dist/chunk-MLJXELPA.js.map +0 -1
  210. package/dist/chunk-NNZDHLXN.js.map +0 -1
  211. package/dist/chunk-QTWA44S3.mjs.map +0 -1
  212. package/dist/chunk-RI6JZUAE.js.map +0 -1
  213. package/dist/chunk-T4QBSRA4.mjs.map +0 -1
  214. package/dist/chunk-TCVHI3JP.mjs.map +0 -1
  215. package/dist/chunk-YJWKHCOB.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/maps/GoogleMap.tsx","../../src/maps/api.ts","../../src/maps/types.ts","../../src/maps/NeighborhoodMap.tsx"],"names":["useState","useCallback","jsx","jsxs","APIProvider","Map","AdvancedMarker","Pin","InfoWindow","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["'use client'\n\nimport { useState, useCallback } from 'react'\nimport { APIProvider, Map, AdvancedMarker, InfoWindow, Pin } from '@vis.gl/react-google-maps'\nimport type { GoogleMapProps, MapMarker } from './types'\n\nexport function GoogleMap({\n apiKey,\n mapId = 'fcca3cd2bb19cf9a960994e7',\n center,\n zoom = 14,\n markers = [],\n className = '',\n showPropertyMarker = true,\n propertyName,\n propertyAddress,\n propertyPinColor = '#4a7c59',\n}: GoogleMapProps) {\n const [selectedMarker, setSelectedMarker] = useState<MapMarker | null>(null)\n const [showPropertyInfo, setShowPropertyInfo] = useState(false)\n\n const handleMarkerClick = useCallback((marker: MapMarker) => {\n setSelectedMarker(marker)\n setShowPropertyInfo(false)\n }, [])\n\n const handlePropertyClick = useCallback(() => {\n setShowPropertyInfo(true)\n setSelectedMarker(null)\n }, [])\n\n if (!apiKey) {\n return (\n <div className={`bg-gray-100 flex items-center justify-center rounded-2xl ${className}`}>\n <div className=\"text-center p-8\">\n <p className=\"text-gray-500\">Map loading...</p>\n <p className=\"text-xs text-gray-400 mt-2\">Google Maps API key not configured</p>\n </div>\n </div>\n )\n }\n\n return (\n <div className={`relative ${className}`}>\n <APIProvider apiKey={apiKey}>\n <Map\n defaultCenter={center}\n defaultZoom={zoom}\n mapId={mapId}\n className=\"w-full h-full rounded-2xl\"\n disableDefaultUI={false}\n gestureHandling=\"cooperative\"\n style={{ borderRadius: '1rem' }}\n >\n {showPropertyMarker && (\n <AdvancedMarker position={center} onClick={handlePropertyClick} title={propertyName}>\n <Pin background={propertyPinColor} glyphColor=\"#ffffff\" borderColor=\"#ffffff\" scale={1.2} />\n </AdvancedMarker>\n )}\n {showPropertyInfo && propertyName && (\n <InfoWindow position={center} onCloseClick={() => setShowPropertyInfo(false)}>\n <div style={{ padding: '12px', minWidth: 200 }}>\n <h3 style={{ fontWeight: 600, fontSize: '1rem', margin: '0 0 4px' }}>{propertyName}</h3>\n {propertyAddress && (\n <p style={{ fontSize: '0.875rem', color: '#6b7280', margin: '0 0 8px' }}>{propertyAddress}</p>\n )}\n <a\n href={`https://www.google.com/maps/search/?api=1&query=${center.lat},${center.lng}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}\n >\n Get Directions\n </a>\n </div>\n </InfoWindow>\n )}\n {markers.map((marker, index) => (\n <AdvancedMarker\n key={marker.title + index}\n position={marker.position}\n onClick={() => handleMarkerClick(marker)}\n title={marker.title}\n >\n <Pin background=\"#dc2626\" glyphColor=\"#ffffff\" borderColor=\"#ffffff\" />\n </AdvancedMarker>\n ))}\n {selectedMarker && (\n <InfoWindow position={selectedMarker.position} onCloseClick={() => setSelectedMarker(null)}>\n <div style={{ padding: '12px', minWidth: 220, maxWidth: 280 }}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8, marginBottom: 4 }}>\n <h4 style={{ fontWeight: 600, fontSize: '0.875rem', margin: 0, lineHeight: 1.3 }}>{selectedMarker.title}</h4>\n {selectedMarker.isOpen !== undefined && (\n <span style={{\n fontSize: '0.75rem', padding: '2px 6px', borderRadius: 4,\n backgroundColor: selectedMarker.isOpen ? '#dcfce7' : '#fee2e2',\n color: selectedMarker.isOpen ? '#15803d' : '#b91c1c',\n }}>\n {selectedMarker.isOpen ? 'Open' : 'Closed'}\n </span>\n )}\n </div>\n {selectedMarker.type && (\n <p style={{ fontSize: '0.75rem', color: '#9ca3af', margin: '0 0 4px' }}>{selectedMarker.type}</p>\n )}\n {selectedMarker.rating && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 8 }}>\n <span style={{ fontSize: '0.75rem' }}>&#9733;</span>\n <span style={{ fontSize: '0.75rem', fontWeight: 500 }}>{selectedMarker.rating.toFixed(1)}</span>\n {selectedMarker.totalRatings && (\n <span style={{ fontSize: '0.75rem', color: '#9ca3af' }}>({selectedMarker.totalRatings.toLocaleString()})</span>\n )}\n </div>\n )}\n {selectedMarker.address && (\n <p style={{ fontSize: '0.75rem', color: '#6b7280', margin: '0 0 8px' }}>{selectedMarker.address}</p>\n )}\n <div style={{ display: 'flex', gap: 12, paddingTop: 8, borderTop: '1px solid #f3f4f6' }}>\n {selectedMarker.mapsUrl && (\n <a href={selectedMarker.mapsUrl} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}>\n Directions\n </a>\n )}\n {selectedMarker.website && (\n <a href={selectedMarker.website} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}>\n Website\n </a>\n )}\n </div>\n </div>\n </InfoWindow>\n )}\n </Map>\n </APIProvider>\n </div>\n )\n}\n","/**\n * @sonordev/site-kit/maps — API Functions\n *\n * Fetch Google Maps config and nearby places from Sonor API.\n * Uses API key authentication (x-api-key header).\n */\n\nimport type { MapsConfig, NearbyPlace } from './types'\n\n// ---------------------------------------------------------------------------\n// Config helpers (same pattern as reputation/api.ts)\n// ---------------------------------------------------------------------------\n\nfunction getApiConfig() {\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : process.env.SONOR_API_URL || 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_KEY__ || ''\n : process.env.SONOR_API_KEY || ''\n return { apiUrl, apiKey }\n}\n\nasync function fetchWithRetry(\n url: string,\n headers: Record<string, string>,\n retries = 2,\n): Promise<Response> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n const response = await fetch(url, { headers })\n if (response.ok) return response\n if (response.status === 429 && attempt < retries) {\n const delay = Math.pow(2, attempt + 1) * 1000\n await new Promise((r) => setTimeout(r, delay))\n continue\n }\n return response\n }\n throw new Error('fetchWithRetry exhausted')\n}\n\n// ---------------------------------------------------------------------------\n// In-memory caches\n// ---------------------------------------------------------------------------\n\nlet configCache: { data: MapsConfig; timestamp: number } | null = null\nconst CONFIG_CACHE_TTL = 300_000 // 5 minutes (key rarely changes)\n\nlet placesCache: Map<string, { data: NearbyPlace[]; timestamp: number }> = new Map()\nconst PLACES_CACHE_TTL = 60_000 // 1 minute\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch Google Maps config (API key + map ID) from Sonor API.\n * Falls back to NEXT_PUBLIC_GOOGLE_MAPS_API_KEY env var if the API\n * endpoint isn't available yet.\n * Cached for 5 minutes to avoid redundant calls.\n */\nexport async function fetchMapsConfig(): Promise<MapsConfig | null> {\n if (configCache && Date.now() - configCache.timestamp < CONFIG_CACHE_TTL) {\n return configCache.data\n }\n\n const { apiUrl, apiKey } = getApiConfig()\n\n // Try Sonor API first\n if (apiKey) {\n try {\n const res = await fetchWithRetry(\n `${apiUrl}/api/public/maps/config`,\n { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n )\n if (res.ok) {\n const data: MapsConfig = await res.json()\n if (data.apiKey) {\n configCache = { data, timestamp: Date.now() }\n return data\n }\n }\n } catch {\n // Fall through to env var fallback\n }\n }\n\n // Fallback: read from env vars (legacy per-site keys)\n const fallbackKey =\n typeof window !== 'undefined'\n ? (window as any).__GOOGLE_MAPS_API_KEY__ || ''\n : process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY || ''\n const fallbackMapId =\n typeof window !== 'undefined'\n ? ''\n : process.env.NEXT_PUBLIC_GOOGLE_MAPS_MAP_ID || ''\n\n if (fallbackKey) {\n const data: MapsConfig = { apiKey: fallbackKey, mapId: fallbackMapId || 'fcca3cd2bb19cf9a960994e7' }\n configCache = { data, timestamp: Date.now() }\n return data\n }\n\n return null\n}\n\n/**\n * Fetch nearby places from Sonor API.\n * Cached per type for 1 minute.\n */\nexport async function fetchNearbyPlaces(params: {\n lat: number\n lng: number\n type: string\n radius?: number\n limit?: number\n}): Promise<NearbyPlace[]> {\n const cacheKey = `${params.lat},${params.lng}:${params.type}`\n const cached = placesCache.get(cacheKey)\n if (cached && Date.now() - cached.timestamp < PLACES_CACHE_TTL) {\n return cached.data\n }\n\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) return []\n\n try {\n const searchParams = new URLSearchParams({\n lat: String(params.lat),\n lng: String(params.lng),\n type: params.type,\n })\n if (params.radius) searchParams.set('radius', String(params.radius))\n if (params.limit) searchParams.set('limit', String(params.limit))\n\n const res = await fetchWithRetry(\n `${apiUrl}/api/public/maps/nearby-places?${searchParams}`,\n { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n )\n if (!res.ok) return []\n\n const data = await res.json()\n const places: NearbyPlace[] = data.places || []\n\n placesCache.set(cacheKey, { data: places, timestamp: Date.now() })\n return places\n } catch (err) {\n console.error('[site-kit/maps] Failed to fetch nearby places:', err)\n return []\n }\n}\n","/**\n * @sonordev/site-kit/maps — Shared types\n */\n\nexport interface MapsConfig {\n apiKey: string\n mapId: string\n}\n\nexport interface MapMarker {\n position: { lat: number; lng: number }\n title: string\n type?: string\n category?: string\n rating?: number\n totalRatings?: number\n address?: string\n mapsUrl?: string\n website?: string\n isOpen?: boolean\n}\n\nexport interface NearbyPlace {\n id: string\n name: string\n address: string\n lat: number\n lng: number\n rating?: number\n totalRatings?: number\n category: string\n types: string[]\n placeType?: string\n isOpen?: boolean\n mapsUrl: string\n website?: string\n}\n\nexport interface GoogleMapProps {\n /** Google Maps JavaScript API key (fetched from Sonor API) */\n apiKey: string\n /** Google Maps style ID */\n mapId?: string\n /** Center coordinates for the map */\n center: { lat: number; lng: number }\n /** Initial zoom level (default 14) */\n zoom?: number\n /** Place markers to display */\n markers?: MapMarker[]\n /** CSS class for the map container */\n className?: string\n /** Show a pin for the property location (default true) */\n showPropertyMarker?: boolean\n /** Property name for the info window */\n propertyName?: string\n /** Property address for the info window */\n propertyAddress?: string\n /** Property pin color (default '#4a7c59') */\n propertyPinColor?: string\n}\n\nexport interface PlaceTypeFilter {\n id: string\n label: string\n icon: string\n}\n\nexport interface NeighborhoodMapProps {\n /** Property coordinates — center of the map and nearby search */\n center: { lat: number; lng: number }\n /** Property name for the map marker */\n propertyName: string\n /** Full address for the info window and Google Maps link */\n propertyAddress: string\n /** CSS class for the outer container */\n className?: string\n /** Custom place type filters (defaults to restaurants, bars, cafes, fitness, parks, shopping) */\n placeTypes?: PlaceTypeFilter[]\n /** Section title (default \"Interactive Map\") */\n title?: string\n /** Section subtitle */\n subtitle?: string\n /** Property pin color */\n propertyPinColor?: string\n}\n\nexport const DEFAULT_PLACE_TYPES: PlaceTypeFilter[] = [\n { id: 'restaurant', label: 'Restaurants', icon: '\\uD83C\\uDF7D\\uFE0F' },\n { id: 'bar', label: 'Bars', icon: '\\uD83C\\uDF7A' },\n { id: 'cafe', label: 'Cafes', icon: '\\u2615' },\n { id: 'gym', label: 'Fitness', icon: '\\uD83D\\uDCAA' },\n { id: 'park', label: 'Parks', icon: '\\uD83C\\uDF33' },\n { id: 'shopping_mall', label: 'Shopping', icon: '\\uD83D\\uDECD\\uFE0F' },\n]\n","'use client'\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { GoogleMap } from './GoogleMap'\nimport { fetchMapsConfig, fetchNearbyPlaces } from './api'\nimport type { MapsConfig, MapMarker, NearbyPlace, NeighborhoodMapProps } from './types'\nimport { DEFAULT_PLACE_TYPES } from './types'\n\nexport function NeighborhoodMap({\n center,\n propertyName,\n propertyAddress,\n className = '',\n placeTypes = DEFAULT_PLACE_TYPES,\n title = 'Interactive Map',\n subtitle,\n propertyPinColor,\n}: NeighborhoodMapProps) {\n const [config, setConfig] = useState<MapsConfig | null>(null)\n const [places, setPlaces] = useState<NearbyPlace[]>([])\n const [loading, setLoading] = useState(true)\n const [activeFilter, setActiveFilter] = useState(placeTypes[0]?.id || 'restaurant')\n\n // Fetch Google Maps config on mount\n useEffect(() => {\n fetchMapsConfig().then(setConfig)\n }, [])\n\n // Fetch nearby places when filter changes\n const loadPlaces = useCallback(async () => {\n setLoading(true)\n try {\n const results = await fetchNearbyPlaces({\n lat: center.lat,\n lng: center.lng,\n type: activeFilter,\n })\n setPlaces(results)\n } catch {\n setPlaces([])\n } finally {\n setLoading(false)\n }\n }, [center.lat, center.lng, activeFilter])\n\n useEffect(() => {\n loadPlaces()\n }, [loadPlaces])\n\n const markers: MapMarker[] = places.map((place) => ({\n position: { lat: place.lat, lng: place.lng },\n title: place.name,\n type: place.placeType,\n category: place.category,\n rating: place.rating,\n totalRatings: place.totalRatings,\n address: place.address,\n mapsUrl: place.mapsUrl,\n isOpen: place.isOpen,\n website: place.website,\n }))\n\n const mapsQuery = encodeURIComponent(propertyAddress)\n const activeLabel = placeTypes.find((t) => t.id === activeFilter)?.label || 'Places'\n\n return (\n <div className={`py-8 ${className}`}>\n {/* Header */}\n <div className=\"text-center mb-6\">\n <h3 className=\"font-heading text-2xl md:text-3xl font-medium text-foreground mb-2\">{title}</h3>\n {subtitle && (\n <p className=\"text-muted-foreground max-w-2xl mx-auto text-sm\">{subtitle}</p>\n )}\n </div>\n\n {/* Filter buttons */}\n <div className=\"flex flex-wrap justify-center gap-2 mb-6\">\n {placeTypes.map((type) => (\n <button\n key={type.id}\n onClick={() => setActiveFilter(type.id)}\n className={`px-4 py-2 rounded-full text-sm font-medium transition-all ${\n activeFilter === type.id\n ? 'bg-primary text-white shadow-md'\n : 'bg-white text-foreground hover:bg-primary/10 border border-border'\n }`}\n >\n <span className=\"mr-1.5\">{type.icon}</span>\n {type.label}\n </button>\n ))}\n </div>\n\n {/* Map + Sidebar */}\n <div className=\"grid lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2\">\n {config?.apiKey ? (\n <GoogleMap\n apiKey={config.apiKey}\n mapId={config.mapId}\n center={center}\n markers={markers}\n zoom={13}\n className=\"h-[500px] w-full rounded-2xl shadow-lg\"\n propertyName={propertyName}\n propertyAddress={propertyAddress}\n propertyPinColor={propertyPinColor}\n />\n ) : (\n <div className=\"h-[500px] w-full rounded-2xl shadow-lg bg-muted flex items-center justify-center\">\n <div className=\"text-center p-8\">\n <div className=\"animate-spin w-8 h-8 border-2 border-primary border-t-transparent rounded-full mx-auto mb-3\" />\n <p className=\"text-muted-foreground text-sm\">Loading map...</p>\n </div>\n </div>\n )}\n </div>\n\n {/* Sidebar */}\n <div className=\"bg-white rounded-2xl shadow-lg overflow-hidden h-[500px] flex flex-col\">\n <div className=\"p-4 border-b border-border bg-gray-50\">\n <h3 className=\"font-semibold text-foreground flex items-center gap-2\">\n {activeLabel} Nearby\n <span className=\"text-muted-foreground font-normal text-sm\">({places.length})</span>\n </h3>\n </div>\n <div className=\"flex-1 overflow-y-auto min-h-0\">\n {loading ? (\n <div className=\"p-8 text-center\">\n <div className=\"animate-spin w-8 h-8 border-2 border-primary border-t-transparent rounded-full mx-auto mb-3\" />\n <p className=\"text-muted-foreground text-sm\">Loading places...</p>\n </div>\n ) : places.length === 0 ? (\n <div className=\"p-8 text-center\">\n <p className=\"text-muted-foreground\">No places found nearby</p>\n </div>\n ) : (\n <div className=\"divide-y divide-border\">\n {places.slice(0, 10).map((place) => (\n <a\n key={place.id}\n href={place.mapsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"block p-4 hover:bg-gray-50 transition-colors group\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-foreground group-hover:text-primary transition-colors truncate\">\n {place.name}\n </h4>\n <p className=\"text-sm text-muted-foreground truncate\">\n {place.placeType || place.category}\n </p>\n {place.rating && (\n <div className=\"flex items-center gap-1 mt-1\">\n <span className=\"text-yellow-400 text-sm\">&#9733;</span>\n <span className=\"text-sm font-medium\">{place.rating.toFixed(1)}</span>\n {place.totalRatings && (\n <span className=\"text-xs text-muted-foreground\">\n ({place.totalRatings.toLocaleString()})\n </span>\n )}\n </div>\n )}\n </div>\n <div className=\"flex flex-col items-end gap-1\">\n {place.isOpen !== undefined && (\n <span\n className={`text-xs px-2 py-0.5 rounded-full ${\n place.isOpen\n ? 'bg-green-100 text-green-700'\n : 'bg-red-100 text-red-700'\n }`}\n >\n {place.isOpen ? 'Open' : 'Closed'}\n </span>\n )}\n </div>\n </div>\n </a>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Explore more link */}\n <div className=\"text-center mt-6\">\n <a\n href={`https://www.google.com/maps/search/?api=1&query=attractions+near+${mapsQuery}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-2 px-6 py-2.5 border border-primary text-primary rounded-md text-sm font-medium hover:bg-primary hover:text-white transition-colors\"\n >\n Explore More on Google Maps\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n </a>\n </div>\n </div>\n )\n}\n"]}
1
+ {"version":3,"sources":["../../src/maps/GoogleMap.tsx","../../src/maps/api.ts","../../src/maps/types.ts","../../src/maps/NeighborhoodMap.tsx"],"names":["useState","useCallback","jsx","jsxs","APIProvider","Map","AdvancedMarker","Pin","InfoWindow","sonorFetch","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["'use client'\n\nimport { useState, useCallback } from 'react'\nimport { APIProvider, Map, AdvancedMarker, InfoWindow, Pin } from '@vis.gl/react-google-maps'\nimport type { GoogleMapProps, MapMarker } from './types'\n\nexport function GoogleMap({\n apiKey,\n mapId = 'fcca3cd2bb19cf9a960994e7',\n center,\n zoom = 14,\n markers = [],\n className = '',\n showPropertyMarker = true,\n propertyName,\n propertyAddress,\n propertyPinColor = '#4a7c59',\n}: GoogleMapProps) {\n const [selectedMarker, setSelectedMarker] = useState<MapMarker | null>(null)\n const [showPropertyInfo, setShowPropertyInfo] = useState(false)\n\n const handleMarkerClick = useCallback((marker: MapMarker) => {\n setSelectedMarker(marker)\n setShowPropertyInfo(false)\n }, [])\n\n const handlePropertyClick = useCallback(() => {\n setShowPropertyInfo(true)\n setSelectedMarker(null)\n }, [])\n\n if (!apiKey) {\n return (\n <div className={`bg-gray-100 flex items-center justify-center rounded-2xl ${className}`}>\n <div className=\"text-center p-8\">\n <p className=\"text-gray-500\">Map loading...</p>\n <p className=\"text-xs text-gray-400 mt-2\">Google Maps API key not configured</p>\n </div>\n </div>\n )\n }\n\n return (\n <div className={`relative ${className}`}>\n <APIProvider apiKey={apiKey}>\n <Map\n defaultCenter={center}\n defaultZoom={zoom}\n mapId={mapId}\n className=\"w-full h-full rounded-2xl\"\n disableDefaultUI={false}\n gestureHandling=\"cooperative\"\n style={{ borderRadius: '1rem' }}\n >\n {showPropertyMarker && (\n <AdvancedMarker position={center} onClick={handlePropertyClick} title={propertyName}>\n <Pin background={propertyPinColor} glyphColor=\"#ffffff\" borderColor=\"#ffffff\" scale={1.2} />\n </AdvancedMarker>\n )}\n {showPropertyInfo && propertyName && (\n <InfoWindow position={center} onCloseClick={() => setShowPropertyInfo(false)}>\n <div style={{ padding: '12px', minWidth: 200 }}>\n <h3 style={{ fontWeight: 600, fontSize: '1rem', margin: '0 0 4px' }}>{propertyName}</h3>\n {propertyAddress && (\n <p style={{ fontSize: '0.875rem', color: '#6b7280', margin: '0 0 8px' }}>{propertyAddress}</p>\n )}\n <a\n href={`https://www.google.com/maps/search/?api=1&query=${center.lat},${center.lng}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}\n >\n Get Directions\n </a>\n </div>\n </InfoWindow>\n )}\n {markers.map((marker, index) => (\n <AdvancedMarker\n key={marker.title + index}\n position={marker.position}\n onClick={() => handleMarkerClick(marker)}\n title={marker.title}\n >\n <Pin background=\"#dc2626\" glyphColor=\"#ffffff\" borderColor=\"#ffffff\" />\n </AdvancedMarker>\n ))}\n {selectedMarker && (\n <InfoWindow position={selectedMarker.position} onCloseClick={() => setSelectedMarker(null)}>\n <div style={{ padding: '12px', minWidth: 220, maxWidth: 280 }}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8, marginBottom: 4 }}>\n <h4 style={{ fontWeight: 600, fontSize: '0.875rem', margin: 0, lineHeight: 1.3 }}>{selectedMarker.title}</h4>\n {selectedMarker.isOpen !== undefined && (\n <span style={{\n fontSize: '0.75rem', padding: '2px 6px', borderRadius: 4,\n backgroundColor: selectedMarker.isOpen ? '#dcfce7' : '#fee2e2',\n color: selectedMarker.isOpen ? '#15803d' : '#b91c1c',\n }}>\n {selectedMarker.isOpen ? 'Open' : 'Closed'}\n </span>\n )}\n </div>\n {selectedMarker.type && (\n <p style={{ fontSize: '0.75rem', color: '#9ca3af', margin: '0 0 4px' }}>{selectedMarker.type}</p>\n )}\n {selectedMarker.rating && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 8 }}>\n <span style={{ fontSize: '0.75rem' }}>&#9733;</span>\n <span style={{ fontSize: '0.75rem', fontWeight: 500 }}>{selectedMarker.rating.toFixed(1)}</span>\n {selectedMarker.totalRatings && (\n <span style={{ fontSize: '0.75rem', color: '#9ca3af' }}>({selectedMarker.totalRatings.toLocaleString()})</span>\n )}\n </div>\n )}\n {selectedMarker.address && (\n <p style={{ fontSize: '0.75rem', color: '#6b7280', margin: '0 0 8px' }}>{selectedMarker.address}</p>\n )}\n <div style={{ display: 'flex', gap: 12, paddingTop: 8, borderTop: '1px solid #f3f4f6' }}>\n {selectedMarker.mapsUrl && (\n <a href={selectedMarker.mapsUrl} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}>\n Directions\n </a>\n )}\n {selectedMarker.website && (\n <a href={selectedMarker.website} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}>\n Website\n </a>\n )}\n </div>\n </div>\n </InfoWindow>\n )}\n </Map>\n </APIProvider>\n </div>\n )\n}\n","/**\n * @sonordev/site-kit/maps — API Functions\n *\n * Fetch Google Maps config and nearby places from Sonor API.\n * Uses API key authentication (x-api-key header).\n */\n\nimport type { MapsConfig, NearbyPlace } from './types'\nimport { sonorFetch } from '../shared/sonorFetch'\n\n// ---------------------------------------------------------------------------\n// Config helpers (same pattern as reputation/api.ts)\n// ---------------------------------------------------------------------------\n\nfunction getApiConfig() {\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : process.env.SONOR_API_URL || 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_KEY__ || ''\n : process.env.SONOR_API_KEY || ''\n return { apiUrl, apiKey }\n}\n\n// ---------------------------------------------------------------------------\n// In-memory caches\n// ---------------------------------------------------------------------------\n\nlet configCache: { data: MapsConfig; timestamp: number } | null = null\nconst CONFIG_CACHE_TTL = 300_000 // 5 minutes (key rarely changes)\n\nlet placesCache: Map<string, { data: NearbyPlace[]; timestamp: number }> = new Map()\nconst PLACES_CACHE_TTL = 60_000 // 1 minute\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch Google Maps config (API key + map ID) from Sonor API.\n * Falls back to NEXT_PUBLIC_GOOGLE_MAPS_API_KEY env var if the API\n * endpoint isn't available yet.\n * Cached for 5 minutes to avoid redundant calls.\n */\nexport async function fetchMapsConfig(): Promise<MapsConfig | null> {\n if (configCache && Date.now() - configCache.timestamp < CONFIG_CACHE_TTL) {\n return configCache.data\n }\n\n const { apiUrl, apiKey } = getApiConfig()\n\n // Try Sonor API first\n if (apiKey) {\n try {\n const res = await sonorFetch(\n `${apiUrl}/api/public/maps/config`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n if (res.ok) {\n const data: MapsConfig = await res.json()\n if (data.apiKey) {\n configCache = { data, timestamp: Date.now() }\n return data\n }\n }\n } catch {\n // Fall through to env var fallback\n }\n }\n\n // Fallback: read from env vars (legacy per-site keys)\n const fallbackKey =\n typeof window !== 'undefined'\n ? (window as any).__GOOGLE_MAPS_API_KEY__ || ''\n : process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY || ''\n const fallbackMapId =\n typeof window !== 'undefined'\n ? ''\n : process.env.NEXT_PUBLIC_GOOGLE_MAPS_MAP_ID || ''\n\n if (fallbackKey) {\n const data: MapsConfig = { apiKey: fallbackKey, mapId: fallbackMapId || 'fcca3cd2bb19cf9a960994e7' }\n configCache = { data, timestamp: Date.now() }\n return data\n }\n\n return null\n}\n\n/**\n * Fetch nearby places from Sonor API.\n * Cached per type for 1 minute.\n */\nexport async function fetchNearbyPlaces(params: {\n lat: number\n lng: number\n type: string\n radius?: number\n limit?: number\n}): Promise<NearbyPlace[]> {\n const cacheKey = `${params.lat},${params.lng}:${params.type}`\n const cached = placesCache.get(cacheKey)\n if (cached && Date.now() - cached.timestamp < PLACES_CACHE_TTL) {\n return cached.data\n }\n\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) return []\n\n try {\n const searchParams = new URLSearchParams({\n lat: String(params.lat),\n lng: String(params.lng),\n type: params.type,\n })\n if (params.radius) searchParams.set('radius', String(params.radius))\n if (params.limit) searchParams.set('limit', String(params.limit))\n\n const res = await sonorFetch(\n `${apiUrl}/api/public/maps/nearby-places?${searchParams}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n if (!res.ok) return []\n\n const data = await res.json()\n const places: NearbyPlace[] = data.places || []\n\n placesCache.set(cacheKey, { data: places, timestamp: Date.now() })\n return places\n } catch (err) {\n console.warn('[site-kit/maps] Failed to fetch nearby places:', err)\n return []\n }\n}\n","/**\n * @sonordev/site-kit/maps — Shared types\n */\n\nexport interface MapsConfig {\n apiKey: string\n mapId: string\n}\n\nexport interface MapMarker {\n position: { lat: number; lng: number }\n title: string\n type?: string\n category?: string\n rating?: number\n totalRatings?: number\n address?: string\n mapsUrl?: string\n website?: string\n isOpen?: boolean\n}\n\nexport interface NearbyPlace {\n id: string\n name: string\n address: string\n lat: number\n lng: number\n rating?: number\n totalRatings?: number\n category: string\n types: string[]\n placeType?: string\n isOpen?: boolean\n mapsUrl: string\n website?: string\n}\n\nexport interface GoogleMapProps {\n /** Google Maps JavaScript API key (fetched from Sonor API) */\n apiKey: string\n /** Google Maps style ID */\n mapId?: string\n /** Center coordinates for the map */\n center: { lat: number; lng: number }\n /** Initial zoom level (default 14) */\n zoom?: number\n /** Place markers to display */\n markers?: MapMarker[]\n /** CSS class for the map container */\n className?: string\n /** Show a pin for the property location (default true) */\n showPropertyMarker?: boolean\n /** Property name for the info window */\n propertyName?: string\n /** Property address for the info window */\n propertyAddress?: string\n /** Property pin color (default '#4a7c59') */\n propertyPinColor?: string\n}\n\nexport interface PlaceTypeFilter {\n id: string\n label: string\n icon: string\n}\n\nexport interface NeighborhoodMapProps {\n /** Property coordinates — center of the map and nearby search */\n center: { lat: number; lng: number }\n /** Property name for the map marker */\n propertyName: string\n /** Full address for the info window and Google Maps link */\n propertyAddress: string\n /** CSS class for the outer container */\n className?: string\n /** Custom place type filters (defaults to restaurants, bars, cafes, fitness, parks, shopping) */\n placeTypes?: PlaceTypeFilter[]\n /** Section title (default \"Interactive Map\") */\n title?: string\n /** Section subtitle */\n subtitle?: string\n /** Property pin color */\n propertyPinColor?: string\n}\n\nexport const DEFAULT_PLACE_TYPES: PlaceTypeFilter[] = [\n { id: 'restaurant', label: 'Restaurants', icon: '\\uD83C\\uDF7D\\uFE0F' },\n { id: 'bar', label: 'Bars', icon: '\\uD83C\\uDF7A' },\n { id: 'cafe', label: 'Cafes', icon: '\\u2615' },\n { id: 'gym', label: 'Fitness', icon: '\\uD83D\\uDCAA' },\n { id: 'park', label: 'Parks', icon: '\\uD83C\\uDF33' },\n { id: 'shopping_mall', label: 'Shopping', icon: '\\uD83D\\uDECD\\uFE0F' },\n]\n","'use client'\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { GoogleMap } from './GoogleMap'\nimport { fetchMapsConfig, fetchNearbyPlaces } from './api'\nimport type { MapsConfig, MapMarker, NearbyPlace, NeighborhoodMapProps } from './types'\nimport { DEFAULT_PLACE_TYPES } from './types'\n\nexport function NeighborhoodMap({\n center,\n propertyName,\n propertyAddress,\n className = '',\n placeTypes = DEFAULT_PLACE_TYPES,\n title = 'Interactive Map',\n subtitle,\n propertyPinColor,\n}: NeighborhoodMapProps) {\n const [config, setConfig] = useState<MapsConfig | null>(null)\n const [places, setPlaces] = useState<NearbyPlace[]>([])\n const [loading, setLoading] = useState(true)\n const [activeFilter, setActiveFilter] = useState(placeTypes[0]?.id || 'restaurant')\n\n // Fetch Google Maps config on mount\n useEffect(() => {\n fetchMapsConfig().then(setConfig)\n }, [])\n\n // Fetch nearby places when filter changes\n const loadPlaces = useCallback(async () => {\n setLoading(true)\n try {\n const results = await fetchNearbyPlaces({\n lat: center.lat,\n lng: center.lng,\n type: activeFilter,\n })\n setPlaces(results)\n } catch {\n setPlaces([])\n } finally {\n setLoading(false)\n }\n }, [center.lat, center.lng, activeFilter])\n\n useEffect(() => {\n loadPlaces()\n }, [loadPlaces])\n\n const markers: MapMarker[] = places.map((place) => ({\n position: { lat: place.lat, lng: place.lng },\n title: place.name,\n type: place.placeType,\n category: place.category,\n rating: place.rating,\n totalRatings: place.totalRatings,\n address: place.address,\n mapsUrl: place.mapsUrl,\n isOpen: place.isOpen,\n website: place.website,\n }))\n\n const mapsQuery = encodeURIComponent(propertyAddress)\n const activeLabel = placeTypes.find((t) => t.id === activeFilter)?.label || 'Places'\n\n return (\n <div className={`py-8 ${className}`}>\n {/* Header */}\n <div className=\"text-center mb-6\">\n <h3 className=\"font-heading text-2xl md:text-3xl font-medium text-foreground mb-2\">{title}</h3>\n {subtitle && (\n <p className=\"text-muted-foreground max-w-2xl mx-auto text-sm\">{subtitle}</p>\n )}\n </div>\n\n {/* Filter buttons */}\n <div className=\"flex flex-wrap justify-center gap-2 mb-6\">\n {placeTypes.map((type) => (\n <button\n key={type.id}\n onClick={() => setActiveFilter(type.id)}\n className={`px-4 py-2 rounded-full text-sm font-medium transition-all ${\n activeFilter === type.id\n ? 'bg-primary text-white shadow-md'\n : 'bg-white text-foreground hover:bg-primary/10 border border-border'\n }`}\n >\n <span className=\"mr-1.5\">{type.icon}</span>\n {type.label}\n </button>\n ))}\n </div>\n\n {/* Map + Sidebar */}\n <div className=\"grid lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2\">\n {config?.apiKey ? (\n <GoogleMap\n apiKey={config.apiKey}\n mapId={config.mapId}\n center={center}\n markers={markers}\n zoom={13}\n className=\"h-[500px] w-full rounded-2xl shadow-lg\"\n propertyName={propertyName}\n propertyAddress={propertyAddress}\n propertyPinColor={propertyPinColor}\n />\n ) : (\n <div className=\"h-[500px] w-full rounded-2xl shadow-lg bg-muted flex items-center justify-center\">\n <div className=\"text-center p-8\">\n <div className=\"animate-spin w-8 h-8 border-2 border-primary border-t-transparent rounded-full mx-auto mb-3\" />\n <p className=\"text-muted-foreground text-sm\">Loading map...</p>\n </div>\n </div>\n )}\n </div>\n\n {/* Sidebar */}\n <div className=\"bg-white rounded-2xl shadow-lg overflow-hidden h-[500px] flex flex-col\">\n <div className=\"p-4 border-b border-border bg-gray-50\">\n <h3 className=\"font-semibold text-foreground flex items-center gap-2\">\n {activeLabel} Nearby\n <span className=\"text-muted-foreground font-normal text-sm\">({places.length})</span>\n </h3>\n </div>\n <div className=\"flex-1 overflow-y-auto min-h-0\">\n {loading ? (\n <div className=\"p-8 text-center\">\n <div className=\"animate-spin w-8 h-8 border-2 border-primary border-t-transparent rounded-full mx-auto mb-3\" />\n <p className=\"text-muted-foreground text-sm\">Loading places...</p>\n </div>\n ) : places.length === 0 ? (\n <div className=\"p-8 text-center\">\n <p className=\"text-muted-foreground\">No places found nearby</p>\n </div>\n ) : (\n <div className=\"divide-y divide-border\">\n {places.slice(0, 10).map((place) => (\n <a\n key={place.id}\n href={place.mapsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"block p-4 hover:bg-gray-50 transition-colors group\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-foreground group-hover:text-primary transition-colors truncate\">\n {place.name}\n </h4>\n <p className=\"text-sm text-muted-foreground truncate\">\n {place.placeType || place.category}\n </p>\n {place.rating && (\n <div className=\"flex items-center gap-1 mt-1\">\n <span className=\"text-yellow-400 text-sm\">&#9733;</span>\n <span className=\"text-sm font-medium\">{place.rating.toFixed(1)}</span>\n {place.totalRatings && (\n <span className=\"text-xs text-muted-foreground\">\n ({place.totalRatings.toLocaleString()})\n </span>\n )}\n </div>\n )}\n </div>\n <div className=\"flex flex-col items-end gap-1\">\n {place.isOpen !== undefined && (\n <span\n className={`text-xs px-2 py-0.5 rounded-full ${\n place.isOpen\n ? 'bg-green-100 text-green-700'\n : 'bg-red-100 text-red-700'\n }`}\n >\n {place.isOpen ? 'Open' : 'Closed'}\n </span>\n )}\n </div>\n </div>\n </a>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Explore more link */}\n <div className=\"text-center mt-6\">\n <a\n href={`https://www.google.com/maps/search/?api=1&query=attractions+near+${mapsQuery}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-2 px-6 py-2.5 border border-primary text-primary rounded-md text-sm font-medium hover:bg-primary hover:text-white transition-colors\"\n >\n Explore More on Google Maps\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n </a>\n </div>\n </div>\n )\n}\n"]}
@@ -1,4 +1,6 @@
1
1
  'use client';
2
+ import { sonorFetch } from '../chunk-LZSCCJ4O.mjs';
3
+ import '../chunk-SN2O72UF.mjs';
2
4
  import '../chunk-4XPGGLVP.mjs';
3
5
  import { useState, useCallback, useEffect } from 'react';
4
6
  import { APIProvider, Map as Map$1, AdvancedMarker, Pin, InfoWindow } from '@vis.gl/react-google-maps';
@@ -124,19 +126,6 @@ function getApiConfig() {
124
126
  const apiKey = typeof window !== "undefined" ? window.__SITE_KIT_API_KEY__ || "" : process.env.SONOR_API_KEY || "";
125
127
  return { apiUrl, apiKey };
126
128
  }
127
- async function fetchWithRetry(url, headers, retries = 2) {
128
- for (let attempt = 0; attempt <= retries; attempt++) {
129
- const response = await fetch(url, { headers });
130
- if (response.ok) return response;
131
- if (response.status === 429 && attempt < retries) {
132
- const delay = Math.pow(2, attempt + 1) * 1e3;
133
- await new Promise((r) => setTimeout(r, delay));
134
- continue;
135
- }
136
- return response;
137
- }
138
- throw new Error("fetchWithRetry exhausted");
139
- }
140
129
  var configCache = null;
141
130
  var CONFIG_CACHE_TTL = 3e5;
142
131
  var placesCache = /* @__PURE__ */ new Map();
@@ -148,9 +137,10 @@ async function fetchMapsConfig() {
148
137
  const { apiUrl, apiKey } = getApiConfig();
149
138
  if (apiKey) {
150
139
  try {
151
- const res = await fetchWithRetry(
140
+ const res = await sonorFetch(
152
141
  `${apiUrl}/api/public/maps/config`,
153
- { "Content-Type": "application/json", "x-api-key": apiKey }
142
+ { headers: { "Content-Type": "application/json" } },
143
+ { apiKey }
154
144
  );
155
145
  if (res.ok) {
156
146
  const data = await res.json();
@@ -187,9 +177,10 @@ async function fetchNearbyPlaces(params) {
187
177
  });
188
178
  if (params.radius) searchParams.set("radius", String(params.radius));
189
179
  if (params.limit) searchParams.set("limit", String(params.limit));
190
- const res = await fetchWithRetry(
180
+ const res = await sonorFetch(
191
181
  `${apiUrl}/api/public/maps/nearby-places?${searchParams}`,
192
- { "Content-Type": "application/json", "x-api-key": apiKey }
182
+ { headers: { "Content-Type": "application/json" } },
183
+ { apiKey }
193
184
  );
194
185
  if (!res.ok) return [];
195
186
  const data = await res.json();
@@ -197,7 +188,7 @@ async function fetchNearbyPlaces(params) {
197
188
  placesCache.set(cacheKey, { data: places, timestamp: Date.now() });
198
189
  return places;
199
190
  } catch (err) {
200
- console.error("[site-kit/maps] Failed to fetch nearby places:", err);
191
+ console.warn("[site-kit/maps] Failed to fetch nearby places:", err);
201
192
  return [];
202
193
  }
203
194
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/maps/GoogleMap.tsx","../../src/maps/api.ts","../../src/maps/types.ts","../../src/maps/NeighborhoodMap.tsx"],"names":["Map","useState","useCallback","jsxs","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client'\n\nimport { useState, useCallback } from 'react'\nimport { APIProvider, Map, AdvancedMarker, InfoWindow, Pin } from '@vis.gl/react-google-maps'\nimport type { GoogleMapProps, MapMarker } from './types'\n\nexport function GoogleMap({\n apiKey,\n mapId = 'fcca3cd2bb19cf9a960994e7',\n center,\n zoom = 14,\n markers = [],\n className = '',\n showPropertyMarker = true,\n propertyName,\n propertyAddress,\n propertyPinColor = '#4a7c59',\n}: GoogleMapProps) {\n const [selectedMarker, setSelectedMarker] = useState<MapMarker | null>(null)\n const [showPropertyInfo, setShowPropertyInfo] = useState(false)\n\n const handleMarkerClick = useCallback((marker: MapMarker) => {\n setSelectedMarker(marker)\n setShowPropertyInfo(false)\n }, [])\n\n const handlePropertyClick = useCallback(() => {\n setShowPropertyInfo(true)\n setSelectedMarker(null)\n }, [])\n\n if (!apiKey) {\n return (\n <div className={`bg-gray-100 flex items-center justify-center rounded-2xl ${className}`}>\n <div className=\"text-center p-8\">\n <p className=\"text-gray-500\">Map loading...</p>\n <p className=\"text-xs text-gray-400 mt-2\">Google Maps API key not configured</p>\n </div>\n </div>\n )\n }\n\n return (\n <div className={`relative ${className}`}>\n <APIProvider apiKey={apiKey}>\n <Map\n defaultCenter={center}\n defaultZoom={zoom}\n mapId={mapId}\n className=\"w-full h-full rounded-2xl\"\n disableDefaultUI={false}\n gestureHandling=\"cooperative\"\n style={{ borderRadius: '1rem' }}\n >\n {showPropertyMarker && (\n <AdvancedMarker position={center} onClick={handlePropertyClick} title={propertyName}>\n <Pin background={propertyPinColor} glyphColor=\"#ffffff\" borderColor=\"#ffffff\" scale={1.2} />\n </AdvancedMarker>\n )}\n {showPropertyInfo && propertyName && (\n <InfoWindow position={center} onCloseClick={() => setShowPropertyInfo(false)}>\n <div style={{ padding: '12px', minWidth: 200 }}>\n <h3 style={{ fontWeight: 600, fontSize: '1rem', margin: '0 0 4px' }}>{propertyName}</h3>\n {propertyAddress && (\n <p style={{ fontSize: '0.875rem', color: '#6b7280', margin: '0 0 8px' }}>{propertyAddress}</p>\n )}\n <a\n href={`https://www.google.com/maps/search/?api=1&query=${center.lat},${center.lng}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}\n >\n Get Directions\n </a>\n </div>\n </InfoWindow>\n )}\n {markers.map((marker, index) => (\n <AdvancedMarker\n key={marker.title + index}\n position={marker.position}\n onClick={() => handleMarkerClick(marker)}\n title={marker.title}\n >\n <Pin background=\"#dc2626\" glyphColor=\"#ffffff\" borderColor=\"#ffffff\" />\n </AdvancedMarker>\n ))}\n {selectedMarker && (\n <InfoWindow position={selectedMarker.position} onCloseClick={() => setSelectedMarker(null)}>\n <div style={{ padding: '12px', minWidth: 220, maxWidth: 280 }}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8, marginBottom: 4 }}>\n <h4 style={{ fontWeight: 600, fontSize: '0.875rem', margin: 0, lineHeight: 1.3 }}>{selectedMarker.title}</h4>\n {selectedMarker.isOpen !== undefined && (\n <span style={{\n fontSize: '0.75rem', padding: '2px 6px', borderRadius: 4,\n backgroundColor: selectedMarker.isOpen ? '#dcfce7' : '#fee2e2',\n color: selectedMarker.isOpen ? '#15803d' : '#b91c1c',\n }}>\n {selectedMarker.isOpen ? 'Open' : 'Closed'}\n </span>\n )}\n </div>\n {selectedMarker.type && (\n <p style={{ fontSize: '0.75rem', color: '#9ca3af', margin: '0 0 4px' }}>{selectedMarker.type}</p>\n )}\n {selectedMarker.rating && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 8 }}>\n <span style={{ fontSize: '0.75rem' }}>&#9733;</span>\n <span style={{ fontSize: '0.75rem', fontWeight: 500 }}>{selectedMarker.rating.toFixed(1)}</span>\n {selectedMarker.totalRatings && (\n <span style={{ fontSize: '0.75rem', color: '#9ca3af' }}>({selectedMarker.totalRatings.toLocaleString()})</span>\n )}\n </div>\n )}\n {selectedMarker.address && (\n <p style={{ fontSize: '0.75rem', color: '#6b7280', margin: '0 0 8px' }}>{selectedMarker.address}</p>\n )}\n <div style={{ display: 'flex', gap: 12, paddingTop: 8, borderTop: '1px solid #f3f4f6' }}>\n {selectedMarker.mapsUrl && (\n <a href={selectedMarker.mapsUrl} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}>\n Directions\n </a>\n )}\n {selectedMarker.website && (\n <a href={selectedMarker.website} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}>\n Website\n </a>\n )}\n </div>\n </div>\n </InfoWindow>\n )}\n </Map>\n </APIProvider>\n </div>\n )\n}\n","/**\n * @sonordev/site-kit/maps — API Functions\n *\n * Fetch Google Maps config and nearby places from Sonor API.\n * Uses API key authentication (x-api-key header).\n */\n\nimport type { MapsConfig, NearbyPlace } from './types'\n\n// ---------------------------------------------------------------------------\n// Config helpers (same pattern as reputation/api.ts)\n// ---------------------------------------------------------------------------\n\nfunction getApiConfig() {\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : process.env.SONOR_API_URL || 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_KEY__ || ''\n : process.env.SONOR_API_KEY || ''\n return { apiUrl, apiKey }\n}\n\nasync function fetchWithRetry(\n url: string,\n headers: Record<string, string>,\n retries = 2,\n): Promise<Response> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n const response = await fetch(url, { headers })\n if (response.ok) return response\n if (response.status === 429 && attempt < retries) {\n const delay = Math.pow(2, attempt + 1) * 1000\n await new Promise((r) => setTimeout(r, delay))\n continue\n }\n return response\n }\n throw new Error('fetchWithRetry exhausted')\n}\n\n// ---------------------------------------------------------------------------\n// In-memory caches\n// ---------------------------------------------------------------------------\n\nlet configCache: { data: MapsConfig; timestamp: number } | null = null\nconst CONFIG_CACHE_TTL = 300_000 // 5 minutes (key rarely changes)\n\nlet placesCache: Map<string, { data: NearbyPlace[]; timestamp: number }> = new Map()\nconst PLACES_CACHE_TTL = 60_000 // 1 minute\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch Google Maps config (API key + map ID) from Sonor API.\n * Falls back to NEXT_PUBLIC_GOOGLE_MAPS_API_KEY env var if the API\n * endpoint isn't available yet.\n * Cached for 5 minutes to avoid redundant calls.\n */\nexport async function fetchMapsConfig(): Promise<MapsConfig | null> {\n if (configCache && Date.now() - configCache.timestamp < CONFIG_CACHE_TTL) {\n return configCache.data\n }\n\n const { apiUrl, apiKey } = getApiConfig()\n\n // Try Sonor API first\n if (apiKey) {\n try {\n const res = await fetchWithRetry(\n `${apiUrl}/api/public/maps/config`,\n { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n )\n if (res.ok) {\n const data: MapsConfig = await res.json()\n if (data.apiKey) {\n configCache = { data, timestamp: Date.now() }\n return data\n }\n }\n } catch {\n // Fall through to env var fallback\n }\n }\n\n // Fallback: read from env vars (legacy per-site keys)\n const fallbackKey =\n typeof window !== 'undefined'\n ? (window as any).__GOOGLE_MAPS_API_KEY__ || ''\n : process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY || ''\n const fallbackMapId =\n typeof window !== 'undefined'\n ? ''\n : process.env.NEXT_PUBLIC_GOOGLE_MAPS_MAP_ID || ''\n\n if (fallbackKey) {\n const data: MapsConfig = { apiKey: fallbackKey, mapId: fallbackMapId || 'fcca3cd2bb19cf9a960994e7' }\n configCache = { data, timestamp: Date.now() }\n return data\n }\n\n return null\n}\n\n/**\n * Fetch nearby places from Sonor API.\n * Cached per type for 1 minute.\n */\nexport async function fetchNearbyPlaces(params: {\n lat: number\n lng: number\n type: string\n radius?: number\n limit?: number\n}): Promise<NearbyPlace[]> {\n const cacheKey = `${params.lat},${params.lng}:${params.type}`\n const cached = placesCache.get(cacheKey)\n if (cached && Date.now() - cached.timestamp < PLACES_CACHE_TTL) {\n return cached.data\n }\n\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) return []\n\n try {\n const searchParams = new URLSearchParams({\n lat: String(params.lat),\n lng: String(params.lng),\n type: params.type,\n })\n if (params.radius) searchParams.set('radius', String(params.radius))\n if (params.limit) searchParams.set('limit', String(params.limit))\n\n const res = await fetchWithRetry(\n `${apiUrl}/api/public/maps/nearby-places?${searchParams}`,\n { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n )\n if (!res.ok) return []\n\n const data = await res.json()\n const places: NearbyPlace[] = data.places || []\n\n placesCache.set(cacheKey, { data: places, timestamp: Date.now() })\n return places\n } catch (err) {\n console.error('[site-kit/maps] Failed to fetch nearby places:', err)\n return []\n }\n}\n","/**\n * @sonordev/site-kit/maps — Shared types\n */\n\nexport interface MapsConfig {\n apiKey: string\n mapId: string\n}\n\nexport interface MapMarker {\n position: { lat: number; lng: number }\n title: string\n type?: string\n category?: string\n rating?: number\n totalRatings?: number\n address?: string\n mapsUrl?: string\n website?: string\n isOpen?: boolean\n}\n\nexport interface NearbyPlace {\n id: string\n name: string\n address: string\n lat: number\n lng: number\n rating?: number\n totalRatings?: number\n category: string\n types: string[]\n placeType?: string\n isOpen?: boolean\n mapsUrl: string\n website?: string\n}\n\nexport interface GoogleMapProps {\n /** Google Maps JavaScript API key (fetched from Sonor API) */\n apiKey: string\n /** Google Maps style ID */\n mapId?: string\n /** Center coordinates for the map */\n center: { lat: number; lng: number }\n /** Initial zoom level (default 14) */\n zoom?: number\n /** Place markers to display */\n markers?: MapMarker[]\n /** CSS class for the map container */\n className?: string\n /** Show a pin for the property location (default true) */\n showPropertyMarker?: boolean\n /** Property name for the info window */\n propertyName?: string\n /** Property address for the info window */\n propertyAddress?: string\n /** Property pin color (default '#4a7c59') */\n propertyPinColor?: string\n}\n\nexport interface PlaceTypeFilter {\n id: string\n label: string\n icon: string\n}\n\nexport interface NeighborhoodMapProps {\n /** Property coordinates — center of the map and nearby search */\n center: { lat: number; lng: number }\n /** Property name for the map marker */\n propertyName: string\n /** Full address for the info window and Google Maps link */\n propertyAddress: string\n /** CSS class for the outer container */\n className?: string\n /** Custom place type filters (defaults to restaurants, bars, cafes, fitness, parks, shopping) */\n placeTypes?: PlaceTypeFilter[]\n /** Section title (default \"Interactive Map\") */\n title?: string\n /** Section subtitle */\n subtitle?: string\n /** Property pin color */\n propertyPinColor?: string\n}\n\nexport const DEFAULT_PLACE_TYPES: PlaceTypeFilter[] = [\n { id: 'restaurant', label: 'Restaurants', icon: '\\uD83C\\uDF7D\\uFE0F' },\n { id: 'bar', label: 'Bars', icon: '\\uD83C\\uDF7A' },\n { id: 'cafe', label: 'Cafes', icon: '\\u2615' },\n { id: 'gym', label: 'Fitness', icon: '\\uD83D\\uDCAA' },\n { id: 'park', label: 'Parks', icon: '\\uD83C\\uDF33' },\n { id: 'shopping_mall', label: 'Shopping', icon: '\\uD83D\\uDECD\\uFE0F' },\n]\n","'use client'\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { GoogleMap } from './GoogleMap'\nimport { fetchMapsConfig, fetchNearbyPlaces } from './api'\nimport type { MapsConfig, MapMarker, NearbyPlace, NeighborhoodMapProps } from './types'\nimport { DEFAULT_PLACE_TYPES } from './types'\n\nexport function NeighborhoodMap({\n center,\n propertyName,\n propertyAddress,\n className = '',\n placeTypes = DEFAULT_PLACE_TYPES,\n title = 'Interactive Map',\n subtitle,\n propertyPinColor,\n}: NeighborhoodMapProps) {\n const [config, setConfig] = useState<MapsConfig | null>(null)\n const [places, setPlaces] = useState<NearbyPlace[]>([])\n const [loading, setLoading] = useState(true)\n const [activeFilter, setActiveFilter] = useState(placeTypes[0]?.id || 'restaurant')\n\n // Fetch Google Maps config on mount\n useEffect(() => {\n fetchMapsConfig().then(setConfig)\n }, [])\n\n // Fetch nearby places when filter changes\n const loadPlaces = useCallback(async () => {\n setLoading(true)\n try {\n const results = await fetchNearbyPlaces({\n lat: center.lat,\n lng: center.lng,\n type: activeFilter,\n })\n setPlaces(results)\n } catch {\n setPlaces([])\n } finally {\n setLoading(false)\n }\n }, [center.lat, center.lng, activeFilter])\n\n useEffect(() => {\n loadPlaces()\n }, [loadPlaces])\n\n const markers: MapMarker[] = places.map((place) => ({\n position: { lat: place.lat, lng: place.lng },\n title: place.name,\n type: place.placeType,\n category: place.category,\n rating: place.rating,\n totalRatings: place.totalRatings,\n address: place.address,\n mapsUrl: place.mapsUrl,\n isOpen: place.isOpen,\n website: place.website,\n }))\n\n const mapsQuery = encodeURIComponent(propertyAddress)\n const activeLabel = placeTypes.find((t) => t.id === activeFilter)?.label || 'Places'\n\n return (\n <div className={`py-8 ${className}`}>\n {/* Header */}\n <div className=\"text-center mb-6\">\n <h3 className=\"font-heading text-2xl md:text-3xl font-medium text-foreground mb-2\">{title}</h3>\n {subtitle && (\n <p className=\"text-muted-foreground max-w-2xl mx-auto text-sm\">{subtitle}</p>\n )}\n </div>\n\n {/* Filter buttons */}\n <div className=\"flex flex-wrap justify-center gap-2 mb-6\">\n {placeTypes.map((type) => (\n <button\n key={type.id}\n onClick={() => setActiveFilter(type.id)}\n className={`px-4 py-2 rounded-full text-sm font-medium transition-all ${\n activeFilter === type.id\n ? 'bg-primary text-white shadow-md'\n : 'bg-white text-foreground hover:bg-primary/10 border border-border'\n }`}\n >\n <span className=\"mr-1.5\">{type.icon}</span>\n {type.label}\n </button>\n ))}\n </div>\n\n {/* Map + Sidebar */}\n <div className=\"grid lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2\">\n {config?.apiKey ? (\n <GoogleMap\n apiKey={config.apiKey}\n mapId={config.mapId}\n center={center}\n markers={markers}\n zoom={13}\n className=\"h-[500px] w-full rounded-2xl shadow-lg\"\n propertyName={propertyName}\n propertyAddress={propertyAddress}\n propertyPinColor={propertyPinColor}\n />\n ) : (\n <div className=\"h-[500px] w-full rounded-2xl shadow-lg bg-muted flex items-center justify-center\">\n <div className=\"text-center p-8\">\n <div className=\"animate-spin w-8 h-8 border-2 border-primary border-t-transparent rounded-full mx-auto mb-3\" />\n <p className=\"text-muted-foreground text-sm\">Loading map...</p>\n </div>\n </div>\n )}\n </div>\n\n {/* Sidebar */}\n <div className=\"bg-white rounded-2xl shadow-lg overflow-hidden h-[500px] flex flex-col\">\n <div className=\"p-4 border-b border-border bg-gray-50\">\n <h3 className=\"font-semibold text-foreground flex items-center gap-2\">\n {activeLabel} Nearby\n <span className=\"text-muted-foreground font-normal text-sm\">({places.length})</span>\n </h3>\n </div>\n <div className=\"flex-1 overflow-y-auto min-h-0\">\n {loading ? (\n <div className=\"p-8 text-center\">\n <div className=\"animate-spin w-8 h-8 border-2 border-primary border-t-transparent rounded-full mx-auto mb-3\" />\n <p className=\"text-muted-foreground text-sm\">Loading places...</p>\n </div>\n ) : places.length === 0 ? (\n <div className=\"p-8 text-center\">\n <p className=\"text-muted-foreground\">No places found nearby</p>\n </div>\n ) : (\n <div className=\"divide-y divide-border\">\n {places.slice(0, 10).map((place) => (\n <a\n key={place.id}\n href={place.mapsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"block p-4 hover:bg-gray-50 transition-colors group\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-foreground group-hover:text-primary transition-colors truncate\">\n {place.name}\n </h4>\n <p className=\"text-sm text-muted-foreground truncate\">\n {place.placeType || place.category}\n </p>\n {place.rating && (\n <div className=\"flex items-center gap-1 mt-1\">\n <span className=\"text-yellow-400 text-sm\">&#9733;</span>\n <span className=\"text-sm font-medium\">{place.rating.toFixed(1)}</span>\n {place.totalRatings && (\n <span className=\"text-xs text-muted-foreground\">\n ({place.totalRatings.toLocaleString()})\n </span>\n )}\n </div>\n )}\n </div>\n <div className=\"flex flex-col items-end gap-1\">\n {place.isOpen !== undefined && (\n <span\n className={`text-xs px-2 py-0.5 rounded-full ${\n place.isOpen\n ? 'bg-green-100 text-green-700'\n : 'bg-red-100 text-red-700'\n }`}\n >\n {place.isOpen ? 'Open' : 'Closed'}\n </span>\n )}\n </div>\n </div>\n </a>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Explore more link */}\n <div className=\"text-center mt-6\">\n <a\n href={`https://www.google.com/maps/search/?api=1&query=attractions+near+${mapsQuery}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-2 px-6 py-2.5 border border-primary text-primary rounded-md text-sm font-medium hover:bg-primary hover:text-white transition-colors\"\n >\n Explore More on Google Maps\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n </a>\n </div>\n </div>\n )\n}\n"]}
1
+ {"version":3,"sources":["../../src/maps/GoogleMap.tsx","../../src/maps/api.ts","../../src/maps/types.ts","../../src/maps/NeighborhoodMap.tsx"],"names":["Map","useState","useCallback","jsxs","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client'\n\nimport { useState, useCallback } from 'react'\nimport { APIProvider, Map, AdvancedMarker, InfoWindow, Pin } from '@vis.gl/react-google-maps'\nimport type { GoogleMapProps, MapMarker } from './types'\n\nexport function GoogleMap({\n apiKey,\n mapId = 'fcca3cd2bb19cf9a960994e7',\n center,\n zoom = 14,\n markers = [],\n className = '',\n showPropertyMarker = true,\n propertyName,\n propertyAddress,\n propertyPinColor = '#4a7c59',\n}: GoogleMapProps) {\n const [selectedMarker, setSelectedMarker] = useState<MapMarker | null>(null)\n const [showPropertyInfo, setShowPropertyInfo] = useState(false)\n\n const handleMarkerClick = useCallback((marker: MapMarker) => {\n setSelectedMarker(marker)\n setShowPropertyInfo(false)\n }, [])\n\n const handlePropertyClick = useCallback(() => {\n setShowPropertyInfo(true)\n setSelectedMarker(null)\n }, [])\n\n if (!apiKey) {\n return (\n <div className={`bg-gray-100 flex items-center justify-center rounded-2xl ${className}`}>\n <div className=\"text-center p-8\">\n <p className=\"text-gray-500\">Map loading...</p>\n <p className=\"text-xs text-gray-400 mt-2\">Google Maps API key not configured</p>\n </div>\n </div>\n )\n }\n\n return (\n <div className={`relative ${className}`}>\n <APIProvider apiKey={apiKey}>\n <Map\n defaultCenter={center}\n defaultZoom={zoom}\n mapId={mapId}\n className=\"w-full h-full rounded-2xl\"\n disableDefaultUI={false}\n gestureHandling=\"cooperative\"\n style={{ borderRadius: '1rem' }}\n >\n {showPropertyMarker && (\n <AdvancedMarker position={center} onClick={handlePropertyClick} title={propertyName}>\n <Pin background={propertyPinColor} glyphColor=\"#ffffff\" borderColor=\"#ffffff\" scale={1.2} />\n </AdvancedMarker>\n )}\n {showPropertyInfo && propertyName && (\n <InfoWindow position={center} onCloseClick={() => setShowPropertyInfo(false)}>\n <div style={{ padding: '12px', minWidth: 200 }}>\n <h3 style={{ fontWeight: 600, fontSize: '1rem', margin: '0 0 4px' }}>{propertyName}</h3>\n {propertyAddress && (\n <p style={{ fontSize: '0.875rem', color: '#6b7280', margin: '0 0 8px' }}>{propertyAddress}</p>\n )}\n <a\n href={`https://www.google.com/maps/search/?api=1&query=${center.lat},${center.lng}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}\n >\n Get Directions\n </a>\n </div>\n </InfoWindow>\n )}\n {markers.map((marker, index) => (\n <AdvancedMarker\n key={marker.title + index}\n position={marker.position}\n onClick={() => handleMarkerClick(marker)}\n title={marker.title}\n >\n <Pin background=\"#dc2626\" glyphColor=\"#ffffff\" borderColor=\"#ffffff\" />\n </AdvancedMarker>\n ))}\n {selectedMarker && (\n <InfoWindow position={selectedMarker.position} onCloseClick={() => setSelectedMarker(null)}>\n <div style={{ padding: '12px', minWidth: 220, maxWidth: 280 }}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8, marginBottom: 4 }}>\n <h4 style={{ fontWeight: 600, fontSize: '0.875rem', margin: 0, lineHeight: 1.3 }}>{selectedMarker.title}</h4>\n {selectedMarker.isOpen !== undefined && (\n <span style={{\n fontSize: '0.75rem', padding: '2px 6px', borderRadius: 4,\n backgroundColor: selectedMarker.isOpen ? '#dcfce7' : '#fee2e2',\n color: selectedMarker.isOpen ? '#15803d' : '#b91c1c',\n }}>\n {selectedMarker.isOpen ? 'Open' : 'Closed'}\n </span>\n )}\n </div>\n {selectedMarker.type && (\n <p style={{ fontSize: '0.75rem', color: '#9ca3af', margin: '0 0 4px' }}>{selectedMarker.type}</p>\n )}\n {selectedMarker.rating && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 8 }}>\n <span style={{ fontSize: '0.75rem' }}>&#9733;</span>\n <span style={{ fontSize: '0.75rem', fontWeight: 500 }}>{selectedMarker.rating.toFixed(1)}</span>\n {selectedMarker.totalRatings && (\n <span style={{ fontSize: '0.75rem', color: '#9ca3af' }}>({selectedMarker.totalRatings.toLocaleString()})</span>\n )}\n </div>\n )}\n {selectedMarker.address && (\n <p style={{ fontSize: '0.75rem', color: '#6b7280', margin: '0 0 8px' }}>{selectedMarker.address}</p>\n )}\n <div style={{ display: 'flex', gap: 12, paddingTop: 8, borderTop: '1px solid #f3f4f6' }}>\n {selectedMarker.mapsUrl && (\n <a href={selectedMarker.mapsUrl} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}>\n Directions\n </a>\n )}\n {selectedMarker.website && (\n <a href={selectedMarker.website} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: '0.75rem', color: '#2563eb', textDecoration: 'none' }}>\n Website\n </a>\n )}\n </div>\n </div>\n </InfoWindow>\n )}\n </Map>\n </APIProvider>\n </div>\n )\n}\n","/**\n * @sonordev/site-kit/maps — API Functions\n *\n * Fetch Google Maps config and nearby places from Sonor API.\n * Uses API key authentication (x-api-key header).\n */\n\nimport type { MapsConfig, NearbyPlace } from './types'\nimport { sonorFetch } from '../shared/sonorFetch'\n\n// ---------------------------------------------------------------------------\n// Config helpers (same pattern as reputation/api.ts)\n// ---------------------------------------------------------------------------\n\nfunction getApiConfig() {\n const apiUrl =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : process.env.SONOR_API_URL || 'https://api.sonor.io'\n const apiKey =\n typeof window !== 'undefined'\n ? (window as any).__SITE_KIT_API_KEY__ || ''\n : process.env.SONOR_API_KEY || ''\n return { apiUrl, apiKey }\n}\n\n// ---------------------------------------------------------------------------\n// In-memory caches\n// ---------------------------------------------------------------------------\n\nlet configCache: { data: MapsConfig; timestamp: number } | null = null\nconst CONFIG_CACHE_TTL = 300_000 // 5 minutes (key rarely changes)\n\nlet placesCache: Map<string, { data: NearbyPlace[]; timestamp: number }> = new Map()\nconst PLACES_CACHE_TTL = 60_000 // 1 minute\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch Google Maps config (API key + map ID) from Sonor API.\n * Falls back to NEXT_PUBLIC_GOOGLE_MAPS_API_KEY env var if the API\n * endpoint isn't available yet.\n * Cached for 5 minutes to avoid redundant calls.\n */\nexport async function fetchMapsConfig(): Promise<MapsConfig | null> {\n if (configCache && Date.now() - configCache.timestamp < CONFIG_CACHE_TTL) {\n return configCache.data\n }\n\n const { apiUrl, apiKey } = getApiConfig()\n\n // Try Sonor API first\n if (apiKey) {\n try {\n const res = await sonorFetch(\n `${apiUrl}/api/public/maps/config`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n if (res.ok) {\n const data: MapsConfig = await res.json()\n if (data.apiKey) {\n configCache = { data, timestamp: Date.now() }\n return data\n }\n }\n } catch {\n // Fall through to env var fallback\n }\n }\n\n // Fallback: read from env vars (legacy per-site keys)\n const fallbackKey =\n typeof window !== 'undefined'\n ? (window as any).__GOOGLE_MAPS_API_KEY__ || ''\n : process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY || ''\n const fallbackMapId =\n typeof window !== 'undefined'\n ? ''\n : process.env.NEXT_PUBLIC_GOOGLE_MAPS_MAP_ID || ''\n\n if (fallbackKey) {\n const data: MapsConfig = { apiKey: fallbackKey, mapId: fallbackMapId || 'fcca3cd2bb19cf9a960994e7' }\n configCache = { data, timestamp: Date.now() }\n return data\n }\n\n return null\n}\n\n/**\n * Fetch nearby places from Sonor API.\n * Cached per type for 1 minute.\n */\nexport async function fetchNearbyPlaces(params: {\n lat: number\n lng: number\n type: string\n radius?: number\n limit?: number\n}): Promise<NearbyPlace[]> {\n const cacheKey = `${params.lat},${params.lng}:${params.type}`\n const cached = placesCache.get(cacheKey)\n if (cached && Date.now() - cached.timestamp < PLACES_CACHE_TTL) {\n return cached.data\n }\n\n const { apiUrl, apiKey } = getApiConfig()\n if (!apiKey) return []\n\n try {\n const searchParams = new URLSearchParams({\n lat: String(params.lat),\n lng: String(params.lng),\n type: params.type,\n })\n if (params.radius) searchParams.set('radius', String(params.radius))\n if (params.limit) searchParams.set('limit', String(params.limit))\n\n const res = await sonorFetch(\n `${apiUrl}/api/public/maps/nearby-places?${searchParams}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n if (!res.ok) return []\n\n const data = await res.json()\n const places: NearbyPlace[] = data.places || []\n\n placesCache.set(cacheKey, { data: places, timestamp: Date.now() })\n return places\n } catch (err) {\n console.warn('[site-kit/maps] Failed to fetch nearby places:', err)\n return []\n }\n}\n","/**\n * @sonordev/site-kit/maps — Shared types\n */\n\nexport interface MapsConfig {\n apiKey: string\n mapId: string\n}\n\nexport interface MapMarker {\n position: { lat: number; lng: number }\n title: string\n type?: string\n category?: string\n rating?: number\n totalRatings?: number\n address?: string\n mapsUrl?: string\n website?: string\n isOpen?: boolean\n}\n\nexport interface NearbyPlace {\n id: string\n name: string\n address: string\n lat: number\n lng: number\n rating?: number\n totalRatings?: number\n category: string\n types: string[]\n placeType?: string\n isOpen?: boolean\n mapsUrl: string\n website?: string\n}\n\nexport interface GoogleMapProps {\n /** Google Maps JavaScript API key (fetched from Sonor API) */\n apiKey: string\n /** Google Maps style ID */\n mapId?: string\n /** Center coordinates for the map */\n center: { lat: number; lng: number }\n /** Initial zoom level (default 14) */\n zoom?: number\n /** Place markers to display */\n markers?: MapMarker[]\n /** CSS class for the map container */\n className?: string\n /** Show a pin for the property location (default true) */\n showPropertyMarker?: boolean\n /** Property name for the info window */\n propertyName?: string\n /** Property address for the info window */\n propertyAddress?: string\n /** Property pin color (default '#4a7c59') */\n propertyPinColor?: string\n}\n\nexport interface PlaceTypeFilter {\n id: string\n label: string\n icon: string\n}\n\nexport interface NeighborhoodMapProps {\n /** Property coordinates — center of the map and nearby search */\n center: { lat: number; lng: number }\n /** Property name for the map marker */\n propertyName: string\n /** Full address for the info window and Google Maps link */\n propertyAddress: string\n /** CSS class for the outer container */\n className?: string\n /** Custom place type filters (defaults to restaurants, bars, cafes, fitness, parks, shopping) */\n placeTypes?: PlaceTypeFilter[]\n /** Section title (default \"Interactive Map\") */\n title?: string\n /** Section subtitle */\n subtitle?: string\n /** Property pin color */\n propertyPinColor?: string\n}\n\nexport const DEFAULT_PLACE_TYPES: PlaceTypeFilter[] = [\n { id: 'restaurant', label: 'Restaurants', icon: '\\uD83C\\uDF7D\\uFE0F' },\n { id: 'bar', label: 'Bars', icon: '\\uD83C\\uDF7A' },\n { id: 'cafe', label: 'Cafes', icon: '\\u2615' },\n { id: 'gym', label: 'Fitness', icon: '\\uD83D\\uDCAA' },\n { id: 'park', label: 'Parks', icon: '\\uD83C\\uDF33' },\n { id: 'shopping_mall', label: 'Shopping', icon: '\\uD83D\\uDECD\\uFE0F' },\n]\n","'use client'\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { GoogleMap } from './GoogleMap'\nimport { fetchMapsConfig, fetchNearbyPlaces } from './api'\nimport type { MapsConfig, MapMarker, NearbyPlace, NeighborhoodMapProps } from './types'\nimport { DEFAULT_PLACE_TYPES } from './types'\n\nexport function NeighborhoodMap({\n center,\n propertyName,\n propertyAddress,\n className = '',\n placeTypes = DEFAULT_PLACE_TYPES,\n title = 'Interactive Map',\n subtitle,\n propertyPinColor,\n}: NeighborhoodMapProps) {\n const [config, setConfig] = useState<MapsConfig | null>(null)\n const [places, setPlaces] = useState<NearbyPlace[]>([])\n const [loading, setLoading] = useState(true)\n const [activeFilter, setActiveFilter] = useState(placeTypes[0]?.id || 'restaurant')\n\n // Fetch Google Maps config on mount\n useEffect(() => {\n fetchMapsConfig().then(setConfig)\n }, [])\n\n // Fetch nearby places when filter changes\n const loadPlaces = useCallback(async () => {\n setLoading(true)\n try {\n const results = await fetchNearbyPlaces({\n lat: center.lat,\n lng: center.lng,\n type: activeFilter,\n })\n setPlaces(results)\n } catch {\n setPlaces([])\n } finally {\n setLoading(false)\n }\n }, [center.lat, center.lng, activeFilter])\n\n useEffect(() => {\n loadPlaces()\n }, [loadPlaces])\n\n const markers: MapMarker[] = places.map((place) => ({\n position: { lat: place.lat, lng: place.lng },\n title: place.name,\n type: place.placeType,\n category: place.category,\n rating: place.rating,\n totalRatings: place.totalRatings,\n address: place.address,\n mapsUrl: place.mapsUrl,\n isOpen: place.isOpen,\n website: place.website,\n }))\n\n const mapsQuery = encodeURIComponent(propertyAddress)\n const activeLabel = placeTypes.find((t) => t.id === activeFilter)?.label || 'Places'\n\n return (\n <div className={`py-8 ${className}`}>\n {/* Header */}\n <div className=\"text-center mb-6\">\n <h3 className=\"font-heading text-2xl md:text-3xl font-medium text-foreground mb-2\">{title}</h3>\n {subtitle && (\n <p className=\"text-muted-foreground max-w-2xl mx-auto text-sm\">{subtitle}</p>\n )}\n </div>\n\n {/* Filter buttons */}\n <div className=\"flex flex-wrap justify-center gap-2 mb-6\">\n {placeTypes.map((type) => (\n <button\n key={type.id}\n onClick={() => setActiveFilter(type.id)}\n className={`px-4 py-2 rounded-full text-sm font-medium transition-all ${\n activeFilter === type.id\n ? 'bg-primary text-white shadow-md'\n : 'bg-white text-foreground hover:bg-primary/10 border border-border'\n }`}\n >\n <span className=\"mr-1.5\">{type.icon}</span>\n {type.label}\n </button>\n ))}\n </div>\n\n {/* Map + Sidebar */}\n <div className=\"grid lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2\">\n {config?.apiKey ? (\n <GoogleMap\n apiKey={config.apiKey}\n mapId={config.mapId}\n center={center}\n markers={markers}\n zoom={13}\n className=\"h-[500px] w-full rounded-2xl shadow-lg\"\n propertyName={propertyName}\n propertyAddress={propertyAddress}\n propertyPinColor={propertyPinColor}\n />\n ) : (\n <div className=\"h-[500px] w-full rounded-2xl shadow-lg bg-muted flex items-center justify-center\">\n <div className=\"text-center p-8\">\n <div className=\"animate-spin w-8 h-8 border-2 border-primary border-t-transparent rounded-full mx-auto mb-3\" />\n <p className=\"text-muted-foreground text-sm\">Loading map...</p>\n </div>\n </div>\n )}\n </div>\n\n {/* Sidebar */}\n <div className=\"bg-white rounded-2xl shadow-lg overflow-hidden h-[500px] flex flex-col\">\n <div className=\"p-4 border-b border-border bg-gray-50\">\n <h3 className=\"font-semibold text-foreground flex items-center gap-2\">\n {activeLabel} Nearby\n <span className=\"text-muted-foreground font-normal text-sm\">({places.length})</span>\n </h3>\n </div>\n <div className=\"flex-1 overflow-y-auto min-h-0\">\n {loading ? (\n <div className=\"p-8 text-center\">\n <div className=\"animate-spin w-8 h-8 border-2 border-primary border-t-transparent rounded-full mx-auto mb-3\" />\n <p className=\"text-muted-foreground text-sm\">Loading places...</p>\n </div>\n ) : places.length === 0 ? (\n <div className=\"p-8 text-center\">\n <p className=\"text-muted-foreground\">No places found nearby</p>\n </div>\n ) : (\n <div className=\"divide-y divide-border\">\n {places.slice(0, 10).map((place) => (\n <a\n key={place.id}\n href={place.mapsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"block p-4 hover:bg-gray-50 transition-colors group\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-foreground group-hover:text-primary transition-colors truncate\">\n {place.name}\n </h4>\n <p className=\"text-sm text-muted-foreground truncate\">\n {place.placeType || place.category}\n </p>\n {place.rating && (\n <div className=\"flex items-center gap-1 mt-1\">\n <span className=\"text-yellow-400 text-sm\">&#9733;</span>\n <span className=\"text-sm font-medium\">{place.rating.toFixed(1)}</span>\n {place.totalRatings && (\n <span className=\"text-xs text-muted-foreground\">\n ({place.totalRatings.toLocaleString()})\n </span>\n )}\n </div>\n )}\n </div>\n <div className=\"flex flex-col items-end gap-1\">\n {place.isOpen !== undefined && (\n <span\n className={`text-xs px-2 py-0.5 rounded-full ${\n place.isOpen\n ? 'bg-green-100 text-green-700'\n : 'bg-red-100 text-red-700'\n }`}\n >\n {place.isOpen ? 'Open' : 'Closed'}\n </span>\n )}\n </div>\n </div>\n </a>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Explore more link */}\n <div className=\"text-center mt-6\">\n <a\n href={`https://www.google.com/maps/search/?api=1&query=attractions+near+${mapsQuery}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-2 px-6 py-2.5 border border-primary text-primary rounded-md text-sm font-medium hover:bg-primary hover:text-white transition-colors\"\n >\n Explore More on Google Maps\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n </a>\n </div>\n </div>\n )\n}\n"]}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @sonordev/site-kit/portfolio/contract — portfolio proof display policy (v1)
3
+ *
4
+ * Single source of truth for the Lighthouse-KPI collapse policy shared by the
5
+ * content side (signal-api generation) and the render side (agency-site-kit
6
+ * display). Same pattern as the other site-kit contracts:
7
+ * - agency-site-kit imports these directly (it already depends on site-kit)
8
+ * from `src/portfolio/curate-proof.ts`, which keeps the render-only
9
+ * primitives that bind to its section types.
10
+ * - signal-api keeps a byte-identical inline mirror
11
+ * (`src/modules/skills/portfolio/portfolio-kpi-policy.util.ts`) guarded by
12
+ * the shared drift-test vectors in `contract.test.ts`.
13
+ *
14
+ * Why it exists: generated case studies arrived with four "100/100 Lighthouse X"
15
+ * KPIs repeated across hero, results cards, and a Performance section. One
16
+ * differentiator repeated a dozen times stops differentiating — collapse the
17
+ * per-category Lighthouse tiles to at most one summary, business outcomes first.
18
+ */
19
+ /** Bump on breaking changes to the collapse policy. */
20
+ declare const PORTFOLIO_CONTRACT_VERSION: 1;
21
+ /** Minimal KPI shape the policy reads — callers pass their own richer tiles. */
22
+ interface KpiLike {
23
+ label: string;
24
+ value: number;
25
+ description?: string;
26
+ }
27
+ /** True when a KPI tile is a per-category Lighthouse score. */
28
+ declare function isLighthouseKpi(kpi: Pick<KpiLike, 'label'>): boolean;
29
+ /**
30
+ * Collapse per-category Lighthouse KPIs to at most one summary tile, business
31
+ * outcomes first. When every category is present at 100 the summary says so;
32
+ * otherwise the Performance category (the one buyers know) represents the set.
33
+ * Fewer than two Lighthouse tiles → returned unchanged.
34
+ */
35
+ declare function curateHeroKpis<T extends KpiLike>(kpis: T[]): T[];
36
+ /**
37
+ * Agent-native contract: JSON Schema for the minimal KPI shape, so services and
38
+ * agents can validate tiles before applying the collapse policy.
39
+ */
40
+ declare const PORTFOLIO_KPI_JSON_SCHEMA: {
41
+ readonly $schema: "http://json-schema.org/draft-07/schema#";
42
+ readonly $id: "https://sonor.io/schemas/portfolio-kpi.v1.json";
43
+ readonly title: "KpiLike";
44
+ readonly description: "The subset of a portfolio KPI tile the Lighthouse-collapse policy reads.";
45
+ readonly type: "object";
46
+ readonly required: readonly ["label", "value"];
47
+ readonly properties: {
48
+ readonly label: {
49
+ readonly type: "string";
50
+ };
51
+ readonly value: {
52
+ readonly type: "number";
53
+ };
54
+ readonly description: {
55
+ readonly type: "string";
56
+ };
57
+ };
58
+ readonly additionalProperties: true;
59
+ };
60
+
61
+ export { type KpiLike, PORTFOLIO_CONTRACT_VERSION, PORTFOLIO_KPI_JSON_SCHEMA, curateHeroKpis, isLighthouseKpi };
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @sonordev/site-kit/portfolio/contract — portfolio proof display policy (v1)
3
+ *
4
+ * Single source of truth for the Lighthouse-KPI collapse policy shared by the
5
+ * content side (signal-api generation) and the render side (agency-site-kit
6
+ * display). Same pattern as the other site-kit contracts:
7
+ * - agency-site-kit imports these directly (it already depends on site-kit)
8
+ * from `src/portfolio/curate-proof.ts`, which keeps the render-only
9
+ * primitives that bind to its section types.
10
+ * - signal-api keeps a byte-identical inline mirror
11
+ * (`src/modules/skills/portfolio/portfolio-kpi-policy.util.ts`) guarded by
12
+ * the shared drift-test vectors in `contract.test.ts`.
13
+ *
14
+ * Why it exists: generated case studies arrived with four "100/100 Lighthouse X"
15
+ * KPIs repeated across hero, results cards, and a Performance section. One
16
+ * differentiator repeated a dozen times stops differentiating — collapse the
17
+ * per-category Lighthouse tiles to at most one summary, business outcomes first.
18
+ */
19
+ /** Bump on breaking changes to the collapse policy. */
20
+ declare const PORTFOLIO_CONTRACT_VERSION: 1;
21
+ /** Minimal KPI shape the policy reads — callers pass their own richer tiles. */
22
+ interface KpiLike {
23
+ label: string;
24
+ value: number;
25
+ description?: string;
26
+ }
27
+ /** True when a KPI tile is a per-category Lighthouse score. */
28
+ declare function isLighthouseKpi(kpi: Pick<KpiLike, 'label'>): boolean;
29
+ /**
30
+ * Collapse per-category Lighthouse KPIs to at most one summary tile, business
31
+ * outcomes first. When every category is present at 100 the summary says so;
32
+ * otherwise the Performance category (the one buyers know) represents the set.
33
+ * Fewer than two Lighthouse tiles → returned unchanged.
34
+ */
35
+ declare function curateHeroKpis<T extends KpiLike>(kpis: T[]): T[];
36
+ /**
37
+ * Agent-native contract: JSON Schema for the minimal KPI shape, so services and
38
+ * agents can validate tiles before applying the collapse policy.
39
+ */
40
+ declare const PORTFOLIO_KPI_JSON_SCHEMA: {
41
+ readonly $schema: "http://json-schema.org/draft-07/schema#";
42
+ readonly $id: "https://sonor.io/schemas/portfolio-kpi.v1.json";
43
+ readonly title: "KpiLike";
44
+ readonly description: "The subset of a portfolio KPI tile the Lighthouse-collapse policy reads.";
45
+ readonly type: "object";
46
+ readonly required: readonly ["label", "value"];
47
+ readonly properties: {
48
+ readonly label: {
49
+ readonly type: "string";
50
+ };
51
+ readonly value: {
52
+ readonly type: "number";
53
+ };
54
+ readonly description: {
55
+ readonly type: "string";
56
+ };
57
+ };
58
+ readonly additionalProperties: true;
59
+ };
60
+
61
+ export { type KpiLike, PORTFOLIO_CONTRACT_VERSION, PORTFOLIO_KPI_JSON_SCHEMA, curateHeroKpis, isLighthouseKpi };
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+
3
+ require('../chunk-ZSMWDLMK.js');
4
+
5
+ // src/portfolio/contract.ts
6
+ var PORTFOLIO_CONTRACT_VERSION = 1;
7
+ var LIGHTHOUSE_RE = /lighthouse/i;
8
+ function isLighthouseKpi(kpi) {
9
+ return LIGHTHOUSE_RE.test(kpi.label || "");
10
+ }
11
+ function curateHeroKpis(kpis) {
12
+ const business = kpis.filter((k) => !isLighthouseKpi(k));
13
+ const lighthouse = kpis.filter(isLighthouseKpi);
14
+ if (lighthouse.length <= 1) return kpis;
15
+ const allPerfect = lighthouse.length >= 4 && lighthouse.every((k) => k.value === 100);
16
+ const summary = allPerfect ? {
17
+ ...lighthouse[0],
18
+ label: "Lighthouse, all 4 categories",
19
+ description: "Perfect scores across performance, SEO, accessibility, and best practices."
20
+ } : lighthouse.find((k) => /performance/i.test(k.label)) ?? lighthouse[0];
21
+ return [...business, summary];
22
+ }
23
+ var PORTFOLIO_KPI_JSON_SCHEMA = {
24
+ $schema: "http://json-schema.org/draft-07/schema#",
25
+ $id: "https://sonor.io/schemas/portfolio-kpi.v1.json",
26
+ title: "KpiLike",
27
+ description: "The subset of a portfolio KPI tile the Lighthouse-collapse policy reads.",
28
+ type: "object",
29
+ required: ["label", "value"],
30
+ properties: {
31
+ label: { type: "string" },
32
+ value: { type: "number" },
33
+ description: { type: "string" }
34
+ },
35
+ additionalProperties: true
36
+ };
37
+
38
+ exports.PORTFOLIO_CONTRACT_VERSION = PORTFOLIO_CONTRACT_VERSION;
39
+ exports.PORTFOLIO_KPI_JSON_SCHEMA = PORTFOLIO_KPI_JSON_SCHEMA;
40
+ exports.curateHeroKpis = curateHeroKpis;
41
+ exports.isLighthouseKpi = isLighthouseKpi;
42
+ //# sourceMappingURL=contract.js.map
43
+ //# sourceMappingURL=contract.js.map