@sonordev/site-kit 6.0.0 → 6.1.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 (255) hide show
  1. package/README.md +11 -0
  2. package/agent-manifest.json +8 -1
  3. package/dist/{AnalyticsProvider-6QVM2B6O.mjs → AnalyticsProvider-PO6SSJG2.mjs} +6 -6
  4. package/dist/{AnalyticsProvider-6QVM2B6O.mjs.map → AnalyticsProvider-PO6SSJG2.mjs.map} +1 -1
  5. package/dist/{AnalyticsProvider-AZQXLRWN.js → AnalyticsProvider-V6G45QG7.js} +10 -10
  6. package/dist/{AnalyticsProvider-AZQXLRWN.js.map → AnalyticsProvider-V6G45QG7.js.map} +1 -1
  7. package/dist/{ArticleViewTracker-AEWJMXQQ.mjs → ArticleViewTracker-CML36HJZ.mjs} +5 -5
  8. package/dist/{ArticleViewTracker-AEWJMXQQ.mjs.map → ArticleViewTracker-CML36HJZ.mjs.map} +1 -1
  9. package/dist/{ArticleViewTracker-CFBTQ46B.js → ArticleViewTracker-FE2YWHX4.js} +6 -6
  10. package/dist/{ArticleViewTracker-CFBTQ46B.js.map → ArticleViewTracker-FE2YWHX4.js.map} +1 -1
  11. package/dist/ChatWidget-GVNDKGUU.mjs +16 -0
  12. package/dist/{ChatWidget-6626OPXO.mjs.map → ChatWidget-GVNDKGUU.mjs.map} +1 -1
  13. package/dist/ChatWidget-YL34KOZM.js +25 -0
  14. package/dist/{ChatWidget-U24AYLXF.js.map → ChatWidget-YL34KOZM.js.map} +1 -1
  15. package/dist/EngageWidget-465O5XUV.mjs +12 -0
  16. package/dist/{EngageWidget-TR47W2ZI.mjs.map → EngageWidget-465O5XUV.mjs.map} +1 -1
  17. package/dist/EngageWidget-IQRKRYPG.js +21 -0
  18. package/dist/{EngageWidget-XUTDFRF3.js.map → EngageWidget-IQRKRYPG.js.map} +1 -1
  19. package/dist/{FileField-R4RQG77G.js → FileField-F3PFKMIF.js} +6 -6
  20. package/dist/{FileField-R4RQG77G.js.map → FileField-F3PFKMIF.js.map} +1 -1
  21. package/dist/{FileField-DNNC5IPS.mjs → FileField-FWKSBFRX.mjs} +5 -5
  22. package/dist/{FileField-DNNC5IPS.mjs.map → FileField-FWKSBFRX.mjs.map} +1 -1
  23. package/dist/{FormSpotlight-7ILRAD3W.js → FormSpotlight-DJQ3P3EX.js} +9 -9
  24. package/dist/{FormSpotlight-7ILRAD3W.js.map → FormSpotlight-DJQ3P3EX.js.map} +1 -1
  25. package/dist/{FormSpotlight-MXY4I46H.mjs → FormSpotlight-K4LP2DMP.mjs} +3 -3
  26. package/dist/{FormSpotlight-MXY4I46H.mjs.map → FormSpotlight-K4LP2DMP.mjs.map} +1 -1
  27. package/dist/{FormStage-CVD3I3SE.js → FormStage-QMGZ3MOT.js} +9 -9
  28. package/dist/{FormStage-CVD3I3SE.js.map → FormStage-QMGZ3MOT.js.map} +1 -1
  29. package/dist/{FormStage-FDJGRGEU.mjs → FormStage-YKVTHPKV.mjs} +3 -3
  30. package/dist/{FormStage-FDJGRGEU.mjs.map → FormStage-YKVTHPKV.mjs.map} +1 -1
  31. package/dist/ManagedForm-MLPETHSQ.js +25 -0
  32. package/dist/{ManagedForm-KYIK54SL.js.map → ManagedForm-MLPETHSQ.js.map} +1 -1
  33. package/dist/ManagedForm-P3L34ALG.mjs +16 -0
  34. package/dist/{ManagedForm-5675CLWS.mjs.map → ManagedForm-P3L34ALG.mjs.map} +1 -1
  35. package/dist/{ManagedNewsletterForm-DFLDGNQU.mjs → ManagedNewsletterForm-C5YQH7MP.mjs} +7 -7
  36. package/dist/{ManagedNewsletterForm-DFLDGNQU.mjs.map → ManagedNewsletterForm-C5YQH7MP.mjs.map} +1 -1
  37. package/dist/{ManagedNewsletterForm-IH3MRJOD.js → ManagedNewsletterForm-R4LLZBRQ.js} +8 -8
  38. package/dist/{ManagedNewsletterForm-IH3MRJOD.js.map → ManagedNewsletterForm-R4LLZBRQ.js.map} +1 -1
  39. package/dist/{SignalCore-ZH3R6XD3.mjs → SignalCore-BNYNS6P7.mjs} +5 -5
  40. package/dist/{SignalCore-ZH3R6XD3.mjs.map → SignalCore-BNYNS6P7.mjs.map} +1 -1
  41. package/dist/{SignalCore-6LYIZFXK.js → SignalCore-CLELIKFI.js} +11 -11
  42. package/dist/{SignalCore-6LYIZFXK.js.map → SignalCore-CLELIKFI.js.map} +1 -1
  43. package/dist/SitemapSync-P7XWL6VV.js +18 -0
  44. package/dist/{SitemapSync-PZ76V5MX.js.map → SitemapSync-P7XWL6VV.js.map} +1 -1
  45. package/dist/SitemapSync-SIKJCK7N.mjs +9 -0
  46. package/dist/{SitemapSync-PKBXWVI6.mjs.map → SitemapSync-SIKJCK7N.mjs.map} +1 -1
  47. package/dist/analytics/index.js +9 -9
  48. package/dist/analytics/index.mjs +4 -4
  49. package/dist/articles/index.js +2 -2
  50. package/dist/articles/index.mjs +2 -2
  51. package/dist/articles/server-ui.js +1 -1
  52. package/dist/articles/server-ui.mjs +1 -1
  53. package/dist/{chunk-QOCLSJIU.js → chunk-36NE4PSS.js} +3 -3
  54. package/dist/{chunk-QOCLSJIU.js.map → chunk-36NE4PSS.js.map} +1 -1
  55. package/dist/{chunk-NR52QHOD.mjs → chunk-3DXJHMQM.mjs} +3 -3
  56. package/dist/{chunk-NR52QHOD.mjs.map → chunk-3DXJHMQM.mjs.map} +1 -1
  57. package/dist/{chunk-XKXZ4OW4.mjs → chunk-4EJI4IOX.mjs} +63 -50
  58. package/dist/chunk-4EJI4IOX.mjs.map +1 -0
  59. package/dist/{chunk-RZGVNDO6.mjs → chunk-6OSHL7H5.mjs} +4 -4
  60. package/dist/{chunk-RZGVNDO6.mjs.map → chunk-6OSHL7H5.mjs.map} +1 -1
  61. package/dist/chunk-ACKFL6WA.mjs +6 -0
  62. package/dist/{chunk-2KRAY5NC.mjs.map → chunk-ACKFL6WA.mjs.map} +1 -1
  63. package/dist/{chunk-YYEBFQGS.js → chunk-AQUWWATH.js} +4 -4
  64. package/dist/{chunk-YYEBFQGS.js.map → chunk-AQUWWATH.js.map} +1 -1
  65. package/dist/{chunk-2WEBUZNP.mjs → chunk-BDSNEB3O.mjs} +3 -3
  66. package/dist/{chunk-2WEBUZNP.mjs.map → chunk-BDSNEB3O.mjs.map} +1 -1
  67. package/dist/{chunk-VINLIMAX.js → chunk-BGOPF6J2.js} +3 -3
  68. package/dist/{chunk-VINLIMAX.js.map → chunk-BGOPF6J2.js.map} +1 -1
  69. package/dist/{chunk-RDPI27TS.mjs → chunk-BJ4T65OK.mjs} +4 -2
  70. package/dist/chunk-BJ4T65OK.mjs.map +1 -0
  71. package/dist/chunk-BZR6RUIN.mjs +128 -0
  72. package/dist/chunk-BZR6RUIN.mjs.map +1 -0
  73. package/dist/{chunk-WV5YQL3W.mjs → chunk-CJX2MC62.mjs} +3 -3
  74. package/dist/{chunk-WV5YQL3W.mjs.map → chunk-CJX2MC62.mjs.map} +1 -1
  75. package/dist/{chunk-3LCJJ6Y6.js → chunk-DQXEYUTD.js} +3 -3
  76. package/dist/{chunk-3LCJJ6Y6.js.map → chunk-DQXEYUTD.js.map} +1 -1
  77. package/dist/{chunk-MCG4BSRW.js → chunk-DXBSBWSS.js} +5 -5
  78. package/dist/{chunk-MCG4BSRW.js.map → chunk-DXBSBWSS.js.map} +1 -1
  79. package/dist/{chunk-JXCMCASE.mjs → chunk-ESAPT5JT.mjs} +3 -3
  80. package/dist/{chunk-JXCMCASE.mjs.map → chunk-ESAPT5JT.mjs.map} +1 -1
  81. package/dist/{chunk-3OCXVTN5.mjs → chunk-F6BYWNHU.mjs} +3 -3
  82. package/dist/{chunk-3OCXVTN5.mjs.map → chunk-F6BYWNHU.mjs.map} +1 -1
  83. package/dist/{chunk-PJYTYM5G.mjs → chunk-FQAZBJJO.mjs} +3 -3
  84. package/dist/{chunk-PJYTYM5G.mjs.map → chunk-FQAZBJJO.mjs.map} +1 -1
  85. package/dist/{chunk-G6KQ3C3W.js → chunk-G3L26XQ7.js} +4 -2
  86. package/dist/chunk-G3L26XQ7.js.map +1 -0
  87. package/dist/{chunk-CSSNZGTU.mjs → chunk-H5FCJBAN.mjs} +3 -3
  88. package/dist/{chunk-CSSNZGTU.mjs.map → chunk-H5FCJBAN.mjs.map} +1 -1
  89. package/dist/{chunk-HX5JPNMN.js → chunk-I4RU3RCS.js} +8 -8
  90. package/dist/{chunk-HX5JPNMN.js.map → chunk-I4RU3RCS.js.map} +1 -1
  91. package/dist/{chunk-YGDQVZEL.js → chunk-IDJY2JWU.js} +5 -5
  92. package/dist/{chunk-YGDQVZEL.js.map → chunk-IDJY2JWU.js.map} +1 -1
  93. package/dist/{chunk-MS2EE6LT.js → chunk-ITVQV7DK.js} +10 -10
  94. package/dist/{chunk-MS2EE6LT.js.map → chunk-ITVQV7DK.js.map} +1 -1
  95. package/dist/chunk-IWSN4DGG.js +132 -0
  96. package/dist/chunk-IWSN4DGG.js.map +1 -0
  97. package/dist/{chunk-BZG34WHF.js → chunk-K4LLYQFZ.js} +14 -14
  98. package/dist/{chunk-BZG34WHF.js.map → chunk-K4LLYQFZ.js.map} +1 -1
  99. package/dist/{chunk-5DSUPTBU.js → chunk-KDNB6BYH.js} +11 -11
  100. package/dist/{chunk-5DSUPTBU.js.map → chunk-KDNB6BYH.js.map} +1 -1
  101. package/dist/{chunk-RC4L4DV2.mjs → chunk-KKTSAT7I.mjs} +4 -4
  102. package/dist/{chunk-RC4L4DV2.mjs.map → chunk-KKTSAT7I.mjs.map} +1 -1
  103. package/dist/{chunk-RPCODOWG.mjs → chunk-L3GAEBJU.mjs} +3 -3
  104. package/dist/{chunk-RPCODOWG.mjs.map → chunk-L3GAEBJU.mjs.map} +1 -1
  105. package/dist/{chunk-TCZHRSWY.js → chunk-LF44SJPP.js} +4 -4
  106. package/dist/{chunk-TCZHRSWY.js.map → chunk-LF44SJPP.js.map} +1 -1
  107. package/dist/{chunk-HFCQGSD2.js → chunk-MZK5APTV.js} +18 -18
  108. package/dist/{chunk-HFCQGSD2.js.map → chunk-MZK5APTV.js.map} +1 -1
  109. package/dist/chunk-NBOBOYMT.js +52 -0
  110. package/dist/chunk-NBOBOYMT.js.map +1 -0
  111. package/dist/{chunk-3U5SVB4W.js → chunk-NDVKIDMN.js} +4 -4
  112. package/dist/{chunk-3U5SVB4W.js.map → chunk-NDVKIDMN.js.map} +1 -1
  113. package/dist/{chunk-YWLBQ3L5.mjs → chunk-NMKUYGKK.mjs} +4 -4
  114. package/dist/{chunk-YWLBQ3L5.mjs.map → chunk-NMKUYGKK.mjs.map} +1 -1
  115. package/dist/chunk-OBKS3CPP.mjs +50 -0
  116. package/dist/chunk-OBKS3CPP.mjs.map +1 -0
  117. package/dist/{chunk-TCCGP3FT.mjs → chunk-OF4V7CSP.mjs} +3 -3
  118. package/dist/{chunk-TCCGP3FT.mjs.map → chunk-OF4V7CSP.mjs.map} +1 -1
  119. package/dist/{chunk-ZR4TYCQW.mjs → chunk-OQWAJBYA.mjs} +3 -3
  120. package/dist/{chunk-ZR4TYCQW.mjs.map → chunk-OQWAJBYA.mjs.map} +1 -1
  121. package/dist/chunk-OXA4ZSX2.js +8 -0
  122. package/dist/{chunk-EL74YDNX.js.map → chunk-OXA4ZSX2.js.map} +1 -1
  123. package/dist/{chunk-GQ3SDRL6.mjs → chunk-QC6VQ2IW.mjs} +3 -3
  124. package/dist/{chunk-GQ3SDRL6.mjs.map → chunk-QC6VQ2IW.mjs.map} +1 -1
  125. package/dist/{chunk-D47W5DE4.js → chunk-QF3XTEXV.js} +4 -4
  126. package/dist/{chunk-D47W5DE4.js.map → chunk-QF3XTEXV.js.map} +1 -1
  127. package/dist/{chunk-2YSB4FIC.mjs → chunk-RGCUND5Q.mjs} +4 -4
  128. package/dist/{chunk-2YSB4FIC.mjs.map → chunk-RGCUND5Q.mjs.map} +1 -1
  129. package/dist/{chunk-N6CB7MK7.js → chunk-RVFOUPK4.js} +6 -6
  130. package/dist/{chunk-N6CB7MK7.js.map → chunk-RVFOUPK4.js.map} +1 -1
  131. package/dist/{chunk-WDEGGHTB.js → chunk-SDGS2R5O.js} +12 -12
  132. package/dist/{chunk-WDEGGHTB.js.map → chunk-SDGS2R5O.js.map} +1 -1
  133. package/dist/{chunk-JMNBU2RG.mjs → chunk-TA3TQTDA.mjs} +8 -8
  134. package/dist/{chunk-JMNBU2RG.mjs.map → chunk-TA3TQTDA.mjs.map} +1 -1
  135. package/dist/{chunk-KA4NNWOK.js → chunk-TMNFPVK5.js} +7 -7
  136. package/dist/{chunk-KA4NNWOK.js.map → chunk-TMNFPVK5.js.map} +1 -1
  137. package/dist/{chunk-254IW4FC.js → chunk-VK74LC4H.js} +5 -5
  138. package/dist/{chunk-254IW4FC.js.map → chunk-VK74LC4H.js.map} +1 -1
  139. package/dist/{chunk-7TKSRUQU.mjs → chunk-XGELGOF6.mjs} +7 -7
  140. package/dist/{chunk-7TKSRUQU.mjs.map → chunk-XGELGOF6.mjs.map} +1 -1
  141. package/dist/{chunk-CZGGUPPQ.js → chunk-XKJLJLQ4.js} +74 -61
  142. package/dist/chunk-XKJLJLQ4.js.map +1 -0
  143. package/dist/{chunk-XSBKR3VF.mjs → chunk-XOYQKFKI.mjs} +4 -4
  144. package/dist/{chunk-XSBKR3VF.mjs.map → chunk-XOYQKFKI.mjs.map} +1 -1
  145. package/dist/{chunk-MIYGP34I.js → chunk-Y53BIB7A.js} +14 -14
  146. package/dist/{chunk-MIYGP34I.js.map → chunk-Y53BIB7A.js.map} +1 -1
  147. package/dist/{chunk-QVBAAPNT.mjs → chunk-YKNXBWPZ.mjs} +3 -3
  148. package/dist/{chunk-QVBAAPNT.mjs.map → chunk-YKNXBWPZ.mjs.map} +1 -1
  149. package/dist/{chunk-HOOVYWTO.mjs → chunk-YP5WAFTI.mjs} +4 -4
  150. package/dist/{chunk-HOOVYWTO.mjs.map → chunk-YP5WAFTI.mjs.map} +1 -1
  151. package/dist/{chunk-SCRB5DZM.js → chunk-YS7Y2PQG.js} +8 -8
  152. package/dist/{chunk-SCRB5DZM.js.map → chunk-YS7Y2PQG.js.map} +1 -1
  153. package/dist/{chunk-3GHPFLEH.js → chunk-ZQJGCQHC.js} +15 -15
  154. package/dist/{chunk-3GHPFLEH.js.map → chunk-ZQJGCQHC.js.map} +1 -1
  155. package/dist/{chunk-QEM2F2DC.mjs → chunk-ZQSJK65K.mjs} +3 -3
  156. package/dist/{chunk-QEM2F2DC.mjs.map → chunk-ZQSJK65K.mjs.map} +1 -1
  157. package/dist/cli/index.js +3 -3
  158. package/dist/cli/index.mjs +1 -1
  159. package/dist/client/index.js +4 -4
  160. package/dist/client/index.mjs +3 -3
  161. package/dist/commerce/index.js +57 -57
  162. package/dist/commerce/index.mjs +5 -5
  163. package/dist/cta-bar/CtaBar.d.ts +71 -0
  164. package/dist/cta-bar/CtaBar.d.ts.map +1 -0
  165. package/dist/cta-bar/CtaBarBehavior.d.ts +46 -0
  166. package/dist/cta-bar/CtaBarBehavior.d.ts.map +1 -0
  167. package/dist/cta-bar/client.d.ts +46 -0
  168. package/dist/cta-bar/client.d.ts.map +1 -0
  169. package/dist/cta-bar/client.js +23 -0
  170. package/dist/cta-bar/client.js.map +1 -0
  171. package/dist/cta-bar/client.mjs +6 -0
  172. package/dist/cta-bar/client.mjs.map +1 -0
  173. package/dist/cta-bar/index.d.ts +12 -0
  174. package/dist/cta-bar/index.d.ts.map +1 -0
  175. package/dist/cta-bar/index.js +230 -0
  176. package/dist/cta-bar/index.js.map +1 -0
  177. package/dist/cta-bar/index.mjs +224 -0
  178. package/dist/cta-bar/index.mjs.map +1 -0
  179. package/dist/cta-bar/styles.d.ts +46 -0
  180. package/dist/cta-bar/styles.d.ts.map +1 -0
  181. package/dist/engage/ChatWidget.d.ts.map +1 -1
  182. package/dist/engage/EchoUiActions.d.ts.map +1 -1
  183. package/dist/engage/index.js +14 -13
  184. package/dist/engage/index.js.map +1 -1
  185. package/dist/engage/index.mjs +8 -7
  186. package/dist/engage/index.mjs.map +1 -1
  187. package/dist/fleet/index.js +8 -8
  188. package/dist/fleet/index.mjs +4 -4
  189. package/dist/forms/index.js +22 -22
  190. package/dist/forms/index.mjs +9 -9
  191. package/dist/forms/server.js +10 -10
  192. package/dist/forms/server.mjs +8 -8
  193. package/dist/forms/static.js +7 -7
  194. package/dist/forms/static.mjs +6 -6
  195. package/dist/images/index.js +11 -11
  196. package/dist/images/index.mjs +4 -4
  197. package/dist/index.js +63 -63
  198. package/dist/index.mjs +9 -9
  199. package/dist/layout/client.js +8 -8
  200. package/dist/layout/client.mjs +7 -7
  201. package/dist/layout/index.js +10 -10
  202. package/dist/layout/index.mjs +8 -8
  203. package/dist/llms/index.js +12 -12
  204. package/dist/llms/index.mjs +2 -2
  205. package/dist/llms/writeLLMsTxt.d.ts +6 -0
  206. package/dist/llms/writeLLMsTxt.d.ts.map +1 -1
  207. package/dist/maps/index.js +5 -5
  208. package/dist/maps/index.mjs +3 -3
  209. package/dist/search/index.js +4 -4
  210. package/dist/search/index.mjs +3 -3
  211. package/dist/seo/client.js +5 -5
  212. package/dist/seo/client.mjs +4 -4
  213. package/dist/seo/index.js +5 -5
  214. package/dist/seo/index.mjs +4 -4
  215. package/dist/seo/register-sitemap-cli-impl.d.ts +2 -0
  216. package/dist/seo/register-sitemap-cli-impl.d.ts.map +1 -1
  217. package/dist/seo/register-sitemap-cli.d.ts +1 -0
  218. package/dist/seo/register-sitemap-cli.d.ts.map +1 -1
  219. package/dist/seo/register-sitemap-cli.js +7 -3
  220. package/dist/seo/register-sitemap-cli.mjs +7 -3
  221. package/dist/server/index.js +3 -3
  222. package/dist/server/index.mjs +2 -2
  223. package/dist/shared/build-entries.d.ts +4 -1
  224. package/dist/shared/build-entries.d.ts.map +1 -1
  225. package/dist/shared/glass.d.ts +51 -0
  226. package/dist/shared/glass.d.ts.map +1 -0
  227. package/dist/shared/version.d.ts +1 -1
  228. package/dist/signal/index.js +11 -11
  229. package/dist/signal/index.mjs +2 -2
  230. package/dist/sitemap/index.d.ts +6 -0
  231. package/dist/sitemap/index.d.ts.map +1 -1
  232. package/dist/sitemap/index.js +3 -2
  233. package/dist/sitemap/index.js.map +1 -1
  234. package/dist/sitemap/index.mjs +2 -1
  235. package/dist/sitemap/index.mjs.map +1 -1
  236. package/dist/sync/index.js +17 -17
  237. package/dist/sync/index.mjs +4 -4
  238. package/dist/{writeLLMsTxt-QJFXBHZF.mjs → writeLLMsTxt-LYYC3ZSN.mjs} +2 -2
  239. package/dist/{writeLLMsTxt-ATADOUVZ.js → writeLLMsTxt-XHLHJ5XY.js} +3 -3
  240. package/package.json +6 -1
  241. package/skills/site-kit/SKILL.md +6 -0
  242. package/dist/ChatWidget-6626OPXO.mjs +0 -15
  243. package/dist/ChatWidget-U24AYLXF.js +0 -24
  244. package/dist/EngageWidget-TR47W2ZI.mjs +0 -12
  245. package/dist/EngageWidget-XUTDFRF3.js +0 -21
  246. package/dist/ManagedForm-5675CLWS.mjs +0 -16
  247. package/dist/ManagedForm-KYIK54SL.js +0 -25
  248. package/dist/SitemapSync-PKBXWVI6.mjs +0 -9
  249. package/dist/SitemapSync-PZ76V5MX.js +0 -18
  250. package/dist/chunk-2KRAY5NC.mjs +0 -6
  251. package/dist/chunk-CZGGUPPQ.js.map +0 -1
  252. package/dist/chunk-EL74YDNX.js +0 -8
  253. package/dist/chunk-G6KQ3C3W.js.map +0 -1
  254. package/dist/chunk-RDPI27TS.mjs.map +0 -1
  255. package/dist/chunk-XKXZ4OW4.mjs.map +0 -1
