@carlonicora/nextjs-jsonapi 3.28.2 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/dist/{BlockNoteEditor-36VL2TNM.js → BlockNoteEditor-BXMTGKDV.js} +21 -20
  2. package/dist/BlockNoteEditor-BXMTGKDV.js.map +1 -0
  3. package/dist/{BlockNoteEditor-4IDXT6ZU.mjs → BlockNoteEditor-FGVQP35E.mjs} +9 -8
  4. package/dist/{BlockNoteEditor-4IDXT6ZU.mjs.map → BlockNoteEditor-FGVQP35E.mjs.map} +1 -1
  5. package/dist/{BlockNoteViewer-KRTAFTUX.mjs → BlockNoteViewer-DQYT6IJW.mjs} +3 -3
  6. package/dist/{BlockNoteViewer-7BFNTN4E.js → BlockNoteViewer-YH7G66PS.js} +4 -4
  7. package/dist/{BlockNoteViewer-7BFNTN4E.js.map → BlockNoteViewer-YH7G66PS.js.map} +1 -1
  8. package/dist/{HandbookSectionInterface-DgYH--Ik.d.mts → HandbookSectionInterface-BYsmnPEz.d.mts} +1 -1
  9. package/dist/{HandbookSectionInterface-Ck1wZJ81.d.ts → HandbookSectionInterface-OePKPbqN.d.ts} +1 -1
  10. package/dist/{JsonApiRequest-UHOWNI3O.mjs → JsonApiRequest-MEP6AXDT.mjs} +2 -2
  11. package/dist/JsonApiRequest-OB6WL4LA.js +26 -0
  12. package/dist/{JsonApiRequest-TE5WD3WS.js.map → JsonApiRequest-OB6WL4LA.js.map} +1 -1
  13. package/dist/ServerSession-DFNNNkg7.d.ts +29 -0
  14. package/dist/ServerSession-DK1z0_Ql.d.mts +29 -0
  15. package/dist/{analytics.modules-CfczU12P.d.ts → analytics.modules-Bsacu6ik.d.ts} +1 -1
  16. package/dist/{analytics.modules-pzGwMASI.d.mts → analytics.modules-txdCLNG-.d.mts} +1 -1
  17. package/dist/billing/index.js +404 -402
  18. package/dist/billing/index.js.map +1 -1
  19. package/dist/billing/index.mjs +10 -8
  20. package/dist/billing/index.mjs.map +1 -1
  21. package/dist/{chunk-7B4E42R5.mjs → chunk-3CZ2GK5R.mjs} +33 -9
  22. package/dist/chunk-3CZ2GK5R.mjs.map +1 -0
  23. package/dist/{chunk-4Z45NYPR.js → chunk-5W5MN7JP.js} +14 -83
  24. package/dist/chunk-5W5MN7JP.js.map +1 -0
  25. package/dist/{chunk-CAKOFJZD.js → chunk-6OFANJTE.js} +195 -142
  26. package/dist/chunk-6OFANJTE.js.map +1 -0
  27. package/dist/{chunk-5TRFNKJS.js → chunk-6TUB7Y6T.js} +23 -25
  28. package/dist/chunk-6TUB7Y6T.js.map +1 -0
  29. package/dist/{chunk-37DMFVLN.mjs → chunk-7SCREMTX.mjs} +4 -3
  30. package/dist/{chunk-37DMFVLN.mjs.map → chunk-7SCREMTX.mjs.map} +1 -1
  31. package/dist/{chunk-Q6J2ICKO.mjs → chunk-ADZSH3MG.mjs} +3 -72
  32. package/dist/chunk-ADZSH3MG.mjs.map +1 -0
  33. package/dist/{chunk-E3I4MT53.mjs → chunk-AQZ3T4BR.mjs} +71 -18
  34. package/dist/chunk-AQZ3T4BR.mjs.map +1 -0
  35. package/dist/{chunk-SJLXPHK5.mjs → chunk-E2LENTUH.mjs} +22 -24
  36. package/dist/chunk-E2LENTUH.mjs.map +1 -0
  37. package/dist/chunk-EBEXWN3I.mjs +17 -0
  38. package/dist/chunk-EBEXWN3I.mjs.map +1 -0
  39. package/dist/chunk-G4JR3SFV.js +28 -0
  40. package/dist/chunk-G4JR3SFV.js.map +1 -0
  41. package/dist/chunk-IK65TDQH.js +15 -0
  42. package/dist/chunk-IK65TDQH.js.map +1 -0
  43. package/dist/{chunk-GHFMKH3M.js → chunk-JEQ34Z5E.js} +62 -38
  44. package/dist/chunk-JEQ34Z5E.js.map +1 -0
  45. package/dist/{chunk-KOTKKBJT.js → chunk-NFCXUAE6.js} +1328 -1183
  46. package/dist/chunk-NFCXUAE6.js.map +1 -0
  47. package/dist/chunk-OEOK6A3P.js +17 -0
  48. package/dist/chunk-OEOK6A3P.js.map +1 -0
  49. package/dist/chunk-PW42LRSL.mjs +28 -0
  50. package/dist/chunk-PW42LRSL.mjs.map +1 -0
  51. package/dist/{chunk-U65JPKO3.mjs → chunk-R6ZYB4VN.mjs} +2 -2
  52. package/dist/chunk-T7SAW3UW.mjs +15 -0
  53. package/dist/chunk-T7SAW3UW.mjs.map +1 -0
  54. package/dist/{chunk-GKDHYB2R.js → chunk-TWBZ2GSX.js} +3 -3
  55. package/dist/{chunk-GKDHYB2R.js.map → chunk-TWBZ2GSX.js.map} +1 -1
  56. package/dist/{chunk-26MQIJNB.js → chunk-WGVNJXZO.js} +4 -3
  57. package/dist/chunk-WGVNJXZO.js.map +1 -0
  58. package/dist/{chunk-HPUV6FBW.mjs → chunk-WJC4SYRL.mjs} +2131 -1986
  59. package/dist/chunk-WJC4SYRL.mjs.map +1 -0
  60. package/dist/client/index.d.mts +3 -3
  61. package/dist/client/index.d.ts +3 -3
  62. package/dist/client/index.js +6 -5
  63. package/dist/client/index.js.map +1 -1
  64. package/dist/client/index.mjs +13 -12
  65. package/dist/components/index.d.mts +16 -6
  66. package/dist/components/index.d.ts +16 -6
  67. package/dist/components/index.js +8 -5
  68. package/dist/components/index.js.map +1 -1
  69. package/dist/components/index.mjs +9 -6
  70. package/dist/{config-3N1LSrcC.d.ts → config-B6UB7j69.d.ts} +1 -1
  71. package/dist/{config-BmufyEj6.d.mts → config-CEAq4Ozy.d.mts} +10 -1
  72. package/dist/{config-AVtuvfM1.d.ts → config-DydDHCfb.d.ts} +10 -1
  73. package/dist/{config-BSKTYDoh.d.mts → config-n-ZpPmOL.d.mts} +1 -1
  74. package/dist/contexts/index.d.mts +28 -4
  75. package/dist/contexts/index.d.ts +28 -4
  76. package/dist/contexts/index.js +10 -5
  77. package/dist/contexts/index.js.map +1 -1
  78. package/dist/contexts/index.mjs +9 -4
  79. package/dist/core/index.d.mts +6 -6
  80. package/dist/core/index.d.ts +6 -6
  81. package/dist/core/index.js +5 -5
  82. package/dist/core/index.js.map +1 -1
  83. package/dist/core/index.mjs +4 -4
  84. package/dist/features/analytics/index.d.mts +2 -2
  85. package/dist/features/analytics/index.d.ts +2 -2
  86. package/dist/features/analytics/index.js +124 -123
  87. package/dist/features/analytics/index.js.map +1 -1
  88. package/dist/features/analytics/index.mjs +6 -5
  89. package/dist/features/analytics/index.mjs.map +1 -1
  90. package/dist/features/analytics/server.d.mts +10 -2
  91. package/dist/features/analytics/server.d.ts +10 -2
  92. package/dist/features/analytics/server.js +8 -6
  93. package/dist/features/analytics/server.js.map +1 -1
  94. package/dist/features/analytics/server.mjs +6 -4
  95. package/dist/features/analytics/server.mjs.map +1 -1
  96. package/dist/features/help/index.d.mts +2 -2
  97. package/dist/features/help/index.d.ts +2 -2
  98. package/dist/features/help/index.js +39 -38
  99. package/dist/features/help/index.js.map +1 -1
  100. package/dist/features/help/index.mjs +5 -4
  101. package/dist/features/help/index.mjs.map +1 -1
  102. package/dist/features/tokenusage/index.d.mts +2 -2
  103. package/dist/features/tokenusage/index.d.ts +2 -2
  104. package/dist/features/tokenusage/index.js +127 -126
  105. package/dist/features/tokenusage/index.js.map +1 -1
  106. package/dist/features/tokenusage/index.mjs +6 -5
  107. package/dist/features/tokenusage/index.mjs.map +1 -1
  108. package/dist/index.d.mts +5 -5
  109. package/dist/index.d.ts +5 -5
  110. package/dist/index.js +8 -6
  111. package/dist/index.js.map +1 -1
  112. package/dist/index.mjs +11 -9
  113. package/dist/next-config/index.d.mts +43 -0
  114. package/dist/next-config/index.d.ts +43 -0
  115. package/dist/next-config/index.js +230 -0
  116. package/dist/next-config/index.js.map +1 -0
  117. package/dist/next-config/index.mjs +230 -0
  118. package/dist/next-config/index.mjs.map +1 -0
  119. package/dist/{request-FXF63NSQ.mjs → request-3IUMNVOS.mjs} +2 -2
  120. package/dist/request-LZBAOT3Y.js +8 -0
  121. package/dist/request-LZBAOT3Y.js.map +1 -0
  122. package/dist/server/cachedGet.d.mts +28 -0
  123. package/dist/server/cachedGet.d.ts +28 -0
  124. package/dist/server/cachedGet.js +60 -0
  125. package/dist/server/cachedGet.js.map +1 -0
  126. package/dist/server/cachedGet.mjs +60 -0
  127. package/dist/server/cachedGet.mjs.map +1 -0
  128. package/dist/server/cachedGet.stub.d.mts +7 -0
  129. package/dist/server/cachedGet.stub.d.ts +7 -0
  130. package/dist/server/cachedGet.stub.js +17 -0
  131. package/dist/server/cachedGet.stub.js.map +1 -0
  132. package/dist/server/cachedGet.stub.mjs +17 -0
  133. package/dist/server/cachedGet.stub.mjs.map +1 -0
  134. package/dist/server/index.d.mts +27 -25
  135. package/dist/server/index.d.ts +27 -25
  136. package/dist/server/index.js +13 -6
  137. package/dist/server/index.js.map +1 -1
  138. package/dist/server/index.mjs +15 -8
  139. package/dist/testing/index.js.map +1 -1
  140. package/dist/testing/index.mjs.map +1 -1
  141. package/dist/{types-D0uLYV2P.d.mts → types-Bq_UA8Lg.d.mts} +1 -1
  142. package/dist/{types-Cn153-mH.d.ts → types-bsm8Fp55.d.ts} +1 -1
  143. package/dist/{usePageUrlGenerator-B-3FRKBD.d.ts → usePageUrlGenerator-J_ECv-oQ.d.ts} +1 -1
  144. package/dist/{usePageUrlGenerator-CCJ_cdQy.d.mts → usePageUrlGenerator-uKBjAKqC.d.mts} +1 -1
  145. package/package.json +12 -1
  146. package/src/components/forms/__tests__/EditorSheet.test.tsx +25 -1
  147. package/src/components/forms/__tests__/useEditorDialog.test.ts +164 -1
  148. package/src/components/forms/useEditorDialog.ts +69 -2
  149. package/src/contexts/SessionContext.tsx +20 -0
  150. package/src/contexts/SocketContext.tsx +30 -3
  151. package/src/contexts/ViewportContext.tsx +17 -2
  152. package/src/contexts/__tests__/SessionContext.test.tsx +58 -0
  153. package/src/contexts/__tests__/SocketContext.session.test.tsx +77 -0
  154. package/src/contexts/index.ts +1 -0
  155. package/src/core/abstracts/AbstractService.ts +4 -6
  156. package/src/core/abstracts/__tests__/AbstractService.locale.test.ts +64 -0
  157. package/src/features/analytics/components/server/AnalyticsAdminPage.tsx +5 -1
  158. package/src/features/analytics/components/server/AnalyticsJourneyPage.tsx +5 -1
  159. package/src/features/notification/contexts/NotificationContext.tsx +5 -2
  160. package/src/features/notification/contexts/__tests__/NotificationContext.spec.tsx +22 -0
  161. package/src/features/user/contexts/CurrentUserContext.tsx +7 -5
  162. package/src/features/user/contexts/__tests__/CurrentUserContext.spec.tsx +63 -3
  163. package/src/hooks/__tests__/useSocket.render.test.ts +22 -0
  164. package/src/hooks/useSocket.ts +0 -1
  165. package/src/i18n/__tests__/config.test.ts +27 -0
  166. package/src/i18n/config.ts +17 -0
  167. package/src/i18n/index.ts +2 -0
  168. package/src/next-config/__tests__/createNextConfig.test.ts +268 -0
  169. package/src/next-config/csp.ts +128 -0
  170. package/src/next-config/headers.ts +61 -0
  171. package/src/next-config/index.ts +114 -0
  172. package/src/server/JsonApiServer.ts +3 -1
  173. package/src/server/ServerSession.ts +29 -1
  174. package/src/server/__tests__/JsonApiServer.test.ts +41 -0
  175. package/src/server/__tests__/ServerSession.read.test.ts +67 -0
  176. package/src/server/__tests__/cache.test.ts +48 -0
  177. package/src/server/__tests__/cachedGet.test.ts +125 -0
  178. package/src/server/__tests__/request.test.ts +96 -1
  179. package/src/server/cache.ts +21 -4
  180. package/src/server/cacheDigest.ts +10 -0
  181. package/src/server/cacheProfiles.ts +15 -0
  182. package/src/server/cachedGet.stub.ts +15 -0
  183. package/src/server/cachedGet.ts +80 -0
  184. package/src/server/request.ts +33 -32
  185. package/src/shadcnui/ui/__tests__/sidebar.menu-skeleton.test.tsx +50 -0
  186. package/src/shadcnui/ui/__tests__/sidebar.session.test.tsx +133 -0
  187. package/src/shadcnui/ui/sidebar.tsx +121 -18
  188. package/src/testing/matchers/jsonApiMatchers.ts +1 -0
  189. package/src/unified/JsonApiRequest.ts +4 -1
  190. package/src/unified/__tests__/JsonApiGet.cache.test.ts +51 -0
  191. package/src/utils/__tests__/map-thenable.test.ts +29 -0
  192. package/src/utils/__tests__/use-mobile.test.tsx +102 -1
  193. package/src/utils/map-thenable.ts +15 -0
  194. package/src/utils/use-mobile.tsx +13 -4
  195. package/dist/BlockNoteEditor-36VL2TNM.js.map +0 -1
  196. package/dist/JsonApiRequest-TE5WD3WS.js +0 -26
  197. package/dist/chunk-26MQIJNB.js.map +0 -1
  198. package/dist/chunk-4Z45NYPR.js.map +0 -1
  199. package/dist/chunk-5TRFNKJS.js.map +0 -1
  200. package/dist/chunk-7B4E42R5.mjs.map +0 -1
  201. package/dist/chunk-CAKOFJZD.js.map +0 -1
  202. package/dist/chunk-E3I4MT53.mjs.map +0 -1
  203. package/dist/chunk-GHFMKH3M.js.map +0 -1
  204. package/dist/chunk-HPUV6FBW.mjs.map +0 -1
  205. package/dist/chunk-KOTKKBJT.js.map +0 -1
  206. package/dist/chunk-Q6J2ICKO.mjs.map +0 -1
  207. package/dist/chunk-SJLXPHK5.mjs.map +0 -1
  208. package/dist/request-ZTX6I63X.js +0 -8
  209. package/dist/request-ZTX6I63X.js.map +0 -1
  210. /package/dist/{BlockNoteViewer-KRTAFTUX.mjs.map → BlockNoteViewer-DQYT6IJW.mjs.map} +0 -0
  211. /package/dist/{JsonApiRequest-UHOWNI3O.mjs.map → JsonApiRequest-MEP6AXDT.mjs.map} +0 -0
  212. /package/dist/{chunk-U65JPKO3.mjs.map → chunk-R6ZYB4VN.mjs.map} +0 -0
  213. /package/dist/{request-FXF63NSQ.mjs.map → request-3IUMNVOS.mjs.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/analytics/server.js","../../../src/features/analytics/components/server/AnalyticsAdminPage.tsx","../../../src/features/analytics/components/server/AnalyticsJourneyPage.tsx"],"names":["redirect","jsx"],"mappings":"AAAA;AACE;AACF,0DAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC;AACE;AACF,0DAAgC;AAChC;AACA;ACbA,6CAAyB;AAMzB,kEAA4C;AAoBnC,+CAAA;AALT,MAAA,SAAsB,kBAAA,CAAmB,EAAE,WAAA,EAAa,OAAA,EAAS,cAAA,EAAgB,eAAA,EAAiB,IAAI,CAAA,EAAU;AAC9G,EAAA,GAAA,CAAI,CAAE,MAAM,8BAAA,CAAc,OAAA,CAAQ,WAAW,CAAA,EAAI;AAC/C,IAAA,kCAAA,cAAuB,CAAA;AAAA,EACzB;AAEA,EAAA,uBAAO,6BAAA,sCAAC,EAAA,EAA4B,OAAA,EAAkB,eAAA,CAAgC,CAAA;AACxF;AANsB,qCAAA,kBAAA,EAAA,oBAAA,CAAA;ADGtB;AACA;AEzBA;AAIA;AAmBS;AALT,MAAA,SAAsB,oBAAA,CAAqB,EAAE,WAAA,EAAa,SAAA,EAAW,OAAA,EAAS,eAAA,EAAiB,IAAI,CAAA,EAAU;AAC3G,EAAA,GAAA,CAAI,CAAE,MAAM,8BAAA,CAAc,OAAA,CAAQ,WAAW,CAAA,EAAI;AAC/C,IAAAA,kCAAAA,cAAuB,CAAA;AAAA,EACzB;AAEA,EAAA,uBAAOC,6BAAAA,wCAAC,EAAA,EAA8B,SAAA,EAAsB,QAAA,CAAkB,CAAA;AAChF;AANsB,qCAAA,oBAAA,EAAA,sBAAA,CAAA;AFkBtB;AACE;AACA;AACF,qGAAC","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/analytics/server.js","sourcesContent":[null,"import { redirect } from \"next/navigation\";\n// The container is imported through the package's own client subpath, never by\n// relative path. tsup keeps this specifier external, so the built server entry\n// reaches the container through `features/analytics/index`, which carries the\n// \"use client\" banner. A relative import would inline the container's hooks and\n// contexts into this server bundle, outside any client boundary.\nimport { AnalyticsAdminPageContainer } from \"@carlonicora/nextjs-jsonapi/analytics\";\nimport { ServerSession } from \"../../../../server\";\n\ntype Props = {\n /** Role id the viewer must hold. The package has no role constants, so the host app passes its own. */\n adminRoleId: string;\n /** Route the breadcrumb links back to. */\n pageUrl?: string;\n /** Base route of the journey page each session row links to. */\n sessionPageUrl?: string;\n /** Where a viewer without the role is sent. */\n deniedRedirect?: string;\n};\n\n/** Server page for the administrative analytics dashboard: role gate, then the client container. */\nexport async function AnalyticsAdminPage({ adminRoleId, pageUrl, sessionPageUrl, deniedRedirect = \"/\" }: Props) {\n if (!(await ServerSession.hasRole(adminRoleId))) {\n redirect(deniedRedirect);\n }\n\n return <AnalyticsAdminPageContainer pageUrl={pageUrl} sessionPageUrl={sessionPageUrl} />;\n}\n","import { redirect } from \"next/navigation\";\n// Imported through the package's own client subpath for the same reason as in\n// AnalyticsAdminPage: the built server entry must reach the container through\n// the \"use client\" bundle, not inline it.\nimport { AnalyticsJourneyPageContainer } from \"@carlonicora/nextjs-jsonapi/analytics\";\nimport { ServerSession } from \"../../../../server\";\n\ntype Props = {\n /** Role id the viewer must hold. The package has no role constants, so the host app passes its own. */\n adminRoleId: string;\n sessionId: string;\n /** Route of the dashboard; the journey pages live under `${pageUrl}/sessions`. */\n pageUrl?: string;\n /** Where a viewer without the role is sent. */\n deniedRedirect?: string;\n};\n\n/** Server page for one session's journey: role gate, then the client container. */\nexport async function AnalyticsJourneyPage({ adminRoleId, sessionId, pageUrl, deniedRedirect = \"/\" }: Props) {\n if (!(await ServerSession.hasRole(adminRoleId))) {\n redirect(deniedRedirect);\n }\n\n return <AnalyticsJourneyPageContainer sessionId={sessionId} pageUrl={pageUrl} />;\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/analytics/server.js","../../../src/features/analytics/components/server/AnalyticsAdminPage.tsx","../../../src/features/analytics/components/server/AnalyticsJourneyPage.tsx"],"names":["redirect","jsx"],"mappings":"AAAA;AACE;AACF,0DAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC;AACE;AACF,0DAAgC;AAChC;AACA;ACfA,6CAAyB;AAMzB,kEAA4C;AAwBnC,+CAAA;AALT,MAAA,SAAsB,kBAAA,CAAmB,EAAE,WAAA,EAAa,OAAA,EAAS,cAAA,EAAgB,eAAA,EAAiB,IAAI,CAAA,EAAU;AAC9G,EAAA,GAAA,CAAI,CAAE,MAAM,8BAAA,CAAc,OAAA,CAAQ,WAAW,CAAA,EAAI;AAC/C,IAAA,kCAAA,cAAuB,CAAA;AAAA,EACzB;AAEA,EAAA,uBAAO,6BAAA,sCAAC,EAAA,EAA4B,OAAA,EAAkB,eAAA,CAAgC,CAAA;AACxF;AANsB,qCAAA,kBAAA,EAAA,oBAAA,CAAA;ADCtB;AACA;AE3BA;AAIA;AAuBS;AALT,MAAA,SAAsB,oBAAA,CAAqB,EAAE,WAAA,EAAa,SAAA,EAAW,OAAA,EAAS,eAAA,EAAiB,IAAI,CAAA,EAAU;AAC3G,EAAA,GAAA,CAAI,CAAE,MAAM,8BAAA,CAAc,OAAA,CAAQ,WAAW,CAAA,EAAI;AAC/C,IAAAA,kCAAAA,cAAuB,CAAA;AAAA,EACzB;AAEA,EAAA,uBAAOC,6BAAAA,wCAAC,EAAA,EAA8B,SAAA,EAAsB,QAAA,CAAkB,CAAA;AAChF;AANsB,qCAAA,oBAAA,EAAA,sBAAA,CAAA;AFgBtB;AACE;AACA;AACF,qGAAC","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/analytics/server.js","sourcesContent":[null,"import { redirect } from \"next/navigation\";\n// The container is imported through the package's own client subpath, never by\n// relative path. tsup keeps this specifier external, so the built server entry\n// reaches the container through `features/analytics/index`, which carries the\n// \"use client\" banner. A relative import would inline the container's hooks and\n// contexts into this server bundle, outside any client boundary.\nimport { AnalyticsAdminPageContainer } from \"@carlonicora/nextjs-jsonapi/analytics\";\nimport { ServerSession } from \"../../../../server\";\n\ntype Props = {\n /** Role id the viewer must hold. The package has no role constants, so the host app passes its own. */\n adminRoleId: string;\n /** Route the breadcrumb links back to. */\n pageUrl?: string;\n /** Base route of the journey page each session row links to. */\n sessionPageUrl?: string;\n /** Where a viewer without the role is sent. */\n deniedRedirect?: string;\n};\n\n/**\n * Server page for the administrative analytics dashboard: role gate, then the client container.\n *\n * Reads the session: render inside a `<Suspense>` boundary (Cache Components).\n */\nexport async function AnalyticsAdminPage({ adminRoleId, pageUrl, sessionPageUrl, deniedRedirect = \"/\" }: Props) {\n if (!(await ServerSession.hasRole(adminRoleId))) {\n redirect(deniedRedirect);\n }\n\n return <AnalyticsAdminPageContainer pageUrl={pageUrl} sessionPageUrl={sessionPageUrl} />;\n}\n","import { redirect } from \"next/navigation\";\n// Imported through the package's own client subpath for the same reason as in\n// AnalyticsAdminPage: the built server entry must reach the container through\n// the \"use client\" bundle, not inline it.\nimport { AnalyticsJourneyPageContainer } from \"@carlonicora/nextjs-jsonapi/analytics\";\nimport { ServerSession } from \"../../../../server\";\n\ntype Props = {\n /** Role id the viewer must hold. The package has no role constants, so the host app passes its own. */\n adminRoleId: string;\n sessionId: string;\n /** Route of the dashboard; the journey pages live under `${pageUrl}/sessions`. */\n pageUrl?: string;\n /** Where a viewer without the role is sent. */\n deniedRedirect?: string;\n};\n\n/**\n * Server page for one session's journey: role gate, then the client container.\n *\n * Reads the session: render inside a `<Suspense>` boundary (Cache Components).\n */\nexport async function AnalyticsJourneyPage({ adminRoleId, sessionId, pageUrl, deniedRedirect = \"/\" }: Props) {\n if (!(await ServerSession.hasRole(adminRoleId))) {\n redirect(deniedRedirect);\n }\n\n return <AnalyticsJourneyPageContainer sessionId={sessionId} pageUrl={pageUrl} />;\n}\n"]}
@@ -1,12 +1,14 @@
1
1
  import {
2
2
  ServerSession
3
- } from "../../chunk-7B4E42R5.mjs";
4
- import "../../chunk-SJLXPHK5.mjs";
3
+ } from "../../chunk-3CZ2GK5R.mjs";
5
4
  import "../../chunk-F5UNXZ3J.mjs";
6
- import "../../chunk-E3I4MT53.mjs";
7
- import "../../chunk-37DMFVLN.mjs";
5
+ import "../../chunk-E2LENTUH.mjs";
6
+ import "../../chunk-T7SAW3UW.mjs";
7
+ import "../../chunk-PW42LRSL.mjs";
8
+ import "../../chunk-AQZ3T4BR.mjs";
8
9
  import "../../chunk-AUXK7QSA.mjs";
9
10
  import "../../chunk-PI56A4DG.mjs";
11
+ import "../../chunk-7SCREMTX.mjs";
10
12
  import {
11
13
  __name
12
14
  } from "../../chunk-PAWJFY3S.mjs";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/features/analytics/components/server/AnalyticsAdminPage.tsx","../../../src/features/analytics/components/server/AnalyticsJourneyPage.tsx"],"sourcesContent":["import { redirect } from \"next/navigation\";\n// The container is imported through the package's own client subpath, never by\n// relative path. tsup keeps this specifier external, so the built server entry\n// reaches the container through `features/analytics/index`, which carries the\n// \"use client\" banner. A relative import would inline the container's hooks and\n// contexts into this server bundle, outside any client boundary.\nimport { AnalyticsAdminPageContainer } from \"@carlonicora/nextjs-jsonapi/analytics\";\nimport { ServerSession } from \"../../../../server\";\n\ntype Props = {\n /** Role id the viewer must hold. The package has no role constants, so the host app passes its own. */\n adminRoleId: string;\n /** Route the breadcrumb links back to. */\n pageUrl?: string;\n /** Base route of the journey page each session row links to. */\n sessionPageUrl?: string;\n /** Where a viewer without the role is sent. */\n deniedRedirect?: string;\n};\n\n/** Server page for the administrative analytics dashboard: role gate, then the client container. */\nexport async function AnalyticsAdminPage({ adminRoleId, pageUrl, sessionPageUrl, deniedRedirect = \"/\" }: Props) {\n if (!(await ServerSession.hasRole(adminRoleId))) {\n redirect(deniedRedirect);\n }\n\n return <AnalyticsAdminPageContainer pageUrl={pageUrl} sessionPageUrl={sessionPageUrl} />;\n}\n","import { redirect } from \"next/navigation\";\n// Imported through the package's own client subpath for the same reason as in\n// AnalyticsAdminPage: the built server entry must reach the container through\n// the \"use client\" bundle, not inline it.\nimport { AnalyticsJourneyPageContainer } from \"@carlonicora/nextjs-jsonapi/analytics\";\nimport { ServerSession } from \"../../../../server\";\n\ntype Props = {\n /** Role id the viewer must hold. The package has no role constants, so the host app passes its own. */\n adminRoleId: string;\n sessionId: string;\n /** Route of the dashboard; the journey pages live under `${pageUrl}/sessions`. */\n pageUrl?: string;\n /** Where a viewer without the role is sent. */\n deniedRedirect?: string;\n};\n\n/** Server page for one session's journey: role gate, then the client container. */\nexport async function AnalyticsJourneyPage({ adminRoleId, sessionId, pageUrl, deniedRedirect = \"/\" }: Props) {\n if (!(await ServerSession.hasRole(adminRoleId))) {\n redirect(deniedRedirect);\n }\n\n return <AnalyticsJourneyPageContainer sessionId={sessionId} pageUrl={pageUrl} />;\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAS,gBAAgB;AAMzB,SAAS,mCAAmC;AAoBnC;AALT,eAAsB,mBAAmB,EAAE,aAAa,SAAS,gBAAgB,iBAAiB,IAAI,GAAU;AAC9G,MAAI,CAAE,MAAM,cAAc,QAAQ,WAAW,GAAI;AAC/C,aAAS,cAAc;AAAA,EACzB;AAEA,SAAO,oBAAC,+BAA4B,SAAkB,gBAAgC;AACxF;AANsB;;;ACrBtB,SAAS,YAAAA,iBAAgB;AAIzB,SAAS,qCAAqC;AAmBrC,gBAAAC,YAAA;AALT,eAAsB,qBAAqB,EAAE,aAAa,WAAW,SAAS,iBAAiB,IAAI,GAAU;AAC3G,MAAI,CAAE,MAAM,cAAc,QAAQ,WAAW,GAAI;AAC/C,IAAAC,UAAS,cAAc;AAAA,EACzB;AAEA,SAAO,gBAAAD,KAAC,iCAA8B,WAAsB,SAAkB;AAChF;AANsB;","names":["redirect","jsx","redirect"]}