@@ -0,0 +1,132 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var chunk3DWIYCQX_js = require('./chunk-3DWIYCQX.js');
5
+ var react = require('react');
6
+ var navigation = require('next/navigation');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ var DIRECTION_THRESHOLD = 8;
10
+ var TOP_ZONE = 80;
11
+ function nextCompactState(state, y) {
12
+ if (y <= TOP_ZONE) return { compact: false, anchorY: y };
13
+ const delta = y - state.anchorY;
14
+ if (Math.abs(delta) < DIRECTION_THRESHOLD) return state;
15
+ return { compact: delta > 0, anchorY: y };
16
+ }
17
+ var NON_TEXT_INPUTS = /* @__PURE__ */ new Set(["button", "checkbox", "color", "file", "hidden", "image", "radio", "range", "reset", "submit"]);
18
+ function isTextEntry(el) {
19
+ if (!el) return false;
20
+ const tag = el.tagName;
21
+ if (tag === "TEXTAREA" || tag === "SELECT") return true;
22
+ if (el.isContentEditable) return true;
23
+ if (tag === "INPUT") return !NON_TEXT_INPUTS.has((el.type || "text").toLowerCase());
24
+ return false;
25
+ }
26
+ function setFlag(el, name, on) {
27
+ if (on) {
28
+ if (!el.hasAttribute(name)) el.setAttribute(name, "");
29
+ } else if (el.hasAttribute(name)) {
30
+ el.removeAttribute(name);
31
+ }
32
+ }
33
+ function CtaBarBehavior({ showAfter, hideOver, hideWhileTyping, compactOnScroll, track }) {
34
+ const anchorRef = react.useRef(null);
35
+ const pathname = navigation.usePathname();
36
+ const hideOverKey = (hideOver ?? []).join("\n");
37
+ react.useEffect(() => {
38
+ const bar = anchorRef.current?.closest("[data-sk-cta-bar]");
39
+ if (!bar) return;
40
+ const state = { beforeStart: false, overTarget: false, typing: false };
41
+ const sync = () => setFlag(bar, "data-hidden", state.beforeStart || state.overTarget || state.typing);
42
+ const cleanups = [];
43
+ const start = showAfter ? document.querySelector(showAfter) : null;
44
+ if (start && "IntersectionObserver" in window) {
45
+ state.beforeStart = true;
46
+ const io = new IntersectionObserver(([entry]) => {
47
+ state.beforeStart = entry.isIntersecting || entry.boundingClientRect.top > 0;
48
+ sync();
49
+ });
50
+ io.observe(start);
51
+ cleanups.push(() => io.disconnect());
52
+ }
53
+ const targets = hideOverKey ? hideOverKey.split("\n").flatMap((sel) => Array.from(document.querySelectorAll(sel))) : [];
54
+ if (targets.length && "IntersectionObserver" in window) {
55
+ const showing = /* @__PURE__ */ new Set();
56
+ const io = new IntersectionObserver((entries) => {
57
+ for (const e of entries) {
58
+ if (e.isIntersecting) showing.add(e.target);
59
+ else showing.delete(e.target);
60
+ }
61
+ state.overTarget = showing.size > 0;
62
+ sync();
63
+ });
64
+ targets.forEach((t) => io.observe(t));
65
+ cleanups.push(() => io.disconnect());
66
+ }
67
+ if (hideWhileTyping) {
68
+ const onFocusIn = (e) => {
69
+ state.typing = isTextEntry(e.target);
70
+ sync();
71
+ };
72
+ const onFocusOut = () => {
73
+ queueMicrotask(() => {
74
+ state.typing = isTextEntry(document.activeElement);
75
+ sync();
76
+ });
77
+ };
78
+ document.addEventListener("focusin", onFocusIn);
79
+ document.addEventListener("focusout", onFocusOut);
80
+ cleanups.push(() => {
81
+ document.removeEventListener("focusin", onFocusIn);
82
+ document.removeEventListener("focusout", onFocusOut);
83
+ });
84
+ }
85
+ if (compactOnScroll) {
86
+ let compactState = { compact: false, anchorY: window.scrollY };
87
+ let frame = 0;
88
+ const onScroll = () => {
89
+ if (frame) return;
90
+ frame = requestAnimationFrame(() => {
91
+ frame = 0;
92
+ compactState = nextCompactState(compactState, window.scrollY);
93
+ setFlag(bar, "data-compact", compactState.compact);
94
+ });
95
+ };
96
+ window.addEventListener("scroll", onScroll, { passive: true });
97
+ cleanups.push(() => {
98
+ window.removeEventListener("scroll", onScroll);
99
+ if (frame) cancelAnimationFrame(frame);
100
+ setFlag(bar, "data-compact", false);
101
+ });
102
+ }
103
+ if (track) {
104
+ const onClick = (e) => {
105
+ const action = e.target?.closest(".sk-cta-bar__action");
106
+ if (!action || !bar.contains(action)) return;
107
+ chunk3DWIYCQX_js.trackEvent({
108
+ name: "cta_click",
109
+ category: "engagement",
110
+ label: action.textContent?.trim() || void 0,
111
+ properties: {
112
+ location: "cta_bar",
113
+ href: action.getAttribute("href") ?? void 0,
114
+ variant: action.getAttribute("data-variant") ?? void 0,
115
+ compact: bar.hasAttribute("data-compact")
116
+ }
117
+ });
118
+ };
119
+ bar.addEventListener("click", onClick);
120
+ cleanups.push(() => bar.removeEventListener("click", onClick));
121
+ }
122
+ sync();
123
+ return () => cleanups.forEach((fn) => fn());
124
+ }, [pathname, showAfter, hideOverKey, hideWhileTyping, compactOnScroll, track]);
125
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { ref: anchorRef, hidden: true });
126
+ }
127
+
128
+ exports.CtaBarBehavior = CtaBarBehavior;
129
+ exports.isTextEntry = isTextEntry;
130
+ exports.nextCompactState = nextCompactState;
131
+ //# sourceMappingURL=chunk-IWSN4DGG.js.map
132
+ //# sourceMappingURL=chunk-IWSN4DGG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cta-bar/CtaBarBehavior.tsx"],"names":["useRef","usePathname","useEffect","trackEvent","jsx"],"mappings":"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","file":"chunk-IWSN4DGG.js","sourcesContent":["/**\n * @sonordev/site-kit/cta-bar — behaviour island\n *\n * Childless. It renders one hidden <span> so it can find the bar it sits in,\n * then drives that bar entirely through data attributes the stylesheet reads:\n *\n * data-hidden off screen: before `showAfter` has scrolled away, while\n * a `hideOver` target is on screen, or while a text field\n * has focus (the keyboard is up and the bar would sit on it)\n * data-compact scrolling down: the bar tightens and icon-bearing\n * secondary actions fold to icons. Scrolling up restores it.\n *\n * Nothing here re-renders React. The bar is server-rendered markup and the\n * island only flips attributes, so a server layout can hand the bar Next\n * <Link> children and none of it crosses a client boundary.\n *\n * Scroll work is one passive listener coalesced to a frame; visibility is\n * IntersectionObserver, so there is no per-frame layout read for it.\n */\n\n'use client'\n\nimport { useEffect, useRef } from 'react'\nimport { usePathname } from 'next/navigation'\nimport { trackEvent } from '../analytics/dispatch'\n\nexport interface CtaBarBehaviorProps {\n showAfter?: string\n hideOver?: string[]\n hideWhileTyping: boolean\n compactOnScroll: boolean\n track: boolean\n}\n\n/** Scroll distance (px) that has to accumulate before the bar changes shape. */\nconst DIRECTION_THRESHOLD = 8\n/** Near the top of the page the bar is always full size. */\nconst TOP_ZONE = 80\n\n/**\n * Scroll-direction state for compact mode. Pure, so it is tested without a\n * DOM. `anchorY` only moves once a change is committed, so slow scrolling\n * still accumulates past the threshold instead of resetting every frame.\n */\nexport function nextCompactState(\n state: { compact: boolean; anchorY: number },\n y: number,\n): { compact: boolean; anchorY: number } {\n if (y <= TOP_ZONE) return { compact: false, anchorY: y }\n const delta = y - state.anchorY\n if (Math.abs(delta) < DIRECTION_THRESHOLD) return state\n return { compact: delta > 0, anchorY: y }\n}\n\nconst NON_TEXT_INPUTS = new Set(['button', 'checkbox', 'color', 'file', 'hidden', 'image', 'radio', 'range', 'reset', 'submit'])\n\n/**\n * Focus targets that raise an on-screen keyboard. Checks tag names rather\n * than `instanceof`, which fails for elements from another realm (an iframe\n * form) and can't run where there is no DOM.\n */\nexport function isTextEntry(el: Pick<Element, 'tagName'> | null): boolean {\n if (!el) return false\n const tag = el.tagName\n if (tag === 'TEXTAREA' || tag === 'SELECT') return true\n if ((el as HTMLElement).isContentEditable) return true\n if (tag === 'INPUT') return !NON_TEXT_INPUTS.has(((el as HTMLInputElement).type || 'text').toLowerCase())\n return false\n}\n\nfunction setFlag(el: HTMLElement, name: string, on: boolean) {\n if (on) {\n if (!el.hasAttribute(name)) el.setAttribute(name, '')\n } else if (el.hasAttribute(name)) {\n el.removeAttribute(name)\n }\n}\n\nexport function CtaBarBehavior({ showAfter, hideOver, hideWhileTyping, compactOnScroll, track }: CtaBarBehaviorProps) {\n const anchorRef = useRef<HTMLSpanElement>(null)\n const pathname = usePathname()\n // Arrays from a server component arrive as a fresh object every render;\n // key the effect on their content, not their identity.\n const hideOverKey = (hideOver ?? []).join('\\n')\n\n useEffect(() => {\n const bar = anchorRef.current?.closest<HTMLElement>('[data-sk-cta-bar]')\n if (!bar) return\n\n const state = { beforeStart: false, overTarget: false, typing: false }\n const sync = () => setFlag(bar, 'data-hidden', state.beforeStart || state.overTarget || state.typing)\n const cleanups: Array<() => void> = []\n\n // showAfter: hidden until the element has scrolled off the top.\n const start = showAfter ? document.querySelector(showAfter) : null\n if (start && 'IntersectionObserver' in window) {\n state.beforeStart = true\n const io = new IntersectionObserver(([entry]) => {\n state.beforeStart = entry.isIntersecting || entry.boundingClientRect.top > 0\n sync()\n })\n io.observe(start)\n cleanups.push(() => io.disconnect())\n }\n\n // hideOver: hidden while any target is on screen.\n const targets = hideOverKey\n ? hideOverKey.split('\\n').flatMap((sel) => Array.from(document.querySelectorAll(sel)))\n : []\n if (targets.length && 'IntersectionObserver' in window) {\n const showing = new Set<Element>()\n const io = new IntersectionObserver((entries) => {\n for (const e of entries) {\n if (e.isIntersecting) showing.add(e.target)\n else showing.delete(e.target)\n }\n state.overTarget = showing.size > 0\n sync()\n })\n targets.forEach((t) => io.observe(t))\n cleanups.push(() => io.disconnect())\n }\n\n if (hideWhileTyping) {\n const onFocusIn = (e: FocusEvent) => {\n state.typing = isTextEntry(e.target as Element)\n sync()\n }\n const onFocusOut = () => {\n // relatedTarget is null for many focus moves; read where focus\n // actually landed once the browser has settled it.\n queueMicrotask(() => {\n state.typing = isTextEntry(document.activeElement)\n sync()\n })\n }\n document.addEventListener('focusin', onFocusIn)\n document.addEventListener('focusout', onFocusOut)\n cleanups.push(() => {\n document.removeEventListener('focusin', onFocusIn)\n document.removeEventListener('focusout', onFocusOut)\n })\n }\n\n if (compactOnScroll) {\n let compactState = { compact: false, anchorY: window.scrollY }\n let frame = 0\n const onScroll = () => {\n if (frame) return\n frame = requestAnimationFrame(() => {\n frame = 0\n compactState = nextCompactState(compactState, window.scrollY)\n setFlag(bar, 'data-compact', compactState.compact)\n })\n }\n window.addEventListener('scroll', onScroll, { passive: true })\n cleanups.push(() => {\n window.removeEventListener('scroll', onScroll)\n if (frame) cancelAnimationFrame(frame)\n setFlag(bar, 'data-compact', false)\n })\n }\n\n if (track) {\n const onClick = (e: MouseEvent) => {\n const action = (e.target as Element | null)?.closest<HTMLElement>('.sk-cta-bar__action')\n if (!action || !bar.contains(action)) return\n trackEvent({\n name: 'cta_click',\n category: 'engagement',\n label: action.textContent?.trim() || undefined,\n properties: {\n location: 'cta_bar',\n href: action.getAttribute('href') ?? undefined,\n variant: action.getAttribute('data-variant') ?? undefined,\n compact: bar.hasAttribute('data-compact'),\n },\n })\n }\n bar.addEventListener('click', onClick)\n cleanups.push(() => bar.removeEventListener('click', onClick))\n }\n\n sync()\n return () => cleanups.forEach((fn) => fn())\n // pathname: a client navigation swaps the page under a persistent layout,\n // so the start element and hideOver targets have to be found again.\n }, [pathname, showAfter, hideOverKey, hideWhileTyping, compactOnScroll, track])\n\n return <span ref={anchorRef} hidden />\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunk3GHPFLEH_js = require('./chunk-3GHPFLEH.js');
4
+ var chunkZQJGCQHC_js = require('./chunk-ZQJGCQHC.js');
5
5
  var react = require('react');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