1
+ {"version":3,"sources":["../../../src/features/analytics/components/server/AnalyticsAdminPage.tsx","../../../src/features/analytics/components/server/AnalyticsJourneyPage.tsx"],"sourcesContent":["import { redirect } from \"next/navigation\";\n// The container is imported through the package's own client subpath, never by\n// relative path. tsup keeps this specifier external, so the built server entry\n// reaches the container through `features/analytics/index`, which carries the\n// \"use client\" banner. A relative import would inline the container's hooks and\n// contexts into this server bundle, outside any client boundary.\nimport { AnalyticsAdminPageContainer } from \"@carlonicora/nextjs-jsonapi/analytics\";\nimport { ServerSession } from \"../../../../server\";\n\ntype Props = {\n /** Role id the viewer must hold. The package has no role constants, so the host app passes its own. */\n adminRoleId: string;\n /** Route the breadcrumb links back to. */\n pageUrl?: string;\n /** Base route of the journey page each session row links to. */\n sessionPageUrl?: string;\n /** Where a viewer without the role is sent. */\n deniedRedirect?: string;\n};\n\n/**\n * Server page for the administrative analytics dashboard: role gate, then the client container.\n *\n * Reads the session: render inside a `<Suspense>` boundary (Cache Components).\n */\nexport async function AnalyticsAdminPage({ adminRoleId, pageUrl, sessionPageUrl, deniedRedirect = \"/\" }: Props) {\n if (!(await ServerSession.hasRole(adminRoleId))) {\n redirect(deniedRedirect);\n }\n\n return <AnalyticsAdminPageContainer pageUrl={pageUrl} sessionPageUrl={sessionPageUrl} />;\n}\n","import { redirect } from \"next/navigation\";\n// Imported through the package's own client subpath for the same reason as in\n// AnalyticsAdminPage: the built server entry must reach the container through\n// the \"use client\" bundle, not inline it.\nimport { AnalyticsJourneyPageContainer } from \"@carlonicora/nextjs-jsonapi/analytics\";\nimport { ServerSession } from \"../../../../server\";\n\ntype Props = {\n /** Role id the viewer must hold. The package has no role constants, so the host app passes its own. */\n adminRoleId: string;\n sessionId: string;\n /** Route of the dashboard; the journey pages live under `${pageUrl}/sessions`. */\n pageUrl?: string;\n /** Where a viewer without the role is sent. */\n deniedRedirect?: string;\n};\n\n/**\n * Server page for one session's journey: role gate, then the client container.\n *\n * Reads the session: render inside a `<Suspense>` boundary (Cache Components).\n */\nexport async function AnalyticsJourneyPage({ adminRoleId, sessionId, pageUrl, deniedRedirect = \"/\" }: Props) {\n if (!(await ServerSession.hasRole(adminRoleId))) {\n redirect(deniedRedirect);\n }\n\n return <AnalyticsJourneyPageContainer sessionId={sessionId} pageUrl={pageUrl} />;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,gBAAgB;AAMzB,SAAS,mCAAmC;AAwBnC;AALT,eAAsB,mBAAmB,EAAE,aAAa,SAAS,gBAAgB,iBAAiB,IAAI,GAAU;AAC9G,MAAI,CAAE,MAAM,cAAc,QAAQ,WAAW,GAAI;AAC/C,aAAS,cAAc;AAAA,EACzB;AAEA,SAAO,oBAAC,+BAA4B,SAAkB,gBAAgC;AACxF;AANsB;;;ACzBtB,SAAS,YAAAA,iBAAgB;AAIzB,SAAS,qCAAqC;AAuBrC,gBAAAC,YAAA;AALT,eAAsB,qBAAqB,EAAE,aAAa,WAAW,SAAS,iBAAiB,IAAI,GAAU;AAC3G,MAAI,CAAE,MAAM,cAAc,QAAQ,WAAW,GAAI;AAC/C,IAAAC,UAAS,cAAc;AAAA,EACzB;AAEA,SAAO,gBAAAD,KAAC,iCAA8B,WAAsB,SAAkB;AAChF;AANsB;","names":["redirect","jsx","redirect"]}
@@ -4,8 +4,8 @@ import { H as HelpContentConfig } from '../../help-content-config.interface-C5ES
4
4
  export { a as HelpBrandConfig } from '../../help-content-config.interface-C5ESIod9.mjs';
5
5
  import { HelpHeading, HelpArticle, HelpMode } from './server.mjs';
6
6
  export { HELP_MODES, HelpRedirect } from './server.mjs';
7
- import { u as usePageUrlGenerator } from '../../usePageUrlGenerator-CCJ_cdQy.mjs';
8
- import '../../types-D0uLYV2P.mjs';
7
+ import { u as usePageUrlGenerator } from '../../usePageUrlGenerator-uKBjAKqC.mjs';
8
+ import '../../types-Bq_UA8Lg.mjs';
9
9
  import 'lucide-react';
10
10
  import '../../ApiRequestDataTypeInterface-CYEcRUrh.mjs';
11
11
 
@@ -4,8 +4,8 @@ import { H as HelpContentConfig } from '../../help-content-config.interface-C5ES
4
4
  export { a as HelpBrandConfig } from '../../help-content-config.interface-C5ESIod9.js';
5
5
  import { HelpHeading, HelpArticle, HelpMode } from './server.js';
6
6
  export { HELP_MODES, HelpRedirect } from './server.js';
7
- import { u as usePageUrlGenerator } from '../../usePageUrlGenerator-B-3FRKBD.js';
8
- import '../../types-Cn153-mH.js';
7
+ import { u as usePageUrlGenerator } from '../../usePageUrlGenerator-J_ECv-oQ.js';
8
+ import '../../types-bsm8Fp55.js';
9
9
  import 'lucide-react';
10
10
  import '../../ApiRequestDataTypeInterface-CYEcRUrh.js';
11
11
 
@@ -23,16 +23,17 @@ var _chunkYBZVWLPHjs = require('../../chunk-YBZVWLPH.js');
23
23
 
24
24
 
25
25
 
26
- var _chunkKOTKKBJTjs = require('../../chunk-KOTKKBJT.js');
26
+ var _chunkNFCXUAE6js = require('../../chunk-NFCXUAE6.js');
27
27
 
28
28
 
29
- var _chunk4Z45NYPRjs = require('../../chunk-4Z45NYPR.js');
29
+ var _chunk5W5MN7JPjs = require('../../chunk-5W5MN7JP.js');
30
+ require('../../chunk-G4JR3SFV.js');
30
31
 
31
32
 
32
- var _chunkCAKOFJZDjs = require('../../chunk-CAKOFJZD.js');
33
- require('../../chunk-26MQIJNB.js');
33
+ var _chunk6OFANJTEjs = require('../../chunk-6OFANJTE.js');
34
34
  require('../../chunk-LXKSUWAV.js');
35
35
  require('../../chunk-JTPRJNT2.js');
36
+ require('../../chunk-WGVNJXZO.js');
36
37
  require('../../chunk-3EPNHTMH.js');
37
38
 
38
39
 
@@ -43,7 +44,7 @@ var _react = require('react');
43
44
  var _jsxruntime = require('react/jsx-runtime');
44
45
  var HelpContext = _react.createContext.call(void 0, null);
45
46
  function HelpProvider({ children }) {
46
- const cfg = _chunk4Z45NYPRjs._getStaticHelpContent.call(void 0, );
47
+ const cfg = _chunk5W5MN7JPjs._getStaticHelpContent.call(void 0, );
47
48
  if (!cfg) {
48
49
  throw new Error(
49
50
  "Help content not configured \u2014 call configureJsonApi({ helpContent: {...} }) before importing help components."
@@ -75,29 +76,29 @@ var _lucidereact = require('lucide-react');
75
76
 
76
77
 
77
78
  function HelpAssistantSheet({ open, onOpenChange }) {
78
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.Sheet, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
79
- _chunkKOTKKBJTjs.SheetContent,
79
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.Sheet, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
80
+ _chunkNFCXUAE6js.SheetContent,
80
81
  {
81
82
  side: "end",
82
83
  className: "flex w-full flex-col data-[side=right]:sm:max-w-2xl data-[side=right]:lg:max-w-3xl data-[side=left]:sm:max-w-2xl data-[side=left]:lg:max-w-3xl",
83
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.AssistantProvider, { manageUrl: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HelpAssistantSheetBody, {}) })
84
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.AssistantProvider, { manageUrl: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HelpAssistantSheetBody, {}) })
84
85
  }
85
86
  ) });
86
87
  }
87
88
  _chunk7QVYU63Ejs.__name.call(void 0, HelpAssistantSheet, "HelpAssistantSheet");
88
89
  function HelpAssistantSheetBody() {
89
90
  const t = _nextintl.useTranslations.call(void 0, );
90
- const ctx = _chunkKOTKKBJTjs.useAssistantContext.call(void 0, );
91
+ const ctx = _chunkNFCXUAE6js.useAssistantContext.call(void 0, );
91
92
  const showThread = !!ctx.assistant || ctx.sending || ctx.messages.length > 0;
92
93
  const send = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (content) => ctx.sendMessage(content, { howToMode: true }), "send");
93
94
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
94
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkKOTKKBJTjs.SheetHeader, { children: [
95
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.SheetTitle, { children: t("help.askAi.sheet.title") }),
96
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.SheetDescription, { children: t("help.askAi.sheet.subtitle") })
95
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkNFCXUAE6js.SheetHeader, { children: [
96
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.SheetTitle, { children: t("help.askAi.sheet.title") }),
97
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.SheetDescription, { children: t("help.askAi.sheet.subtitle") })
97
98
  ] }),
98
- !showThread ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.AssistantEmptyState, { onSend: send }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
99
+ !showThread ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.AssistantEmptyState, { onSend: send }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
99
100
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
100
- _chunkKOTKKBJTjs.AssistantThread,
101
+ _chunkNFCXUAE6js.AssistantThread,
101
102
  {
102
103
  messages: ctx.messages,
103
104
  sending: ctx.sending,
@@ -107,7 +108,7 @@ function HelpAssistantSheetBody() {
107
108
  onRetry: ctx.retrySend
108
109
  }
109
110
  ),
110
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.AssistantComposer, { onSend: send, disabled: ctx.sending })
111
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.AssistantComposer, { onSend: send, disabled: ctx.sending })
111
112
  ] })
112
113
  ] });
113
114
  }
@@ -117,20 +118,20 @@ _chunk7QVYU63Ejs.__name.call(void 0, HelpAssistantSheetBody, "HelpAssistantSheet
117
118
 
118
119
  function HelpAskAi() {
119
120
  const t = _nextintl.useTranslations.call(void 0, );
120
- const { currentUser } = _chunkKOTKKBJTjs.useCurrentUserContext.call(void 0, );
121
+ const { currentUser } = _chunkNFCXUAE6js.useCurrentUserContext.call(void 0, );
121
122
  const [open, setOpen] = _react.useState.call(void 0, false);
122
123
  const disabled = !currentUser;
123
124
  if (disabled) {
124
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkKOTKKBJTjs.Tooltip, { children: [
125
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkKOTKKBJTjs.TooltipTrigger, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.Button, { variant: "outline", size: "sm", disabled: true }), children: [
125
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkNFCXUAE6js.Tooltip, { children: [
126
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkNFCXUAE6js.TooltipTrigger, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.Button, { variant: "outline", size: "sm", disabled: true }), children: [
126
127
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.SparklesIcon, { className: "h-4 w-4" }),
127
128
  t("help.askAi.button")
128
129
  ] }),
129
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.TooltipContent, { children: t("help.askAi.loginTooltip") })
130
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.TooltipContent, { children: t("help.askAi.loginTooltip") })
130
131
  ] });
131
132
  }
132
133
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
133
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkKOTKKBJTjs.Button, { variant: "outline", size: "sm", onClick: () => setOpen(true), children: [
134
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkNFCXUAE6js.Button, { variant: "outline", size: "sm", onClick: () => setOpen(true), children: [
134
135
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.SparklesIcon, { className: "h-4 w-4" }),
135
136
  t("help.askAi.button")
136
137
  ] }),
@@ -143,7 +144,7 @@ _chunk7QVYU63Ejs.__name.call(void 0, HelpAskAi, "HelpAskAi");
143
144
 
144
145
  function HelpHeader() {
145
146
  const t = _nextintl.useTranslations.call(void 0, );
146
- const { currentUser } = _chunkKOTKKBJTjs.useCurrentUserContext.call(void 0, );
147
+ const { currentUser } = _chunkNFCXUAE6js.useCurrentUserContext.call(void 0, );
147
148
  const { brand } = useHelp();
148
149
  const logo = _optionalChain([brand, 'optionalAccess', _ => _.logo]);
149
150
  const label = _nullishCoalesce(_optionalChain([brand, 'optionalAccess', _2 => _2.label]), () => ( "Help"));
@@ -159,7 +160,7 @@ function HelpHeader() {
159
160
  ] }),
160
161
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2 max-md:shrink-0", children: [
161
162
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HelpAskAi, {}),
162
- currentUser ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: appHref, className: _chunkKOTKKBJTjs.buttonVariants.call(void 0, { variant: "outline", size: "sm" }), children: t("help.header.openApp") }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: "/login", className: _chunkKOTKKBJTjs.buttonVariants.call(void 0, { variant: "outline", size: "sm" }), children: t("help.header.login") })
163
+ currentUser ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: appHref, className: _chunkNFCXUAE6js.buttonVariants.call(void 0, { variant: "outline", size: "sm" }), children: t("help.header.openApp") }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: "/login", className: _chunkNFCXUAE6js.buttonVariants.call(void 0, { variant: "outline", size: "sm" }), children: t("help.header.login") })
163
164
  ] })
164
165
  ] });
165
166
  }
@@ -201,12 +202,12 @@ _chunk7QVYU63Ejs.__name.call(void 0, useHelpFilter, "useHelpFilter");
201
202
 