7
 
@@ -40,7 +40,7 @@ function ManagedImage({
40
40
  }
41
41
  try {
42
42
  const params = new URLSearchParams({ page_path: currentPath });
43
- const res = await chunk3GHPFLEH_js.sonorFetch(
43
+ const res = await chunkZQJGCQHC_js.sonorFetch(
44
44
  `${apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,
45
45
  { headers: { "Content-Type": "application/json" } },
46
46
  { apiKey }
@@ -214,7 +214,7 @@ function ImagePickerModal({
214
214
  const params = new URLSearchParams();
215
215
  if (currentFolder) params.set("folder", currentFolder);
216
216
  if (search) params.set("search", search);
217
- const res = await chunk3GHPFLEH_js.sonorFetch(
217
+ const res = await chunkZQJGCQHC_js.sonorFetch(
218
218
  `${config.apiUrl}/public/images/files?${params}`,
219
219
  { headers: { "Content-Type": "application/json" } },
220
220
  { apiKey: config.apiKey }
@@ -236,7 +236,7 @@ function ImagePickerModal({
236
236
  const handleSelectFile = async (file) => {
237
237
  if (!config?.apiKey || !config?.apiUrl) return;
238
238
  try {
239
- const res = await chunk3GHPFLEH_js.sonorFetch(
239
+ const res = await chunkZQJGCQHC_js.sonorFetch(
240
240
  `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,
241
241
  {
242
242
  method: "POST",
@@ -267,7 +267,7 @@ function ImagePickerModal({
267
267
  formData.append("page_path", pagePath);
268
268
  formData.append("folder", currentFolder || "Website/Images");
269
269
  if (altText) formData.append("alt_text", altText);
270
- const res = await chunk3GHPFLEH_js.sonorFetch(`${config.apiUrl}/public/images/upload`, {
270
+ const res = await chunkZQJGCQHC_js.sonorFetch(`${config.apiUrl}/public/images/upload`, {
271
271
  method: "POST",
272
272
  body: formData
273
273
  }, { apiKey: config.apiKey, retries: 0, timeoutMs: 6e4 });
@@ -284,7 +284,7 @@ function ImagePickerModal({
284
284
  if (!config?.apiKey || !config?.apiUrl) return;
285
285
  try {
286
286
  const params = new URLSearchParams({ page_path: pagePath });
287
- await chunk3GHPFLEH_js.sonorFetch(
287
+ await chunkZQJGCQHC_js.sonorFetch(
288
288
  `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,
289
289
  { method: "DELETE" },
290
290
  { apiKey: config.apiKey, retries: 0 }
@@ -428,7 +428,7 @@ function ImagePickerModal({
428
428
  async function fetchManagedImage(config, slotId, pagePath) {
429
429
  const params = new URLSearchParams();
430
430
  if (pagePath) params.set("page_path", pagePath);
431
- const res = await chunk3GHPFLEH_js.sonorFetch(
431
+ const res = await chunkZQJGCQHC_js.sonorFetch(
432
432
  `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,
433
433
  { headers: { "Content-Type": "application/json" } },
434
434
  { apiKey: config.apiKey }
@@ -443,7 +443,7 @@ async function fetchManagedImages(config, options) {
443
443
  if (options?.pagePath) params.set("page_path", options.pagePath);
444
444
  if (options?.category) params.set("category", options.category);
445
445
  if (options?.includePlaceholders) params.set("include_placeholders", "true");
446
- const res = await chunk3GHPFLEH_js.sonorFetch(
446
+ const res = await chunkZQJGCQHC_js.sonorFetch(
447
447
  `${config.apiUrl}/public/images?${params}`,
448
448
  { headers: { "Content-Type": "application/json" } },
449
449
  { apiKey: config.apiKey }
@@ -457,7 +457,7 @@ async function listImageFiles(config, options) {
457
457
  const params = new URLSearchParams();
458
458
  if (options?.folder) params.set("folder", options.folder);
459
459
  if (options?.search) params.set("search", options.search);
460
- const res = await chunk3GHPFLEH_js.sonorFetch(
460
+ const res = await chunkZQJGCQHC_js.sonorFetch(
461
461
  `${config.apiUrl}/public/images/files?${params}`,
462
462
  { headers: { "Content-Type": "application/json" } },
463
463
  { apiKey: config.apiKey }
@@ -474,7 +474,7 @@ async function uploadImage(config, file, options) {
474
474
  if (options?.pagePath) formData.append("page_path", options.pagePath);
475
475
  if (options?.folder) formData.append("folder", options.folder);
476
476
  if (options?.altText) formData.append("alt_text", options.altText);
477
- const res = await chunk3GHPFLEH_js.sonorFetch(`${config.apiUrl}/public/images/upload`, {
477
+ const res = await chunkZQJGCQHC_js.sonorFetch(`${config.apiUrl}/public/images/upload`, {
478
478
  method: "POST",
479
479
  body: formData
480
480
  }, { apiKey: config.apiKey, retries: 0, timeoutMs: 6e4 });
@@ -484,7 +484,7 @@ async function uploadImage(config, file, options) {
484
484
  return res.json();
485
485
  }
486
486
  async function assignImageToSlot(config, slotId, options) {
487
- const res = await chunk3GHPFLEH_js.sonorFetch(
487
+ const res = await chunkZQJGCQHC_js.sonorFetch(
488
488
  `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,
489
489
  {
490
490
  method: "POST",
@@ -511,7 +511,7 @@ async function assignImageToSlot(config, slotId, options) {
511
511
  async function clearImageSlot(config, slotId, pagePath) {
512
512
  const params = new URLSearchParams();
513
513
  if (pagePath) params.set("page_path", pagePath);
514
- const res = await chunk3GHPFLEH_js.sonorFetch(
514
+ const res = await chunkZQJGCQHC_js.sonorFetch(
515
515
  `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,
516
516
  { method: "DELETE" },
517
517
  { apiKey: config.apiKey, retries: 0 }
@@ -529,5 +529,5 @@ exports.fetchManagedImage = fetchManagedImage;
529
529
  exports.fetchManagedImages = fetchManagedImages;
530
530
  exports.listImageFiles = listImageFiles;
531
531
  exports.uploadImage = uploadImage;
532
- //# sourceMappingURL=chunk-BZG34WHF.js.map
533
- //# sourceMappingURL=chunk-BZG34WHF.js.map
532
+ //# sourceMappingURL=chunk-K4LLYQFZ.js.map
533
+ //# sourceMappingURL=chunk-K4LLYQFZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/images/ManagedImage.tsx","../src/images/api.ts"],"names":["useState","useCallback","sonorFetch","useEffect","jsx","jsxs"],"mappings":"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","file":"chunk-BZG34WHF.js","sourcesContent":["/**\n * ManagedImage - Portal-managed image component\n * \n * Features:\n * - Fetches images from Portal API via API key (never direct Supabase)\n * - Dev mode: Click to open image picker modal\n * - Supports responsive variants\n * - Automatic focal point handling\n * - Placeholder state for empty slots\n * \n * @example\n * ```tsx\n * <ManagedImage \n * slotId=\"hero-background\"\n * alt=\"Hero background image\"\n * className=\"w-full h-96 object-cover\"\n * />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ManagedImageData {\n id: string\n slot_id: string\n page_path: string | null\n file_id: string | null\n external_url: string | null\n alt_text: string | null\n title: string | null\n caption: string | null\n focal_point_x: number\n focal_point_y: number\n aspect_ratio: string | null\n public_url?: string\n is_placeholder: boolean\n}\n\nexport interface ImageFile {\n id: string\n filename: string\n storage_path: string\n mime_type: string\n file_size: number\n folder_path: string | null\n public_url?: string\n}\n\nexport interface ManagedImageProps {\n /** API key for Portal API */\n apiKey?: string\n /** API URL (defaults to https://api.sonor.io) */\n apiUrl?: string\n /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */\n slotId: string\n /** Page path for page-specific slots (defaults to current path) */\n pagePath?: string\n /** Fallback alt text if not set in Portal */\n alt?: string\n /** CSS class names */\n className?: string\n /** Image width */\n width?: number | string\n /** Image height */\n height?: number | string\n /** CSS object-fit property */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** Fallback image URL when no image assigned */\n fallback?: string\n /** Custom placeholder component */\n placeholder?: React.ReactNode\n /** Called when image loads */\n onLoad?: () => void\n /** Called on error */\n onError?: (error: Error) => void\n /** Priority loading (Next.js Image optimization) */\n priority?: boolean\n /** Additional styles */\n style?: React.CSSProperties\n /** Enable dev picker even outside dev mode */\n forceDevMode?: boolean\n}\n\n// Check if we're in dev mode. `?sonor_dev=true` opens the picker on any host.\n// (The Uptrade-era `uptrade_dev` param is gone: nothing in the workspace sent it.)\nconst isDevMode = (): boolean => {\n if (typeof window === 'undefined') return false\n return (\n process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n new URLSearchParams(window.location.search).get('sonor_dev') === 'true'\n )\n}\n\nexport function ManagedImage({\n apiKey = process.env.SONOR_API_KEY,\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n slotId,\n pagePath,\n alt,\n className = '',\n width,\n height,\n objectFit = 'cover',\n fallback,\n placeholder,\n onLoad,\n onError,\n priority,\n style,\n forceDevMode,\n}: ManagedImageProps) {\n const [imageData, setImageData] = useState<ManagedImageData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n const [showPicker, setShowPicker] = useState(false)\n const [devMode] = useState(() => forceDevMode || isDevMode())\n\n // Get current page path if not provided\n const currentPath = pagePath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n // Fetch image data from Portal API\n const fetchImage = useCallback(async () => {\n if (!apiKey || !apiUrl) {\n setLoading(false)\n return\n }\n\n try {\n const params = new URLSearchParams({ page_path: currentPath })\n const res = await sonorFetch(\n `${apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n const data = await res.json()\n setImageData(data.image)\n setError(null)\n } catch (err) {\n // warn, not error: a failed slot fetch must not fail the Lighthouse\n // best-practices errors-in-console audit on every page using this slot.\n console.warn('[ManagedImage] Fetch error:', err)\n setError(err instanceof Error ? err : new Error(String(err)))\n onError?.(err instanceof Error ? err : new Error(String(err)))\n } finally {\n setLoading(false)\n }\n }, [apiKey, apiUrl, slotId, currentPath, onError])\n\n useEffect(() => {\n fetchImage()\n }, [fetchImage])\n\n // Calculate object-position from focal point\n const objectPosition = imageData\n ? `${imageData.focal_point_x}% ${imageData.focal_point_y}%`\n : '50% 50%'\n\n // Get the image URL\n const imageUrl = imageData?.public_url || imageData?.external_url || fallback\n\n // Handle click in dev mode\n const handleClick = (e: React.MouseEvent) => {\n if (devMode) {\n e.preventDefault()\n e.stopPropagation()\n setShowPicker(true)\n }\n }\n\n // Render placeholder state\n if (loading) {\n return (\n <div\n className={`bg-gray-200 animate-pulse ${className}`}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n />\n )\n }\n\n // No image assigned - show placeholder or dev picker hint\n if (!imageUrl) {\n if (placeholder) {\n return <>{placeholder}</>\n }\n\n return (\n <div\n onClick={handleClick}\n className={`\n bg-gray-100 border-2 border-dashed border-gray-300 \n flex items-center justify-center text-gray-400\n ${devMode ? 'cursor-pointer hover:border-blue-400 hover:text-blue-500 hover:bg-blue-50' : ''}\n ${className}\n `}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n title={devMode ? `Click to add image for slot: ${slotId}` : undefined}\n >\n <div className=\"text-center p-4\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n {devMode && (\n <p className=\"text-sm font-medium\">Click to add image</p>\n )}\n <p className=\"text-xs mt-1\">{slotId}</p>\n </div>\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n }\n\n // Render the image\n return (\n <div className=\"relative\" style={{ width, height }}>\n <img\n src={imageUrl}\n alt={imageData?.alt_text || alt || ''}\n title={imageData?.title || undefined}\n data-managed-image=\"true\"\n data-slot-id={slotId}\n data-page-path={currentPath}\n className={className}\n style={{\n objectFit,\n objectPosition,\n width: width ?? '100%',\n height: height ?? 'auto',\n ...style,\n }}\n onLoad={onLoad}\n onError={() => onError?.(new Error('Image failed to load'))}\n loading={priority ? 'eager' : 'lazy'}\n onClick={handleClick}\n />\n\n {/* Dev mode overlay */}\n {devMode && (\n <div\n className=\"absolute inset-0 bg-black/0 hover:bg-black/30 transition-colors cursor-pointer flex items-center justify-center opacity-0 hover:opacity-100\"\n onClick={handleClick}\n >\n <div className=\"bg-white/90 px-3 py-1.5 rounded-lg shadow-lg text-sm font-medium text-gray-700\">\n Edit Image\n </div>\n </div>\n )}\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n currentImage={imageData}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n}\n\n// ============================================================================\n// IMAGE PICKER MODAL\n// ============================================================================\n\ninterface ImagePickerModalProps {\n slotId: string\n pagePath: string\n config: any\n currentImage?: ManagedImageData | null\n onClose: () => void\n onSelect: () => void\n}\n\nfunction ImagePickerModal({\n slotId,\n pagePath,\n config,\n currentImage,\n onClose,\n onSelect,\n}: ImagePickerModalProps) {\n const [files, setFiles] = useState<ImageFile[]>([])\n const [folders, setFolders] = useState<string[]>([])\n const [currentFolder, setCurrentFolder] = useState<string>('')\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(true)\n const [uploading, setUploading] = useState(false)\n const [altText, setAltText] = useState(currentImage?.alt_text || '')\n\n // Fetch available files\n const fetchFiles = useCallback(async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n setLoading(true)\n try {\n const params = new URLSearchParams()\n if (currentFolder) params.set('folder', currentFolder)\n if (search) params.set('search', search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (res.ok) {\n const data = await res.json()\n setFiles(data.files || [])\n setFolders(data.folders || [])\n }\n } catch (err) {\n console.warn('[ImagePicker] Fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [config?.apiKey, config?.apiUrl, currentFolder, search])\n\n useEffect(() => {\n fetchFiles()\n }, [fetchFiles])\n\n // Select an existing file\n const handleSelectFile = async (file: ImageFile) => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: pagePath,\n file_id: file.id,\n alt_text: altText || file.filename,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Select error:', err)\n }\n }\n\n // Upload new file\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file || !config?.apiKey || !config?.apiUrl) return\n\n setUploading(true)\n try {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('slot_id', slotId)\n formData.append('page_path', pagePath)\n formData.append('folder', currentFolder || 'Website/Images')\n if (altText) formData.append('alt_text', altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long\n // timeout, no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Upload error:', err)\n } finally {\n setUploading(false)\n }\n }\n\n // Clear the slot\n const handleClear = async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const params = new URLSearchParams({ page_path: pagePath })\n await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n onSelect()\n } catch (err) {\n console.warn('[ImagePicker] Clear error:', err)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-[99999] bg-black/50 flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <div\n className=\"bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-4 border-b\">\n <div>\n <h2 className=\"text-lg font-semibold\">Select Image</h2>\n <p className=\"text-sm text-gray-500\">Slot: {slotId}</p>\n </div>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 p-2\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-4 overflow-y-auto\" style={{ maxHeight: 'calc(90vh - 180px)' }}>\n {/* Upload & Search */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <input\n type=\"text\"\n placeholder=\"Search images...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n <label className=\"px-4 py-2 bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 text-sm font-medium flex items-center gap-2\">\n {uploading ? 'Uploading...' : 'Upload New'}\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleUpload}\n disabled={uploading}\n className=\"hidden\"\n />\n </label>\n {currentImage?.file_id && (\n <button\n onClick={handleClear}\n className=\"px-4 py-2 border border-red-200 text-red-600 rounded-lg hover:bg-red-50 text-sm\"\n >\n Remove\n </button>\n )}\n </div>\n\n {/* Alt text input */}\n <div className=\"mb-4\">\n <input\n type=\"text\"\n placeholder=\"Alt text for image...\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n\n {/* Folder navigation */}\n {folders.length > 0 && (\n <div className=\"flex gap-2 mb-4 flex-wrap\">\n <button\n onClick={() => setCurrentFolder('')}\n className={`px-3 py-1 text-sm rounded-full ${\n !currentFolder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n All\n </button>\n {folders.map((folder) => (\n <button\n key={folder}\n onClick={() => setCurrentFolder(folder)}\n className={`px-3 py-1 text-sm rounded-full ${\n currentFolder === folder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n {folder}\n </button>\n ))}\n </div>\n )}\n\n {/* File grid */}\n {loading ? (\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(8)].map((_, i) => (\n <div key={i} className=\"aspect-square bg-gray-200 rounded-lg animate-pulse\" />\n ))}\n </div>\n ) : files.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500\">\n <p>No images found</p>\n <p className=\"text-sm mt-1\">Upload a new image to get started</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-4 gap-4\">\n {files.map((file) => (\n <button\n key={file.id}\n onClick={() => handleSelectFile(file)}\n className={`\n aspect-square rounded-lg overflow-hidden border-2 transition-all\n hover:border-blue-400 hover:shadow-lg\n ${currentImage?.file_id === file.id ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-200'}\n `}\n >\n <img\n src={file.public_url}\n alt={file.filename}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg text-sm\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ManagedImage\n","/**\n * Images API functions\n * \n * All functions use Portal API with API key authentication.\n * Never makes direct Supabase calls.\n */\n\nimport type { ManagedImageData, ImageFile } from './ManagedImage'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ImageApiConfig {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Fetch a managed image for a specific slot\n */\nexport async function fetchManagedImage(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ image: ManagedImageData | null; is_placeholder: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Fetch all managed images for the project\n */\nexport async function fetchManagedImages(\n config: ImageApiConfig,\n options?: {\n pagePath?: string\n category?: string\n includePlaceholders?: boolean\n },\n): Promise<{ images: ManagedImageData[] }> {\n const params = new URLSearchParams()\n if (options?.pagePath) params.set('page_path', options.pagePath)\n if (options?.category) params.set('category', options.category)\n if (options?.includePlaceholders) params.set('include_placeholders', 'true')\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch images: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * List available image files in the project\n */\nexport async function listImageFiles(\n config: ImageApiConfig,\n options?: {\n folder?: string\n search?: string\n },\n): Promise<{ files: ImageFile[]; folders: string[] }> {\n const params = new URLSearchParams()\n if (options?.folder) params.set('folder', options.folder)\n if (options?.search) params.set('search', options.search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to list files: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Upload a new image\n */\nexport async function uploadImage(\n config: ImageApiConfig,\n file: File,\n options?: {\n slotId?: string\n pagePath?: string\n folder?: string\n altText?: string\n },\n): Promise<{ file: ImageFile; image?: ManagedImageData }> {\n const formData = new FormData()\n formData.append('file', file)\n if (options?.slotId) formData.append('slot_id', options.slotId)\n if (options?.pagePath) formData.append('page_path', options.pagePath)\n if (options?.folder) formData.append('folder', options.folder)\n if (options?.altText) formData.append('alt_text', options.altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long timeout,\n // no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (!res.ok) {\n throw new Error(`Failed to upload image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Assign an existing file to an image slot\n */\nexport async function assignImageToSlot(\n config: ImageApiConfig,\n slotId: string,\n options: {\n fileId?: string\n externalUrl?: string\n pagePath?: string\n altText?: string\n title?: string\n caption?: string\n focalPointX?: number\n focalPointY?: number\n aspectRatio?: string\n },\n): Promise<{ image: ManagedImageData }> {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: options.pagePath,\n file_id: options.fileId,\n external_url: options.externalUrl,\n alt_text: options.altText,\n title: options.title,\n caption: options.caption,\n focal_point_x: options.focalPointX,\n focal_point_y: options.focalPointY,\n aspect_ratio: options.aspectRatio,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to assign image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Clear an image from a slot (keeps the file)\n */\nexport async function clearImageSlot(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ success: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to clear slot: ${res.status}`)\n }\n\n return res.json()\n}\n"]}
1
+ {"version":3,"sources":["../src/images/ManagedImage.tsx","../src/images/api.ts"],"names":["useState","useCallback","sonorFetch","useEffect","jsx","jsxs"],"mappings":"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","file":"chunk-K4LLYQFZ.js","sourcesContent":["/**\n * ManagedImage - Portal-managed image component\n * \n * Features:\n * - Fetches images from Portal API via API key (never direct Supabase)\n * - Dev mode: Click to open image picker modal\n * - Supports responsive variants\n * - Automatic focal point handling\n * - Placeholder state for empty slots\n * \n * @example\n * ```tsx\n * <ManagedImage \n * slotId=\"hero-background\"\n * alt=\"Hero background image\"\n * className=\"w-full h-96 object-cover\"\n * />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ManagedImageData {\n id: string\n slot_id: string\n page_path: string | null\n file_id: string | null\n external_url: string | null\n alt_text: string | null\n title: string | null\n caption: string | null\n focal_point_x: number\n focal_point_y: number\n aspect_ratio: string | null\n public_url?: string\n is_placeholder: boolean\n}\n\nexport interface ImageFile {\n id: string\n filename: string\n storage_path: string\n mime_type: string\n file_size: number\n folder_path: string | null\n public_url?: string\n}\n\nexport interface ManagedImageProps {\n /** API key for Portal API */\n apiKey?: string\n /** API URL (defaults to https://api.sonor.io) */\n apiUrl?: string\n /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */\n slotId: string\n /** Page path for page-specific slots (defaults to current path) */\n pagePath?: string\n /** Fallback alt text if not set in Portal */\n alt?: string\n /** CSS class names */\n className?: string\n /** Image width */\n width?: number | string\n /** Image height */\n height?: number | string\n /** CSS object-fit property */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** Fallback image URL when no image assigned */\n fallback?: string\n /** Custom placeholder component */\n placeholder?: React.ReactNode\n /** Called when image loads */\n onLoad?: () => void\n /** Called on error */\n onError?: (error: Error) => void\n /** Priority loading (Next.js Image optimization) */\n priority?: boolean\n /** Additional styles */\n style?: React.CSSProperties\n /** Enable dev picker even outside dev mode */\n forceDevMode?: boolean\n}\n\n// Check if we're in dev mode. `?sonor_dev=true` opens the picker on any host.\n// (The Uptrade-era `uptrade_dev` param is gone: nothing in the workspace sent it.)\nconst isDevMode = (): boolean => {\n if (typeof window === 'undefined') return false\n return (\n process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n new URLSearchParams(window.location.search).get('sonor_dev') === 'true'\n )\n}\n\nexport function ManagedImage({\n apiKey = process.env.SONOR_API_KEY,\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n slotId,\n pagePath,\n alt,\n className = '',\n width,\n height,\n objectFit = 'cover',\n fallback,\n placeholder,\n onLoad,\n onError,\n priority,\n style,\n forceDevMode,\n}: ManagedImageProps) {\n const [imageData, setImageData] = useState<ManagedImageData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n const [showPicker, setShowPicker] = useState(false)\n const [devMode] = useState(() => forceDevMode || isDevMode())\n\n // Get current page path if not provided\n const currentPath = pagePath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n // Fetch image data from Portal API\n const fetchImage = useCallback(async () => {\n if (!apiKey || !apiUrl) {\n setLoading(false)\n return\n }\n\n try {\n const params = new URLSearchParams({ page_path: currentPath })\n const res = await sonorFetch(\n `${apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n const data = await res.json()\n setImageData(data.image)\n setError(null)\n } catch (err) {\n // warn, not error: a failed slot fetch must not fail the Lighthouse\n // best-practices errors-in-console audit on every page using this slot.\n console.warn('[ManagedImage] Fetch error:', err)\n setError(err instanceof Error ? err : new Error(String(err)))\n onError?.(err instanceof Error ? err : new Error(String(err)))\n } finally {\n setLoading(false)\n }\n }, [apiKey, apiUrl, slotId, currentPath, onError])\n\n useEffect(() => {\n fetchImage()\n }, [fetchImage])\n\n // Calculate object-position from focal point\n const objectPosition = imageData\n ? `${imageData.focal_point_x}% ${imageData.focal_point_y}%`\n : '50% 50%'\n\n // Get the image URL\n const imageUrl = imageData?.public_url || imageData?.external_url || fallback\n\n // Handle click in dev mode\n const handleClick = (e: React.MouseEvent) => {\n if (devMode) {\n e.preventDefault()\n e.stopPropagation()\n setShowPicker(true)\n }\n }\n\n // Render placeholder state\n if (loading) {\n return (\n <div\n className={`bg-gray-200 animate-pulse ${className}`}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n />\n )\n }\n\n // No image assigned - show placeholder or dev picker hint\n if (!imageUrl) {\n if (placeholder) {\n return <>{placeholder}</>\n }\n\n return (\n <div\n onClick={handleClick}\n className={`\n bg-gray-100 border-2 border-dashed border-gray-300 \n flex items-center justify-center text-gray-400\n ${devMode ? 'cursor-pointer hover:border-blue-400 hover:text-blue-500 hover:bg-blue-50' : ''}\n ${className}\n `}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n title={devMode ? `Click to add image for slot: ${slotId}` : undefined}\n >\n <div className=\"text-center p-4\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n {devMode && (\n <p className=\"text-sm font-medium\">Click to add image</p>\n )}\n <p className=\"text-xs mt-1\">{slotId}</p>\n </div>\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n }\n\n // Render the image\n return (\n <div className=\"relative\" style={{ width, height }}>\n <img\n src={imageUrl}\n alt={imageData?.alt_text || alt || ''}\n title={imageData?.title || undefined}\n data-managed-image=\"true\"\n data-slot-id={slotId}\n data-page-path={currentPath}\n className={className}\n style={{\n objectFit,\n objectPosition,\n width: width ?? '100%',\n height: height ?? 'auto',\n ...style,\n }}\n onLoad={onLoad}\n onError={() => onError?.(new Error('Image failed to load'))}\n loading={priority ? 'eager' : 'lazy'}\n onClick={handleClick}\n />\n\n {/* Dev mode overlay */}\n {devMode && (\n <div\n className=\"absolute inset-0 bg-black/0 hover:bg-black/30 transition-colors cursor-pointer flex items-center justify-center opacity-0 hover:opacity-100\"\n onClick={handleClick}\n >\n <div className=\"bg-white/90 px-3 py-1.5 rounded-lg shadow-lg text-sm font-medium text-gray-700\">\n Edit Image\n </div>\n </div>\n )}\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n currentImage={imageData}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n}\n\n// ============================================================================\n// IMAGE PICKER MODAL\n// ============================================================================\n\ninterface ImagePickerModalProps {\n slotId: string\n pagePath: string\n config: any\n currentImage?: ManagedImageData | null\n onClose: () => void\n onSelect: () => void\n}\n\nfunction ImagePickerModal({\n slotId,\n pagePath,\n config,\n currentImage,\n onClose,\n onSelect,\n}: ImagePickerModalProps) {\n const [files, setFiles] = useState<ImageFile[]>([])\n const [folders, setFolders] = useState<string[]>([])\n const [currentFolder, setCurrentFolder] = useState<string>('')\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(true)\n const [uploading, setUploading] = useState(false)\n const [altText, setAltText] = useState(currentImage?.alt_text || '')\n\n // Fetch available files\n const fetchFiles = useCallback(async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n setLoading(true)\n try {\n const params = new URLSearchParams()\n if (currentFolder) params.set('folder', currentFolder)\n if (search) params.set('search', search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (res.ok) {\n const data = await res.json()\n setFiles(data.files || [])\n setFolders(data.folders || [])\n }\n } catch (err) {\n console.warn('[ImagePicker] Fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [config?.apiKey, config?.apiUrl, currentFolder, search])\n\n useEffect(() => {\n fetchFiles()\n }, [fetchFiles])\n\n // Select an existing file\n const handleSelectFile = async (file: ImageFile) => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: pagePath,\n file_id: file.id,\n alt_text: altText || file.filename,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Select error:', err)\n }\n }\n\n // Upload new file\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file || !config?.apiKey || !config?.apiUrl) return\n\n setUploading(true)\n try {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('slot_id', slotId)\n formData.append('page_path', pagePath)\n formData.append('folder', currentFolder || 'Website/Images')\n if (altText) formData.append('alt_text', altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long\n // timeout, no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Upload error:', err)\n } finally {\n setUploading(false)\n }\n }\n\n // Clear the slot\n const handleClear = async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const params = new URLSearchParams({ page_path: pagePath })\n await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n onSelect()\n } catch (err) {\n console.warn('[ImagePicker] Clear error:', err)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-[99999] bg-black/50 flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <div\n className=\"bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-4 border-b\">\n <div>\n <h2 className=\"text-lg font-semibold\">Select Image</h2>\n <p className=\"text-sm text-gray-500\">Slot: {slotId}</p>\n </div>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 p-2\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-4 overflow-y-auto\" style={{ maxHeight: 'calc(90vh - 180px)' }}>\n {/* Upload & Search */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <input\n type=\"text\"\n placeholder=\"Search images...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n <label className=\"px-4 py-2 bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 text-sm font-medium flex items-center gap-2\">\n {uploading ? 'Uploading...' : 'Upload New'}\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleUpload}\n disabled={uploading}\n className=\"hidden\"\n />\n </label>\n {currentImage?.file_id && (\n <button\n onClick={handleClear}\n className=\"px-4 py-2 border border-red-200 text-red-600 rounded-lg hover:bg-red-50 text-sm\"\n >\n Remove\n </button>\n )}\n </div>\n\n {/* Alt text input */}\n <div className=\"mb-4\">\n <input\n type=\"text\"\n placeholder=\"Alt text for image...\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n\n {/* Folder navigation */}\n {folders.length > 0 && (\n <div className=\"flex gap-2 mb-4 flex-wrap\">\n <button\n onClick={() => setCurrentFolder('')}\n className={`px-3 py-1 text-sm rounded-full ${\n !currentFolder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n All\n </button>\n {folders.map((folder) => (\n <button\n key={folder}\n onClick={() => setCurrentFolder(folder)}\n className={`px-3 py-1 text-sm rounded-full ${\n currentFolder === folder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n {folder}\n </button>\n ))}\n </div>\n )}\n\n {/* File grid */}\n {loading ? (\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(8)].map((_, i) => (\n <div key={i} className=\"aspect-square bg-gray-200 rounded-lg animate-pulse\" />\n ))}\n </div>\n ) : files.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500\">\n <p>No images found</p>\n <p className=\"text-sm mt-1\">Upload a new image to get started</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-4 gap-4\">\n {files.map((file) => (\n <button\n key={file.id}\n onClick={() => handleSelectFile(file)}\n className={`\n aspect-square rounded-lg overflow-hidden border-2 transition-all\n hover:border-blue-400 hover:shadow-lg\n ${currentImage?.file_id === file.id ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-200'}\n `}\n >\n <img\n src={file.public_url}\n alt={file.filename}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg text-sm\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ManagedImage\n","/**\n * Images API functions\n * \n * All functions use Portal API with API key authentication.\n * Never makes direct Supabase calls.\n */\n\nimport type { ManagedImageData, ImageFile } from './ManagedImage'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ImageApiConfig {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Fetch a managed image for a specific slot\n */\nexport async function fetchManagedImage(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ image: ManagedImageData | null; is_placeholder: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Fetch all managed images for the project\n */\nexport async function fetchManagedImages(\n config: ImageApiConfig,\n options?: {\n pagePath?: string\n category?: string\n includePlaceholders?: boolean\n },\n): Promise<{ images: ManagedImageData[] }> {\n const params = new URLSearchParams()\n if (options?.pagePath) params.set('page_path', options.pagePath)\n if (options?.category) params.set('category', options.category)\n if (options?.includePlaceholders) params.set('include_placeholders', 'true')\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch images: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * List available image files in the project\n */\nexport async function listImageFiles(\n config: ImageApiConfig,\n options?: {\n folder?: string\n search?: string\n },\n): Promise<{ files: ImageFile[]; folders: string[] }> {\n const params = new URLSearchParams()\n if (options?.folder) params.set('folder', options.folder)\n if (options?.search) params.set('search', options.search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to list files: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Upload a new image\n */\nexport async function uploadImage(\n config: ImageApiConfig,\n file: File,\n options?: {\n slotId?: string\n pagePath?: string\n folder?: string\n altText?: string\n },\n): Promise<{ file: ImageFile; image?: ManagedImageData }> {\n const formData = new FormData()\n formData.append('file', file)\n if (options?.slotId) formData.append('slot_id', options.slotId)\n if (options?.pagePath) formData.append('page_path', options.pagePath)\n if (options?.folder) formData.append('folder', options.folder)\n if (options?.altText) formData.append('alt_text', options.altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long timeout,\n // no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (!res.ok) {\n throw new Error(`Failed to upload image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Assign an existing file to an image slot\n */\nexport async function assignImageToSlot(\n config: ImageApiConfig,\n slotId: string,\n options: {\n fileId?: string\n externalUrl?: string\n pagePath?: string\n altText?: string\n title?: string\n caption?: string\n focalPointX?: number\n focalPointY?: number\n aspectRatio?: string\n },\n): Promise<{ image: ManagedImageData }> {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: options.pagePath,\n file_id: options.fileId,\n external_url: options.externalUrl,\n alt_text: options.altText,\n title: options.title,\n caption: options.caption,\n focal_point_x: options.focalPointX,\n focal_point_y: options.focalPointY,\n aspect_ratio: options.aspectRatio,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to assign image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Clear an image from a slot (keeps the file)\n */\nexport async function clearImageSlot(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ success: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to clear slot: ${res.status}`)\n }\n\n return res.json()\n}\n"]}
@@ -1,10 +1,10 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunkYGDQVZEL_js = require('./chunk-YGDQVZEL.js');
5
- var chunkKA4NNWOK_js = require('./chunk-KA4NNWOK.js');
4
+ var chunkIDJY2JWU_js = require('./chunk-IDJY2JWU.js');
5
+ var chunkTMNFPVK5_js = require('./chunk-TMNFPVK5.js');
6
6
  var chunkHGNSJXWT_js = require('./chunk-HGNSJXWT.js');
7
- var chunkVINLIMAX_js = require('./chunk-VINLIMAX.js');
7
+ var chunkBGOPF6J2_js = require('./chunk-BGOPF6J2.js');
8
8
  var chunkUZKXOZHR_js = require('./chunk-UZKXOZHR.js');
9
9
  var chunkRC4WWQXR_js = require('./chunk-RC4WWQXR.js');
10
10
  var React = require('react');
@@ -17,15 +17,15 @@ var React__default = /*#__PURE__*/_interopDefault(React);
17
17
  var dynamic__default = /*#__PURE__*/_interopDefault(dynamic);
18
18
 
19
19
  var LazyAnalyticsProvider = dynamic__default.default(
20
- () => import('./AnalyticsProvider-AZQXLRWN.js').then((m) => ({ default: m.AnalyticsProvider })),
20
+ () => import('./AnalyticsProvider-V6G45QG7.js').then((m) => ({ default: m.AnalyticsProvider })),
21
21
  { ssr: false }
22
22
  );
23
23
  var LazyEngageWidget = dynamic__default.default(
24
- () => import('./EngageWidget-XUTDFRF3.js').then((m) => ({ default: m.EngageWidget })),
24
+ () => import('./EngageWidget-IQRKRYPG.js').then((m) => ({ default: m.EngageWidget })),
25
25
  { ssr: false }
26
26
  );
27
27
  var LazySitemapSync = dynamic__default.default(
28
- () => import('./SitemapSync-PZ76V5MX.js').then((m) => ({ default: m.SitemapSync })),
28
+ () => import('./SitemapSync-P7XWL6VV.js').then((m) => ({ default: m.SitemapSync })),
29
29
  { ssr: false }
30
30
  );
31
31
  function SiteKitClientProviders({
@@ -45,7 +45,7 @@ function SiteKitClientProviders({
45
45
  const modulesReady = chunkHGNSJXWT_js.useDeferredActivation(defer);
46
46
  const analyticsConfig = typeof analytics === "object" ? analytics : {};
47
47
  const site = chunkUZKXOZHR_js.resolveSiteHost(analyticsConfig.site);
48
- chunkYGDQVZEL_js.publishSiteCredential({ apiKey, apiUrl, site, debug, mapsBrowserKey });
48
+ chunkIDJY2JWU_js.publishSiteCredential({ apiKey, apiUrl, site, debug, mapsBrowserKey });
49
49
  const [visitorId] = React.useState(() => chunkRC4WWQXR_js.getOrCreateVisitorId());
50
50
  const [sessionId] = React.useState(() => chunkRC4WWQXR_js.getOrCreateSessionId());
51
51
  const pageMetadataRef = React.useRef(null);
@@ -57,7 +57,7 @@ function SiteKitClientProviders({
57
57
  const signalConfig = typeof signal === "object" ? signal : {};
58
58
  siblings.push(
59
59
  /* @__PURE__ */ jsxRuntime.jsx(
60
- chunkVINLIMAX_js.SignalBridge,
60
+ chunkBGOPF6J2_js.SignalBridge,
61
61
  {
62
62
  enabled: true,
63
63
  realtime: signalConfig.realtime !== false,
@@ -134,7 +134,7 @@ function SiteKitClientProviders({
134
134
  if (sitemapSync) activeModules.push("sitemapSync");
135
135
  siblings.push(
136
136
  /* @__PURE__ */ jsxRuntime.jsx(React__default.default.Fragment, { children: modulesReady && /* @__PURE__ */ jsxRuntime.jsx(
137
- chunkKA4NNWOK_js.FleetHeartbeat,
137
+ chunkTMNFPVK5_js.FleetHeartbeat,
138
138
  {
139
139
  apiUrl,
140
140
  apiKey,
@@ -155,5 +155,5 @@ function SiteKitClientProviders({
155
155
  }
156
156
 
157
157
  exports.SiteKitClientProviders = SiteKitClientProviders;
158
- //# sourceMappingURL=chunk-5DSUPTBU.js.map
159
- //# sourceMappingURL=chunk-5DSUPTBU.js.map
158
+ //# sourceMappingURL=chunk-KDNB6BYH.js.map
159
+ //# sourceMappingURL=chunk-KDNB6BYH.js.map