202
203
  function HelpSideNav() {
203
204
  const t = _nextintl.useTranslations.call(void 0, );
204
- const generateUrl = _chunkKOTKKBJTjs.usePageUrlGenerator.call(void 0, );
205
+ const generateUrl = _chunkNFCXUAE6js.usePageUrlGenerator.call(void 0, );
205
206
  const pathname = _navigation.usePathname.call(void 0, );
206
207
  const [articles, setArticles] = _react.useState.call(void 0, []);
207
208
  _react.useEffect.call(void 0, () => {
208
209
  let active = true;
209
- _chunkCAKOFJZDjs.HowToService.findPublished().then((list) => active && setArticles(list)).catch(() => active && setArticles([]));
210
+ _chunk6OFANJTEjs.HowToService.findPublished().then((list) => active && setArticles(list)).catch(() => active && setArticles([]));
210
211
  return () => {
211
212
  active = false;
212
213
  };
@@ -282,7 +283,7 @@ _chunk7QVYU63Ejs.__name.call(void 0, HelpSideNav, "HelpSideNav");
282
283
  function HelpArticleBody(props) {
283
284
  const t = _nextintl.useTranslations.call(void 0, );
284
285
  const format = _nextintl.useFormatter.call(void 0, );
285
- const generateUrl = _chunkKOTKKBJTjs.usePageUrlGenerator.call(void 0, );
286
+ const generateUrl = _chunkNFCXUAE6js.usePageUrlGenerator.call(void 0, );
286
287
  const { howToType, title, summary, updatedAt, prev, next, children } = props;
287
288
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "article", { className: "prose dark:prose-invert max-w-none", children: [
288
289
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "nav", { className: "text-muted-foreground mb-2 text-xs", children: [
@@ -339,7 +340,7 @@ function HelpTOC({ headings }) {
339
340
  }, [headings]);
340
341
  if (headings.length === 0) return null;
341
342
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "nav", { "aria-label": t("help.toc.title"), className: "hidden lg:block", children: [
342
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.MicroLabel, { className: "mb-2", children: t("help.toc.title") }),
343
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.MicroLabel, { className: "mb-2", children: t("help.toc.title") }),
343
344
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "space-y-1 text-sm", children: headings.map((h) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { style: { paddingInlineStart: `${(h.depth - 2) * 0.75}rem` }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
344
345
  "a",
345
346
  {
@@ -360,13 +361,13 @@ _chunk7QVYU63Ejs.__name.call(void 0, HelpTOC, "HelpTOC");
360
361
 
361
362
  function HelpHint({ contextKey }) {
362
363
  const t = _nextintl.useTranslations.call(void 0, );
363
- const generateUrl = _chunkKOTKKBJTjs.usePageUrlGenerator.call(void 0, );
364
+ const generateUrl = _chunkNFCXUAE6js.usePageUrlGenerator.call(void 0, );
364
365
  const [open, setOpen] = _react.useState.call(void 0, false);
365
366
  const [picked, setPicked] = _react.useState.call(void 0, null);
366
367
  const [articles, setArticles] = _react.useState.call(void 0, []);
367
368
  _react.useEffect.call(void 0, () => {
368
369
  let active2 = true;
369
- _chunkCAKOFJZDjs.HowToService.findPublished().then((list) => active2 && setArticles(list)).catch(() => active2 && setArticles([]));
370
+ _chunk6OFANJTEjs.HowToService.findPublished().then((list) => active2 && setArticles(list)).catch(() => active2 && setArticles([]));
370
371
  return () => {
371
372
  active2 = false;
372
373
  };
@@ -378,7 +379,7 @@ function HelpHint({ contextKey }) {
378
379
  if (matches.length === 0) return null;
379
380
  const active = _nullishCoalesce(picked, () => ( (matches.length === 1 ? matches[0] : null)));
380
381
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
381
- _chunkKOTKKBJTjs.Sheet,
382
+ _chunkNFCXUAE6js.Sheet,
382
383
  {
383
384
  open,
384
385
  onOpenChange: (o) => {
@@ -386,11 +387,11 @@ function HelpHint({ contextKey }) {
386
387
  if (!o) setPicked(null);
387
388
  },
388
389
  children: [
389
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.SheetTrigger, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.Button, { variant: "ghost", size: "icon-sm", "aria-label": t("help.hint.trigger") }), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.HelpCircleIcon, { className: "h-4 w-4" }) }),
390
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkKOTKKBJTjs.SheetContent, { side: "end", className: "w-full max-w-md sm:max-w-lg", children: [
391
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkKOTKKBJTjs.SheetHeader, { children: [
392
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.SheetTitle, { children: active ? active.name : t("help.hint.pickArticle") }),
393
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.SheetDescription, { children: _nullishCoalesce(_optionalChain([active, 'optionalAccess', _4 => _4.summary]), () => ( "")) })
390
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.SheetTrigger, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.Button, { variant: "ghost", size: "icon-sm", "aria-label": t("help.hint.trigger") }), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.HelpCircleIcon, { className: "h-4 w-4" }) }),
391
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkNFCXUAE6js.SheetContent, { side: "end", className: "w-full max-w-md sm:max-w-lg", children: [
392
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkNFCXUAE6js.SheetHeader, { children: [
393
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.SheetTitle, { children: active ? active.name : t("help.hint.pickArticle") }),
394
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.SheetDescription, { children: _nullishCoalesce(_optionalChain([active, 'optionalAccess', _4 => _4.summary]), () => ( "")) })
394
395
  ] }),
395
396
  active ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-4 space-y-3", children: [
396
397
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground text-sm", children: active.summary }),
@@ -422,18 +423,18 @@ _chunk7QVYU63Ejs.__name.call(void 0, HelpHint, "HelpHint");
422
423
 
423
424
  function HelpSearchResultRow({ result, onSelect }) {
424
425
  const t = _nextintl.useTranslations.call(void 0, );
425
- const generateUrl = _chunkKOTKKBJTjs.usePageUrlGenerator.call(void 0, );
426
+ const generateUrl = _chunkNFCXUAE6js.usePageUrlGenerator.call(void 0, );
426
427
  const [article, setArticle] = _react.useState.call(void 0, null);
427
428
  _react.useEffect.call(void 0, () => {
428
429
  let active = true;
429
- _chunkCAKOFJZDjs.HowToService.findOne({ id: result.id }).then((a) => active && setArticle(a)).catch(() => active && setArticle(null));
430
+ _chunk6OFANJTEjs.HowToService.findOne({ id: result.id }).then((a) => active && setArticle(a)).catch(() => active && setArticle(null));
430
431
  return () => {
431
432
  active = false;
432
433
  };
433
434
  }, [result.id]);
434
435
  if (!article) {
435
436
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
436
- _chunkKOTKKBJTjs.CommandItem,
437
+ _chunkNFCXUAE6js.CommandItem,
437
438
  {
438
439
  value: result.id,
439
440
  disabled: true,
@@ -442,7 +443,7 @@ function HelpSearchResultRow({ result, onSelect }) {
442
443
  }
443
444
  );
444
445
  }
445
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKOTKKBJTjs.CommandItem, { value: result.id, onSelect, className: "cursor-pointer p-0", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
446
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNFCXUAE6js.CommandItem, { value: result.id, onSelect, className: "cursor-pointer p-0", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
446
447
  _link2.default,
447
448
  {
448
449
  href: generateUrl({ page: `/help/${article.howToType}/${article.slug}` }),
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/help/index.js","../../../src/features/help/contexts/HelpContext.tsx","../../../src/features/help/components/HelpHeader.tsx","../../../src/features/help/components/HelpAskAi.tsx","../../../src/features/help/components/HelpAssistantSheet.tsx","../../../src/features/help/components/HelpSideNav.tsx","../../../src/features/help/hooks/useHelpFilter.ts","../../../src/features/help/components/HelpArticleBody.tsx","../../../src/features/help/components/HelpTOC.tsx","../../../src/features/help/components/HelpHint.tsx","../../../src/features/help/components/HelpSearchResultRow.tsx","../../../src/features/help/utils/articleUrl.ts","../../../src/features/help/i18n-keys.ts"],"names":["jsx","useTranslations","jsxs","Fragment","useState","useMemo","Link","active"],"mappings":"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","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/help/index.js","sourcesContent":[null,"\"use client\";\nimport { createContext, useContext, ReactNode } from \"react\";\nimport { _getStaticHelpContent } from \"../../../core/registry/helpStore\";\nimport type { HelpContentConfig } from \"../interfaces/help-content-config.interface\";\n\nconst HelpContext = createContext<HelpContentConfig | null>(null);\n\nexport function HelpProvider({ children }: { children: ReactNode }) {\n const cfg = _getStaticHelpContent<HelpContentConfig>();\n if (!cfg) {\n throw new Error(\n \"Help content not configured — call configureJsonApi({ helpContent: {...} }) before importing help components.\",\n );\n }\n return <HelpContext.Provider value={cfg}>{children}</HelpContext.Provider>;\n}\n\nexport function useHelp(): HelpContentConfig {\n const ctx = useContext(HelpContext);\n if (!ctx) {\n throw new Error(\"useHelp() called outside <HelpProvider>. Wrap your help route group with <HelpProvider>.\");\n }\n return ctx;\n}\n","\"use client\";\nimport Link from \"next/link\";\nimport Image from \"next/image\";\nimport { useTranslations } from \"next-intl\";\nimport { useCurrentUserContext } from \"../../user/contexts/CurrentUserContext\";\nimport { buttonVariants } from \"../../../shadcnui\";\nimport { useHelp } from \"../contexts/HelpContext\";\nimport { HelpAskAi } from \"./HelpAskAi\";\n\nexport function HelpHeader() {\n const t = useTranslations();\n const { currentUser } = useCurrentUserContext();\n const { brand } = useHelp();\n const logo = brand?.logo;\n const label = brand?.label ?? \"Help\";\n const appHref = brand?.appHref ?? \"/\";\n\n return (\n <header className=\"border-border bg-background flex items-center justify-between border-b px-4 py-3 max-md:gap-2\">\n {/* Phone: the title shrinks and the \"· Help & Documentation\" suffix\n truncates with an ellipsis instead of wrapping onto a second line. */}\n <Link href=\"/help\" className=\"flex items-center gap-2 max-md:min-w-0\">\n {logo ? <Image src={logo} alt={label} width={28} height={28} className=\"max-md:shrink-0\" /> : null}\n <span className=\"text-base font-semibold max-md:truncate\">\n {label} · {t(\"help.footerLink\")}\n </span>\n </Link>\n <div className=\"flex items-center gap-2 max-md:shrink-0\">\n <HelpAskAi />\n {/* Styled Links, not <Button render={<Link/>} nativeButton={false}>. Base UI's\n Button primitive warns when rendered as a non-button, and nativeButton={false}\n silences that by stamping role=\"button\" onto the anchor — so a control that\n navigates would announce as a button. Both of these navigate, so they stay\n real links and only borrow the button styling. */}\n {currentUser ? (\n <Link href={appHref} className={buttonVariants({ variant: \"outline\", size: \"sm\" })}>\n {t(\"help.header.openApp\")}\n </Link>\n ) : (\n <Link href=\"/login\" className={buttonVariants({ variant: \"outline\", size: \"sm\" })}>\n {t(\"help.header.login\")}\n </Link>\n )}\n </div>\n </header>\n );\n}\n","\"use client\";\nimport { useState } from \"react\";\nimport { SparklesIcon } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { useCurrentUserContext } from \"../../user/contexts/CurrentUserContext\";\nimport { Button, Tooltip, TooltipTrigger, TooltipContent } from \"../../../shadcnui\";\nimport { HelpAssistantSheet } from \"./HelpAssistantSheet\";\n\nexport function HelpAskAi() {\n const t = useTranslations();\n const { currentUser } = useCurrentUserContext();\n const [open, setOpen] = useState(false);\n const disabled = !currentUser;\n\n if (disabled) {\n return (\n <Tooltip>\n <TooltipTrigger render={<Button variant=\"outline\" size=\"sm\" disabled />}>\n <SparklesIcon className=\"h-4 w-4\" />\n {t(\"help.askAi.button\")}\n </TooltipTrigger>\n <TooltipContent>{t(\"help.askAi.loginTooltip\")}</TooltipContent>\n </Tooltip>\n );\n }\n\n return (\n <>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setOpen(true)}>\n <SparklesIcon className=\"h-4 w-4\" />\n {t(\"help.askAi.button\")}\n </Button>\n <HelpAssistantSheet open={open} onOpenChange={setOpen} />\n </>\n );\n}\n","\"use client\";\nimport { useTranslations } from \"next-intl\";\nimport { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from \"../../../shadcnui\";\nimport { AssistantProvider, useAssistantContext } from \"../../assistant/contexts/AssistantContext\";\nimport { AssistantThread } from \"../../assistant/components/parts/AssistantThread\";\nimport { AssistantComposer } from \"../../assistant/components/parts/AssistantComposer\";\nimport { AssistantEmptyState } from \"../../assistant/components/parts/AssistantEmptyState\";\n\nexport function HelpAssistantSheet({ open, onOpenChange }: { open: boolean; onOpenChange: (o: boolean) => void }) {\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent\n side=\"end\"\n /* rtl-ok: keyed to the resolved physical side (\"right\" in LTR, \"left\" in RTL) */\n className=\"flex w-full flex-col data-[side=right]:sm:max-w-2xl data-[side=right]:lg:max-w-3xl data-[side=left]:sm:max-w-2xl data-[side=left]:lg:max-w-3xl\"\n >\n <AssistantProvider manageUrl={false}>\n <HelpAssistantSheetBody />\n </AssistantProvider>\n </SheetContent>\n </Sheet>\n );\n}\n\nfunction HelpAssistantSheetBody() {\n const t = useTranslations();\n const ctx = useAssistantContext();\n const showThread = !!ctx.assistant || ctx.sending || ctx.messages.length > 0;\n const send = (content: string) => ctx.sendMessage(content, { howToMode: true });\n\n return (\n <>\n <SheetHeader>\n <SheetTitle>{t(\"help.askAi.sheet.title\")}</SheetTitle>\n <SheetDescription>{t(\"help.askAi.sheet.subtitle\")}</SheetDescription>\n </SheetHeader>\n {!showThread ? (\n <AssistantEmptyState onSend={send} />\n ) : (\n <>\n <AssistantThread\n messages={ctx.messages}\n sending={ctx.sending}\n status={ctx.status}\n onSelectFollowUp={send}\n failedMessageIds={ctx.failedMessageIds}\n onRetry={ctx.retrySend}\n />\n <AssistantComposer onSend={send} disabled={ctx.sending} />\n </>\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useTranslations } from \"next-intl\";\nimport Link from \"next/link\";\nimport { usePathname } from \"next/navigation\";\nimport { HELP_MODES } from \"../types/help-article.types\";\nimport { usePageUrlGenerator } from \"../../../client\";\nimport { useHelpFilter } from \"../hooks/useHelpFilter\";\nimport { HowToService } from \"../../how-to/data/HowToService\";\nimport type { HowToInterface } from \"../../how-to/data/HowToInterface\";\n\nexport function HelpSideNav() {\n const t = useTranslations();\n const generateUrl = usePageUrlGenerator();\n const pathname = usePathname();\n const [articles, setArticles] = useState<HowToInterface[]>([]);\n\n useEffect(() => {\n let active = true;\n HowToService.findPublished()\n .then((list) => active && setArticles(list))\n .catch(() => active && setArticles([]));\n return () => {\n active = false;\n };\n }, []);\n\n // useHelpFilter indexes by title/summary/tags — map HowTo getters into the shape it expects.\n const indexable = useMemo(\n () =>\n articles.map((a) => ({\n id: a.id,\n title: a.name,\n summary: a.summary ?? \"\",\n tags: a.tags,\n mode: a.howToType ?? \"\",\n slug: a.slug ?? \"\",\n })),\n [articles],\n );\n const { query, setQuery, filtered } = useHelpFilter(indexable as any);\n const filtering = query.trim().length > 0;\n\n const groups = useMemo(\n () =>\n HELP_MODES.map((mode) => ({\n mode,\n articles: articles\n .filter((a) => a.howToType === mode && !a.draft)\n .sort((x, y) => (x.order ?? 0) - (y.order ?? 0)),\n })),\n [articles],\n );\n\n const isActive = (mode: string, slug: string) => pathname.endsWith(`/help/${mode}/${slug}`);\n\n return (\n <nav aria-label=\"Help navigation\" className=\"flex h-full flex-col gap-3 overflow-y-auto p-4\">\n <input\n type=\"search\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={t(\"help.sideNav.filterPlaceholder\")}\n className=\"border-input bg-background w-full rounded-md border px-3 py-2 text-sm\"\n />\n {filtering ? (\n (filtered as any[]).length === 0 ? (\n <p className=\"text-muted-foreground text-sm\">{t(\"help.sideNav.noMatches\")}</p>\n ) : (\n <ul className=\"space-y-1\">\n {(filtered as any[]).map((a) => (\n <li key={a.id}>\n <Link\n href={generateUrl({ page: `/help/${a.mode}/${a.slug}` })}\n className={\n \"hover:bg-muted block rounded px-2 py-1 text-sm \" +\n (isActive(a.mode, a.slug) ? \"bg-muted font-medium\" : \"\")\n }\n >\n {a.title}\n </Link>\n </li>\n ))}\n </ul>\n )\n ) : (\n groups.map((group) => {\n if (group.articles.length === 0) return null;\n return (\n <div key={group.mode}>\n <Link\n href={generateUrl({ page: `/help/${group.mode}` })}\n className=\"text-muted-foreground hover:text-foreground mb-1 block text-xs font-semibold tracking-wider uppercase\"\n >\n {t(`help.modes.${group.mode}`)}\n </Link>\n <ul className=\"space-y-0.5\">\n {group.articles.map((a) => (\n <li key={a.id}>\n <Link\n href={generateUrl({ page: `/help/${a.howToType}/${a.slug}` })}\n className={\n \"hover:bg-muted block rounded px-2 py-1 text-sm \" +\n (isActive(a.howToType ?? \"\", a.slug ?? \"\") ? \"bg-muted font-medium\" : \"\")\n }\n >\n {a.name}\n </Link>\n </li>\n ))}\n </ul>\n </div>\n );\n })\n )}\n </nav>\n );\n}\n","\"use client\";\nimport { useMemo, useState } from \"react\";\nimport Fuse from \"fuse.js\";\nimport type { HelpArticle } from \"../types/help-article.types\";\n\nexport function useHelpFilter(articles: readonly HelpArticle[]) {\n const [query, setQuery] = useState(\"\");\n const fuse = useMemo(\n () =>\n new Fuse([...articles], {\n keys: [\n { name: \"title\", weight: 0.5 },\n { name: \"summary\", weight: 0.3 },\n { name: \"tags\", weight: 0.1 },\n { name: \"headings.text\", weight: 0.1 },\n ],\n threshold: 0.4,\n ignoreLocation: true,\n }),\n [articles],\n );\n const filtered = useMemo(() => {\n if (!query.trim()) return [...articles];\n return fuse.search(query).map((r) => r.item);\n }, [query, articles, fuse]);\n return { query, setQuery, filtered };\n}\n","\"use client\";\n\nimport { ReactNode } from \"react\";\nimport Link from \"next/link\";\nimport { useFormatter, useTranslations } from \"next-intl\";\nimport { usePageUrlGenerator } from \"../../../client\";\n\ntype Sibling = { howToType: string; slug: string; title: string };\n\nexport function HelpArticleBody(props: {\n howToType: string;\n title: string;\n summary?: string;\n updatedAt?: string;\n prev?: Sibling | null;\n next?: Sibling | null;\n children: ReactNode;\n}) {\n const t = useTranslations();\n const format = useFormatter();\n const generateUrl = usePageUrlGenerator();\n const { howToType, title, summary, updatedAt, prev, next, children } = props;\n\n return (\n <article className=\"prose dark:prose-invert max-w-none\">\n <nav className=\"text-muted-foreground mb-2 text-xs\">\n <Link href={generateUrl({ page: \"/help\" })}>Help</Link>\n {\" · \"}\n <Link href={generateUrl({ page: `/help/${howToType}` })}>{t(`help.modes.${howToType}`)}</Link>\n </nav>\n <h1>{title}</h1>\n {summary ? <p className=\"text-muted-foreground !mt-0 text-base\">{summary}</p> : null}\n {children}\n <hr className=\"my-6\" />\n {updatedAt ? (\n <div className=\"text-muted-foreground text-xs\">\n <span>\n {t(\"help.article.lastUpdated\", {\n date: format.dateTime(new Date(updatedAt), { dateStyle: \"short\" }),\n })}\n </span>\n </div>\n ) : null}\n <div className=\"mt-4 flex justify-between text-sm\">\n {prev ? (\n <Link href={generateUrl({ page: `/help/${prev.howToType}/${prev.slug}` })}>\n ← {t(\"help.article.previous\")}: {prev.title}\n </Link>\n ) : (\n <span />\n )}\n {next ? (\n <Link href={generateUrl({ page: `/help/${next.howToType}/${next.slug}` })}>\n {t(\"help.article.next\")}: {next.title} →\n </Link>\n ) : (\n <span />\n )}\n </div>\n </article>\n );\n}\n","\"use client\";\nimport { useEffect, useState } from \"react\";\nimport { useTranslations } from \"next-intl\";\nimport type { HelpHeading } from \"../types/help-article.types\";\nimport { MicroLabel } from \"../../../components/typography\";\n\nexport function HelpTOC({ headings }: { headings: readonly HelpHeading[] }) {\n const t = useTranslations();\n const [active, setActive] = useState<string | null>(null);\n\n useEffect(() => {\n const observer = new IntersectionObserver(\n (entries) => {\n for (const e of entries) {\n if (e.isIntersecting) setActive(e.target.id);\n }\n },\n { rootMargin: \"0px 0px -70% 0px\", threshold: 0 },\n );\n headings.forEach((h) => {\n const el = document.getElementById(h.slug);\n if (el) observer.observe(el);\n });\n return () => observer.disconnect();\n }, [headings]);\n\n if (headings.length === 0) return null;\n return (\n <nav aria-label={t(\"help.toc.title\")} className=\"hidden lg:block\">\n <MicroLabel className=\"mb-2\">{t(\"help.toc.title\")}</MicroLabel>\n <ul className=\"space-y-1 text-sm\">\n {headings.map((h) => (\n <li key={h.slug} style={{ paddingInlineStart: `${(h.depth - 2) * 0.75}rem` }}>\n <a\n href={`#${h.slug}`}\n className={\n \"block truncate hover:text-foreground \" +\n (active === h.slug ? \"text-foreground font-medium\" : \"text-muted-foreground\")\n }\n >\n {h.text}\n </a>\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n","\"use client\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useTranslations } from \"next-intl\";\nimport Link from \"next/link\";\nimport { HelpCircleIcon } from \"lucide-react\";\nimport {\n Button,\n Sheet,\n SheetContent,\n SheetTrigger,\n SheetHeader,\n SheetTitle,\n SheetDescription,\n} from \"../../../shadcnui\";\nimport { usePageUrlGenerator } from \"../../../client\";\nimport { HowToService } from \"../../how-to/data/HowToService\";\nimport type { HowToInterface } from \"../../how-to/data/HowToInterface\";\n\nexport function HelpHint({ contextKey }: { contextKey: string }) {\n const t = useTranslations();\n const generateUrl = usePageUrlGenerator();\n const [open, setOpen] = useState(false);\n const [picked, setPicked] = useState<HowToInterface | null>(null);\n\n const [articles, setArticles] = useState<HowToInterface[]>([]);\n useEffect(() => {\n let active = true;\n HowToService.findPublished()\n .then((list) => active && setArticles(list))\n .catch(() => active && setArticles([]));\n return () => {\n active = false;\n };\n }, []);\n\n const matches = useMemo(\n () => articles.filter((a) => a.contextualKeys.includes(contextKey) && !a.draft),\n [articles, contextKey],\n );\n\n if (matches.length === 0) return null;\n const active = picked ?? (matches.length === 1 ? matches[0] : null);\n\n return (\n <Sheet\n open={open}\n onOpenChange={(o) => {\n setOpen(o);\n if (!o) setPicked(null);\n }}\n >\n <SheetTrigger render={<Button variant=\"ghost\" size=\"icon-sm\" aria-label={t(\"help.hint.trigger\")} />}>\n <HelpCircleIcon className=\"h-4 w-4\" />\n </SheetTrigger>\n <SheetContent side=\"end\" className=\"w-full max-w-md sm:max-w-lg\">\n <SheetHeader>\n <SheetTitle>{active ? active.name : t(\"help.hint.pickArticle\")}</SheetTitle>\n <SheetDescription>{active?.summary ?? \"\"}</SheetDescription>\n </SheetHeader>\n {active ? (\n <div className=\"mt-4 space-y-3\">\n <p className=\"text-muted-foreground text-sm\">{active.summary}</p>\n <Link href={generateUrl({ page: `/help/${active.howToType}/${active.slug}` })} className=\"text-sm\">\n {t(\"help.hint.viewArticle\")}\n </Link>\n </div>\n ) : (\n <ul className=\"mt-4 space-y-1\">\n {matches.map((a) => (\n <li key={a.id}>\n <button\n type=\"button\"\n onClick={() => setPicked(a)}\n className=\"hover:bg-muted block w-full rounded px-2 py-1 text-start text-sm\"\n >\n <div className=\"font-medium\">{a.name}</div>\n <div className=\"text-muted-foreground text-xs\">{a.summary}</div>\n </button>\n </li>\n ))}\n </ul>\n )}\n </SheetContent>\n </Sheet>\n );\n}\n","\"use client\";\nimport Link from \"next/link\";\nimport { useTranslations } from \"next-intl\";\nimport { useEffect, useState } from \"react\";\nimport { LifeBuoyIcon, ArrowUpRightIcon } from \"lucide-react\";\nimport { CommandItem } from \"../../../shadcnui\";\nimport { usePageUrlGenerator } from \"../../../client\";\nimport { HowToService } from \"../../how-to/data/HowToService\";\nimport type { HowToInterface } from \"../../how-to/data/HowToInterface\";\n\nexport interface HelpSearchResultRowProps {\n result: { id: string; name: string; entityType: string };\n onSelect?: () => void;\n}\n\nexport function HelpSearchResultRow({ result, onSelect }: HelpSearchResultRowProps) {\n const t = useTranslations();\n const generateUrl = usePageUrlGenerator();\n const [article, setArticle] = useState<HowToInterface | null>(null);\n useEffect(() => {\n let active = true;\n HowToService.findOne({ id: result.id })\n .then((a) => active && setArticle(a))\n .catch(() => active && setArticle(null));\n return () => {\n active = false;\n };\n }, [result.id]);\n\n if (!article) {\n return (\n <CommandItem\n value={result.id}\n disabled\n className=\"text-muted-foreground cursor-not-allowed px-3 py-1.5 text-sm italic\"\n >\n {t(\"help.search.removed\")}\n </CommandItem>\n );\n }\n\n return (\n <CommandItem value={result.id} onSelect={onSelect} className=\"cursor-pointer p-0\">\n <Link\n href={generateUrl({ page: `/help/${article.howToType}/${article.slug}` })}\n className=\"hover:bg-muted flex w-full items-center gap-3 rounded px-3 py-2\"\n >\n <div className=\"bg-muted text-muted-foreground flex h-10 w-10 shrink-0 items-center justify-center rounded-full\">\n <LifeBuoyIcon className=\"h-5 w-5\" />\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"text-foreground truncate text-sm font-semibold\">{article.name}</span>\n <span className=\"text-muted-foreground truncate text-xs\">\n {t(`help.modes.${article.howToType}`)} · {article.summary}\n </span>\n </div>\n <ArrowUpRightIcon className=\"text-muted-foreground h-5 w-5 shrink-0\" />\n </Link>\n </CommandItem>\n );\n}\n","import type { HelpMode } from \"../types/help-article.types\";\nimport type { usePageUrlGenerator } from \"../../../client\";\n\nexport function articleUrl(\n generateUrl: ReturnType<typeof usePageUrlGenerator>,\n article: { mode: HelpMode; slug: string },\n): string {\n return generateUrl({ page: `/help/${article.mode}/${article.slug}` });\n}\n\nexport function modeUrl(generateUrl: ReturnType<typeof usePageUrlGenerator>, mode: HelpMode): string {\n return generateUrl({ page: `/help/${mode}` });\n}\n","/**\n * The fixed namespace of i18n keys this feature reads via useTranslations/getTranslations.\n * Consuming apps must define each entry in their messages/<locale>.json.\n */\nexport const HELP_I18N_KEYS = [\n \"help.modes.tutorial\",\n \"help.modes.how-to\",\n \"help.modes.reference\",\n \"help.modes.explanation\",\n \"help.sideNav.filterPlaceholder\",\n \"help.sideNav.noMatches\",\n \"help.toc.title\",\n \"help.article.lastUpdated\",\n \"help.article.previous\",\n \"help.article.next\",\n \"help.article.related\",\n \"help.askAi.button\",\n \"help.askAi.loginTooltip\",\n \"help.askAi.sheet.title\",\n \"help.askAi.sheet.subtitle\",\n \"help.header.search\",\n \"help.header.login\",\n \"help.header.openApp\",\n \"help.hint.trigger\",\n \"help.hint.viewArticle\",\n \"help.hint.pickArticle\",\n \"help.landing.heading\",\n \"help.landing.subheading\",\n \"help.landing.featuredTutorials\",\n \"help.landing.browseByMode\",\n \"help.modeIndex.empty\",\n \"help.search.removed\",\n \"help.footerLink\",\n] as const;\n"]}
1
+ {"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/help/index.js","../../../src/features/help/contexts/HelpContext.tsx","../../../src/features/help/components/HelpHeader.tsx","../../../src/features/help/components/HelpAskAi.tsx","../../../src/features/help/components/HelpAssistantSheet.tsx","../../../src/features/help/components/HelpSideNav.tsx","../../../src/features/help/hooks/useHelpFilter.ts","../../../src/features/help/components/HelpArticleBody.tsx","../../../src/features/help/components/HelpTOC.tsx","../../../src/features/help/components/HelpHint.tsx","../../../src/features/help/components/HelpSearchResultRow.tsx","../../../src/features/help/utils/articleUrl.ts","../../../src/features/help/i18n-keys.ts"],"names":["jsx","useTranslations","jsxs","Fragment","useState","useMemo","Link","active"],"mappings":"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","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/help/index.js","sourcesContent":[null,"\"use client\";\nimport { createContext, useContext, ReactNode } from \"react\";\nimport { _getStaticHelpContent } from \"../../../core/registry/helpStore\";\nimport type { HelpContentConfig } from \"../interfaces/help-content-config.interface\";\n\nconst HelpContext = createContext<HelpContentConfig | null>(null);\n\nexport function HelpProvider({ children }: { children: ReactNode }) {\n const cfg = _getStaticHelpContent<HelpContentConfig>();\n if (!cfg) {\n throw new Error(\n \"Help content not configured — call configureJsonApi({ helpContent: {...} }) before importing help components.\",\n );\n }\n return <HelpContext.Provider value={cfg}>{children}</HelpContext.Provider>;\n}\n\nexport function useHelp(): HelpContentConfig {\n const ctx = useContext(HelpContext);\n if (!ctx) {\n throw new Error(\"useHelp() called outside <HelpProvider>. Wrap your help route group with <HelpProvider>.\");\n }\n return ctx;\n}\n","\"use client\";\nimport Link from \"next/link\";\nimport Image from \"next/image\";\nimport { useTranslations } from \"next-intl\";\nimport { useCurrentUserContext } from \"../../user/contexts/CurrentUserContext\";\nimport { buttonVariants } from \"../../../shadcnui\";\nimport { useHelp } from \"../contexts/HelpContext\";\nimport { HelpAskAi } from \"./HelpAskAi\";\n\nexport function HelpHeader() {\n const t = useTranslations();\n const { currentUser } = useCurrentUserContext();\n const { brand } = useHelp();\n const logo = brand?.logo;\n const label = brand?.label ?? \"Help\";\n const appHref = brand?.appHref ?? \"/\";\n\n return (\n <header className=\"border-border bg-background flex items-center justify-between border-b px-4 py-3 max-md:gap-2\">\n {/* Phone: the title shrinks and the \"· Help & Documentation\" suffix\n truncates with an ellipsis instead of wrapping onto a second line. */}\n <Link href=\"/help\" className=\"flex items-center gap-2 max-md:min-w-0\">\n {logo ? <Image src={logo} alt={label} width={28} height={28} className=\"max-md:shrink-0\" /> : null}\n <span className=\"text-base font-semibold max-md:truncate\">\n {label} · {t(\"help.footerLink\")}\n </span>\n </Link>\n <div className=\"flex items-center gap-2 max-md:shrink-0\">\n <HelpAskAi />\n {/* Styled Links, not <Button render={<Link/>} nativeButton={false}>. Base UI's\n Button primitive warns when rendered as a non-button, and nativeButton={false}\n silences that by stamping role=\"button\" onto the anchor — so a control that\n navigates would announce as a button. Both of these navigate, so they stay\n real links and only borrow the button styling. */}\n {currentUser ? (\n <Link href={appHref} className={buttonVariants({ variant: \"outline\", size: \"sm\" })}>\n {t(\"help.header.openApp\")}\n </Link>\n ) : (\n <Link href=\"/login\" className={buttonVariants({ variant: \"outline\", size: \"sm\" })}>\n {t(\"help.header.login\")}\n </Link>\n )}\n </div>\n </header>\n );\n}\n","\"use client\";\nimport { useState } from \"react\";\nimport { SparklesIcon } from \"lucide-react\";\nimport { useTranslations } from \"next-intl\";\nimport { useCurrentUserContext } from \"../../user/contexts/CurrentUserContext\";\nimport { Button, Tooltip, TooltipTrigger, TooltipContent } from \"../../../shadcnui\";\nimport { HelpAssistantSheet } from \"./HelpAssistantSheet\";\n\nexport function HelpAskAi() {\n const t = useTranslations();\n const { currentUser } = useCurrentUserContext();\n const [open, setOpen] = useState(false);\n const disabled = !currentUser;\n\n if (disabled) {\n return (\n <Tooltip>\n <TooltipTrigger render={<Button variant=\"outline\" size=\"sm\" disabled />}>\n <SparklesIcon className=\"h-4 w-4\" />\n {t(\"help.askAi.button\")}\n </TooltipTrigger>\n <TooltipContent>{t(\"help.askAi.loginTooltip\")}</TooltipContent>\n </Tooltip>\n );\n }\n\n return (\n <>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setOpen(true)}>\n <SparklesIcon className=\"h-4 w-4\" />\n {t(\"help.askAi.button\")}\n </Button>\n <HelpAssistantSheet open={open} onOpenChange={setOpen} />\n </>\n );\n}\n","\"use client\";\nimport { useTranslations } from \"next-intl\";\nimport { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from \"../../../shadcnui\";\nimport { AssistantProvider, useAssistantContext } from \"../../assistant/contexts/AssistantContext\";\nimport { AssistantThread } from \"../../assistant/components/parts/AssistantThread\";\nimport { AssistantComposer } from \"../../assistant/components/parts/AssistantComposer\";\nimport { AssistantEmptyState } from \"../../assistant/components/parts/AssistantEmptyState\";\n\nexport function HelpAssistantSheet({ open, onOpenChange }: { open: boolean; onOpenChange: (o: boolean) => void }) {\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent\n side=\"end\"\n /* rtl-ok: keyed to the resolved physical side (\"right\" in LTR, \"left\" in RTL) */\n className=\"flex w-full flex-col data-[side=right]:sm:max-w-2xl data-[side=right]:lg:max-w-3xl data-[side=left]:sm:max-w-2xl data-[side=left]:lg:max-w-3xl\"\n >\n <AssistantProvider manageUrl={false}>\n <HelpAssistantSheetBody />\n </AssistantProvider>\n </SheetContent>\n </Sheet>\n );\n}\n\nfunction HelpAssistantSheetBody() {\n const t = useTranslations();\n const ctx = useAssistantContext();\n const showThread = !!ctx.assistant || ctx.sending || ctx.messages.length > 0;\n const send = (content: string) => ctx.sendMessage(content, { howToMode: true });\n\n return (\n <>\n <SheetHeader>\n <SheetTitle>{t(\"help.askAi.sheet.title\")}</SheetTitle>\n <SheetDescription>{t(\"help.askAi.sheet.subtitle\")}</SheetDescription>\n </SheetHeader>\n {!showThread ? (\n <AssistantEmptyState onSend={send} />\n ) : (\n <>\n <AssistantThread\n messages={ctx.messages}\n sending={ctx.sending}\n status={ctx.status}\n onSelectFollowUp={send}\n failedMessageIds={ctx.failedMessageIds}\n onRetry={ctx.retrySend}\n />\n <AssistantComposer onSend={send} disabled={ctx.sending} />\n </>\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useTranslations } from \"next-intl\";\nimport Link from \"next/link\";\nimport { usePathname } from \"next/navigation\";\nimport { HELP_MODES } from \"../types/help-article.types\";\nimport { usePageUrlGenerator } from \"../../../client\";\nimport { useHelpFilter } from \"../hooks/useHelpFilter\";\nimport { HowToService } from \"../../how-to/data/HowToService\";\nimport type { HowToInterface } from \"../../how-to/data/HowToInterface\";\n\nexport function HelpSideNav() {\n const t = useTranslations();\n const generateUrl = usePageUrlGenerator();\n const pathname = usePathname();\n const [articles, setArticles] = useState<HowToInterface[]>([]);\n\n useEffect(() => {\n let active = true;\n HowToService.findPublished()\n .then((list) => active && setArticles(list))\n .catch(() => active && setArticles([]));\n return () => {\n active = false;\n };\n }, []);\n\n // useHelpFilter indexes by title/summary/tags — map HowTo getters into the shape it expects.\n const indexable = useMemo(\n () =>\n articles.map((a) => ({\n id: a.id,\n title: a.name,\n summary: a.summary ?? \"\",\n tags: a.tags,\n mode: a.howToType ?? \"\",\n slug: a.slug ?? \"\",\n })),\n [articles],\n );\n const { query, setQuery, filtered } = useHelpFilter(indexable as any);\n const filtering = query.trim().length > 0;\n\n const groups = useMemo(\n () =>\n HELP_MODES.map((mode) => ({\n mode,\n articles: articles\n .filter((a) => a.howToType === mode && !a.draft)\n .sort((x, y) => (x.order ?? 0) - (y.order ?? 0)),\n })),\n [articles],\n );\n\n const isActive = (mode: string, slug: string) => pathname.endsWith(`/help/${mode}/${slug}`);\n\n return (\n <nav aria-label=\"Help navigation\" className=\"flex h-full flex-col gap-3 overflow-y-auto p-4\">\n <input\n type=\"search\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={t(\"help.sideNav.filterPlaceholder\")}\n className=\"border-input bg-background w-full rounded-md border px-3 py-2 text-sm\"\n />\n {filtering ? (\n (filtered as any[]).length === 0 ? (\n <p className=\"text-muted-foreground text-sm\">{t(\"help.sideNav.noMatches\")}</p>\n ) : (\n <ul className=\"space-y-1\">\n {(filtered as any[]).map((a) => (\n <li key={a.id}>\n <Link\n href={generateUrl({ page: `/help/${a.mode}/${a.slug}` })}\n className={\n \"hover:bg-muted block rounded px-2 py-1 text-sm \" +\n (isActive(a.mode, a.slug) ? \"bg-muted font-medium\" : \"\")\n }\n >\n {a.title}\n </Link>\n </li>\n ))}\n </ul>\n )\n ) : (\n groups.map((group) => {\n if (group.articles.length === 0) return null;\n return (\n <div key={group.mode}>\n <Link\n href={generateUrl({ page: `/help/${group.mode}` })}\n className=\"text-muted-foreground hover:text-foreground mb-1 block text-xs font-semibold tracking-wider uppercase\"\n >\n {t(`help.modes.${group.mode}`)}\n </Link>\n <ul className=\"space-y-0.5\">\n {group.articles.map((a) => (\n <li key={a.id}>\n <Link\n href={generateUrl({ page: `/help/${a.howToType}/${a.slug}` })}\n className={\n \"hover:bg-muted block rounded px-2 py-1 text-sm \" +\n (isActive(a.howToType ?? \"\", a.slug ?? \"\") ? \"bg-muted font-medium\" : \"\")\n }\n >\n {a.name}\n </Link>\n </li>\n ))}\n </ul>\n </div>\n );\n })\n )}\n </nav>\n );\n}\n","\"use client\";\nimport { useMemo, useState } from \"react\";\nimport Fuse from \"fuse.js\";\nimport type { HelpArticle } from \"../types/help-article.types\";\n\nexport function useHelpFilter(articles: readonly HelpArticle[]) {\n const [query, setQuery] = useState(\"\");\n const fuse = useMemo(\n () =>\n new Fuse([...articles], {\n keys: [\n { name: \"title\", weight: 0.5 },\n { name: \"summary\", weight: 0.3 },\n { name: \"tags\", weight: 0.1 },\n { name: \"headings.text\", weight: 0.1 },\n ],\n threshold: 0.4,\n ignoreLocation: true,\n }),\n [articles],\n );\n const filtered = useMemo(() => {\n if (!query.trim()) return [...articles];\n return fuse.search(query).map((r) => r.item);\n }, [query, articles, fuse]);\n return { query, setQuery, filtered };\n}\n","\"use client\";\n\nimport { ReactNode } from \"react\";\nimport Link from \"next/link\";\nimport { useFormatter, useTranslations } from \"next-intl\";\nimport { usePageUrlGenerator } from \"../../../client\";\n\ntype Sibling = { howToType: string; slug: string; title: string };\n\nexport function HelpArticleBody(props: {\n howToType: string;\n title: string;\n summary?: string;\n updatedAt?: string;\n prev?: Sibling | null;\n next?: Sibling | null;\n children: ReactNode;\n}) {\n const t = useTranslations();\n const format = useFormatter();\n const generateUrl = usePageUrlGenerator();\n const { howToType, title, summary, updatedAt, prev, next, children } = props;\n\n return (\n <article className=\"prose dark:prose-invert max-w-none\">\n <nav className=\"text-muted-foreground mb-2 text-xs\">\n <Link href={generateUrl({ page: \"/help\" })}>Help</Link>\n {\" · \"}\n <Link href={generateUrl({ page: `/help/${howToType}` })}>{t(`help.modes.${howToType}`)}</Link>\n </nav>\n <h1>{title}</h1>\n {summary ? <p className=\"text-muted-foreground !mt-0 text-base\">{summary}</p> : null}\n {children}\n <hr className=\"my-6\" />\n {updatedAt ? (\n <div className=\"text-muted-foreground text-xs\">\n <span>\n {t(\"help.article.lastUpdated\", {\n date: format.dateTime(new Date(updatedAt), { dateStyle: \"short\" }),\n })}\n </span>\n </div>\n ) : null}\n <div className=\"mt-4 flex justify-between text-sm\">\n {prev ? (\n <Link href={generateUrl({ page: `/help/${prev.howToType}/${prev.slug}` })}>\n ← {t(\"help.article.previous\")}: {prev.title}\n </Link>\n ) : (\n <span />\n )}\n {next ? (\n <Link href={generateUrl({ page: `/help/${next.howToType}/${next.slug}` })}>\n {t(\"help.article.next\")}: {next.title} →\n </Link>\n ) : (\n <span />\n )}\n </div>\n </article>\n );\n}\n","\"use client\";\nimport { useEffect, useState } from \"react\";\nimport { useTranslations } from \"next-intl\";\nimport type { HelpHeading } from \"../types/help-article.types\";\nimport { MicroLabel } from \"../../../components/typography\";\n\nexport function HelpTOC({ headings }: { headings: readonly HelpHeading[] }) {\n const t = useTranslations();\n const [active, setActive] = useState<string | null>(null);\n\n useEffect(() => {\n const observer = new IntersectionObserver(\n (entries) => {\n for (const e of entries) {\n if (e.isIntersecting) setActive(e.target.id);\n }\n },\n { rootMargin: \"0px 0px -70% 0px\", threshold: 0 },\n );\n headings.forEach((h) => {\n const el = document.getElementById(h.slug);\n if (el) observer.observe(el);\n });\n return () => observer.disconnect();\n }, [headings]);\n\n if (headings.length === 0) return null;\n return (\n <nav aria-label={t(\"help.toc.title\")} className=\"hidden lg:block\">\n <MicroLabel className=\"mb-2\">{t(\"help.toc.title\")}</MicroLabel>\n <ul className=\"space-y-1 text-sm\">\n {headings.map((h) => (\n <li key={h.slug} style={{ paddingInlineStart: `${(h.depth - 2) * 0.75}rem` }}>\n <a\n href={`#${h.slug}`}\n className={\n \"block truncate hover:text-foreground \" +\n (active === h.slug ? \"text-foreground font-medium\" : \"text-muted-foreground\")\n }\n >\n {h.text}\n </a>\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n","\"use client\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useTranslations } from \"next-intl\";\nimport Link from \"next/link\";\nimport { HelpCircleIcon } from \"lucide-react\";\nimport {\n Button,\n Sheet,\n SheetContent,\n SheetTrigger,\n SheetHeader,\n SheetTitle,\n SheetDescription,\n} from \"../../../shadcnui\";\nimport { usePageUrlGenerator } from \"../../../client\";\nimport { HowToService } from \"../../how-to/data/HowToService\";\nimport type { HowToInterface } from \"../../how-to/data/HowToInterface\";\n\nexport function HelpHint({ contextKey }: { contextKey: string }) {\n const t = useTranslations();\n const generateUrl = usePageUrlGenerator();\n const [open, setOpen] = useState(false);\n const [picked, setPicked] = useState<HowToInterface | null>(null);\n\n const [articles, setArticles] = useState<HowToInterface[]>([]);\n useEffect(() => {\n let active = true;\n HowToService.findPublished()\n .then((list) => active && setArticles(list))\n .catch(() => active && setArticles([]));\n return () => {\n active = false;\n };\n }, []);\n\n const matches = useMemo(\n () => articles.filter((a) => a.contextualKeys.includes(contextKey) && !a.draft),\n [articles, contextKey],\n );\n\n if (matches.length === 0) return null;\n const active = picked ?? (matches.length === 1 ? matches[0] : null);\n\n return (\n <Sheet\n open={open}\n onOpenChange={(o) => {\n setOpen(o);\n if (!o) setPicked(null);\n }}\n >\n <SheetTrigger render={<Button variant=\"ghost\" size=\"icon-sm\" aria-label={t(\"help.hint.trigger\")} />}>\n <HelpCircleIcon className=\"h-4 w-4\" />\n </SheetTrigger>\n <SheetContent side=\"end\" className=\"w-full max-w-md sm:max-w-lg\">\n <SheetHeader>\n <SheetTitle>{active ? active.name : t(\"help.hint.pickArticle\")}</SheetTitle>\n <SheetDescription>{active?.summary ?? \"\"}</SheetDescription>\n </SheetHeader>\n {active ? (\n <div className=\"mt-4 space-y-3\">\n <p className=\"text-muted-foreground text-sm\">{active.summary}</p>\n <Link href={generateUrl({ page: `/help/${active.howToType}/${active.slug}` })} className=\"text-sm\">\n {t(\"help.hint.viewArticle\")}\n </Link>\n </div>\n ) : (\n <ul className=\"mt-4 space-y-1\">\n {matches.map((a) => (\n <li key={a.id}>\n <button\n type=\"button\"\n onClick={() => setPicked(a)}\n className=\"hover:bg-muted block w-full rounded px-2 py-1 text-start text-sm\"\n >\n <div className=\"font-medium\">{a.name}</div>\n <div className=\"text-muted-foreground text-xs\">{a.summary}</div>\n </button>\n </li>\n ))}\n </ul>\n )}\n </SheetContent>\n </Sheet>\n );\n}\n","\"use client\";\nimport Link from \"next/link\";\nimport { useTranslations } from \"next-intl\";\nimport { useEffect, useState } from \"react\";\nimport { LifeBuoyIcon, ArrowUpRightIcon } from \"lucide-react\";\nimport { CommandItem } from \"../../../shadcnui\";\nimport { usePageUrlGenerator } from \"../../../client\";\nimport { HowToService } from \"../../how-to/data/HowToService\";\nimport type { HowToInterface } from \"../../how-to/data/HowToInterface\";\n\nexport interface HelpSearchResultRowProps {\n result: { id: string; name: string; entityType: string };\n onSelect?: () => void;\n}\n\nexport function HelpSearchResultRow({ result, onSelect }: HelpSearchResultRowProps) {\n const t = useTranslations();\n const generateUrl = usePageUrlGenerator();\n const [article, setArticle] = useState<HowToInterface | null>(null);\n useEffect(() => {\n let active = true;\n HowToService.findOne({ id: result.id })\n .then((a) => active && setArticle(a))\n .catch(() => active && setArticle(null));\n return () => {\n active = false;\n };\n }, [result.id]);\n\n if (!article) {\n return (\n <CommandItem\n value={result.id}\n disabled\n className=\"text-muted-foreground cursor-not-allowed px-3 py-1.5 text-sm italic\"\n >\n {t(\"help.search.removed\")}\n </CommandItem>\n );\n }\n\n return (\n <CommandItem value={result.id} onSelect={onSelect} className=\"cursor-pointer p-0\">\n <Link\n href={generateUrl({ page: `/help/${article.howToType}/${article.slug}` })}\n className=\"hover:bg-muted flex w-full items-center gap-3 rounded px-3 py-2\"\n >\n <div className=\"bg-muted text-muted-foreground flex h-10 w-10 shrink-0 items-center justify-center rounded-full\">\n <LifeBuoyIcon className=\"h-5 w-5\" />\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"text-foreground truncate text-sm font-semibold\">{article.name}</span>\n <span className=\"text-muted-foreground truncate text-xs\">\n {t(`help.modes.${article.howToType}`)} · {article.summary}\n </span>\n </div>\n <ArrowUpRightIcon className=\"text-muted-foreground h-5 w-5 shrink-0\" />\n </Link>\n </CommandItem>\n );\n}\n","import type { HelpMode } from \"../types/help-article.types\";\nimport type { usePageUrlGenerator } from \"../../../client\";\n\nexport function articleUrl(\n generateUrl: ReturnType<typeof usePageUrlGenerator>,\n article: { mode: HelpMode; slug: string },\n): string {\n return generateUrl({ page: `/help/${article.mode}/${article.slug}` });\n}\n\nexport function modeUrl(generateUrl: ReturnType<typeof usePageUrlGenerator>, mode: HelpMode): string {\n return generateUrl({ page: `/help/${mode}` });\n}\n","/**\n * The fixed namespace of i18n keys this feature reads via useTranslations/getTranslations.\n * Consuming apps must define each entry in their messages/<locale>.json.\n */\nexport const HELP_I18N_KEYS = [\n \"help.modes.tutorial\",\n \"help.modes.how-to\",\n \"help.modes.reference\",\n \"help.modes.explanation\",\n \"help.sideNav.filterPlaceholder\",\n \"help.sideNav.noMatches\",\n \"help.toc.title\",\n \"help.article.lastUpdated\",\n \"help.article.previous\",\n \"help.article.next\",\n \"help.article.related\",\n \"help.askAi.button\",\n \"help.askAi.loginTooltip\",\n \"help.askAi.sheet.title\",\n \"help.askAi.sheet.subtitle\",\n \"help.header.search\",\n \"help.header.login\",\n \"help.header.openApp\",\n \"help.hint.trigger\",\n \"help.hint.viewArticle\",\n \"help.hint.pickArticle\",\n \"help.landing.heading\",\n \"help.landing.subheading\",\n \"help.landing.featuredTutorials\",\n \"help.landing.browseByMode\",\n \"help.modeIndex.empty\",\n \"help.search.removed\",\n \"help.footerLink\",\n] as const;\n"]}
@@ -23,16 +23,17 @@ import {
23
23
  useAssistantContext,
24
24
  useCurrentUserContext,
25
25
  usePageUrlGenerator
26
- } from "../../chunk-HPUV6FBW.mjs";
26
+ } from "../../chunk-WJC4SYRL.mjs";
27
27
  import {
28
28
  _getStaticHelpContent
29
- } from "../../chunk-Q6J2ICKO.mjs";
29
+ } from "../../chunk-ADZSH3MG.mjs";
30
+ import "../../chunk-PW42LRSL.mjs";
30
31
  import {
31
32
  HowToService
32
- } from "../../chunk-E3I4MT53.mjs";
33
- import "../../chunk-37DMFVLN.mjs";
33
+ } from "../../chunk-AQZ3T4BR.mjs";
34
34
  import "../../chunk-AUXK7QSA.mjs";
35
35
  import "../../chunk-PI56A4DG.mjs";
36
+ import "../../chunk-7SCREMTX.mjs";
36
37
  import "../../chunk-VOXD3ZLY.mjs";
37
38
  import {
38
39
  __name