@carlonicora/nextjs-jsonapi 1.108.0 → 1.110.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 (144) hide show
  1. package/dist/{AssistantInterface-BYgI5z1-.d.mts → AssistantInterface-B1c8FhGA.d.mts} +2 -0
  2. package/dist/{AssistantInterface-DfDcz0gJ.d.ts → AssistantInterface-BBUHxOCd.d.ts} +2 -0
  3. package/dist/{AssistantMessageInterface-BpEhx2pC.d.ts → AssistantMessageInterface-BNzf1etU.d.ts} +16 -1
  4. package/dist/{AssistantMessageInterface-DJ3Me16Y.d.mts → AssistantMessageInterface-DrgHDjZ5.d.mts} +16 -1
  5. package/dist/{AuthComponent-B6DIk8Vf.d.ts → AuthComponent-Cd7lcYif.d.ts} +1 -1
  6. package/dist/{AuthComponent-BKI0ZbtD.d.mts → AuthComponent-DdxCFgUZ.d.mts} +1 -1
  7. package/dist/{BlockNoteEditor-2AXSTGGG.js → BlockNoteEditor-7OKW6HHN.js} +19 -19
  8. package/dist/{BlockNoteEditor-2AXSTGGG.js.map → BlockNoteEditor-7OKW6HHN.js.map} +1 -1
  9. package/dist/{BlockNoteEditor-XVIBGXHF.mjs → BlockNoteEditor-K7IIWM3S.mjs} +4 -4
  10. package/dist/BlockNoteViewer-OPSCTHKJ.mjs +31 -0
  11. package/dist/BlockNoteViewer-OPSCTHKJ.mjs.map +1 -0
  12. package/dist/BlockNoteViewer-UW5VZ5UF.js +31 -0
  13. package/dist/BlockNoteViewer-UW5VZ5UF.js.map +1 -0
  14. package/dist/{auth.interface-BBUgMZzs.d.ts → auth.interface-8b601idJ.d.ts} +1 -1
  15. package/dist/{auth.interface-XYEREOD6.d.mts → auth.interface-CXBF8Mhi.d.mts} +1 -1
  16. package/dist/billing/index.d.mts +41 -41
  17. package/dist/billing/index.d.ts +41 -41
  18. package/dist/billing/index.js +346 -346
  19. package/dist/billing/index.mjs +3 -3
  20. package/dist/{chunk-VLDLERJN.js → chunk-6XWW67F2.js} +29 -9
  21. package/dist/chunk-6XWW67F2.js.map +1 -0
  22. package/dist/{chunk-HC3JFN3C.js → chunk-AKXUNE3A.js} +1004 -862
  23. package/dist/chunk-AKXUNE3A.js.map +1 -0
  24. package/dist/{chunk-CFECWLHH.mjs → chunk-CWVYU4YZ.mjs} +23 -3
  25. package/dist/chunk-CWVYU4YZ.mjs.map +1 -0
  26. package/dist/{chunk-56XBGQGU.mjs → chunk-TXVVZLUQ.mjs} +1422 -1280
  27. package/dist/chunk-TXVVZLUQ.mjs.map +1 -0
  28. package/dist/{chunk-RXXZGPC3.js → chunk-U2HR57MY.js} +265 -113
  29. package/dist/chunk-U2HR57MY.js.map +1 -0
  30. package/dist/chunk-WPAQRB5Q.mjs +7 -0
  31. package/dist/chunk-WPAQRB5Q.mjs.map +1 -0
  32. package/dist/chunk-YBZVWLPH.js +7 -0
  33. package/dist/chunk-YBZVWLPH.js.map +1 -0
  34. package/dist/{chunk-N3NVIPSU.mjs → chunk-ZYPNVEHB.mjs} +235 -83
  35. package/dist/{chunk-N3NVIPSU.mjs.map → chunk-ZYPNVEHB.mjs.map} +1 -1
  36. package/dist/client/index.d.mts +9 -18
  37. package/dist/client/index.d.ts +9 -18
  38. package/dist/client/index.js +4 -4
  39. package/dist/client/index.mjs +3 -3
  40. package/dist/components/index.d.mts +421 -417
  41. package/dist/components/index.d.ts +421 -417
  42. package/dist/components/index.js +6 -4
  43. package/dist/components/index.js.map +1 -1
  44. package/dist/components/index.mjs +5 -3
  45. package/dist/{config-CLQynoaa.d.ts → config-BrkU_Ynz.d.ts} +4 -1
  46. package/dist/{config-k61pe_o2.d.mts → config-snd2ToEB.d.mts} +4 -1
  47. package/dist/contexts/index.d.mts +31 -20
  48. package/dist/contexts/index.d.ts +31 -20
  49. package/dist/contexts/index.js +4 -4
  50. package/dist/contexts/index.mjs +3 -3
  51. package/dist/core/index.d.mts +75 -11
  52. package/dist/core/index.d.ts +75 -11
  53. package/dist/core/index.js +2 -2
  54. package/dist/core/index.mjs +1 -1
  55. package/dist/features/help/index.css +29 -0
  56. package/dist/features/help/index.css.map +1 -0
  57. package/dist/features/help/index.d.mts +74 -0
  58. package/dist/features/help/index.d.ts +74 -0
  59. package/dist/features/help/index.js +522 -0
  60. package/dist/features/help/index.js.map +1 -0
  61. package/dist/features/help/index.mjs +522 -0
  62. package/dist/features/help/index.mjs.map +1 -0
  63. package/dist/features/help/server.d.mts +33 -0
  64. package/dist/features/help/server.d.ts +33 -0
  65. package/dist/features/help/server.js +8 -0
  66. package/dist/features/help/server.js.map +1 -0
  67. package/dist/features/help/server.mjs +8 -0
  68. package/dist/features/help/server.mjs.map +1 -0
  69. package/dist/help-content-config.interface-C5ESIod9.d.mts +13 -0
  70. package/dist/help-content-config.interface-C5ESIod9.d.ts +13 -0
  71. package/dist/index.d.mts +10 -8
  72. package/dist/index.d.ts +10 -8
  73. package/dist/index.js +3 -3
  74. package/dist/index.mjs +2 -2
  75. package/dist/{notification.interface-aLEJbA_g.d.ts → notification.interface-C1T1C2ee.d.ts} +1 -100
  76. package/dist/{notification.interface-DLZGtV7Z.d.mts → notification.interface-DIxR23eS.d.mts} +1 -100
  77. package/dist/{s3.service-CVgLWaDc.d.mts → s3.service-0BTClOYO.d.mts} +2 -2
  78. package/dist/{s3.service-SLlX0Zbz.d.ts → s3.service-CT27Fm1s.d.ts} +2 -2
  79. package/dist/server/index.d.mts +4 -3
  80. package/dist/server/index.d.ts +4 -3
  81. package/dist/server/index.js +3 -3
  82. package/dist/server/index.mjs +1 -1
  83. package/dist/testing/index.d.mts +1 -2
  84. package/dist/testing/index.d.ts +1 -2
  85. package/dist/types-CQSjy7et.d.mts +101 -0
  86. package/dist/types-DHOxe8rc.d.ts +101 -0
  87. package/dist/usePageUrlGenerator-tjq2mlDV.d.ts +14 -0
  88. package/dist/usePageUrlGenerator-uOnyJ6j2.d.mts +14 -0
  89. package/dist/{useSocket-BkxHHujj.d.mts → useSocket-B1fMIr17.d.mts} +1 -1
  90. package/dist/{useSocket-CMDjWFYm.d.ts → useSocket-BdJTBXKv.d.ts} +1 -1
  91. package/package.json +15 -1
  92. package/src/client/config.ts +9 -1
  93. package/src/components/index.ts +1 -0
  94. package/src/components/viewers/BlockNoteViewer.tsx +27 -0
  95. package/src/components/viewers/BlockNoteViewerContainer.tsx +10 -0
  96. package/src/core/registry/helpStore.ts +28 -0
  97. package/src/features/assistant/contexts/AssistantContext.tsx +35 -19
  98. package/src/features/assistant/contexts/__tests__/AssistantContext.spec.tsx +66 -6
  99. package/src/features/assistant/data/Assistant.ts +2 -0
  100. package/src/features/assistant/data/AssistantInterface.ts +2 -0
  101. package/src/features/assistant/data/AssistantService.ts +18 -8
  102. package/src/features/assistant-message/components/parts/MessageSourcesContainer.tsx +4 -0
  103. package/src/features/assistant-message/components/parts/MessageSourcesPanel.tsx +6 -4
  104. package/src/features/assistant-message/components/parts/tabs/ContentsTab.tsx +5 -1
  105. package/src/features/assistant-message/components/parts/tabs/ReferencesTab.tsx +3 -1
  106. package/src/features/assistant-message/data/AssistantMessage.ts +27 -1
  107. package/src/features/assistant-message/data/AssistantMessageInterface.ts +1 -0
  108. package/src/features/assistant-message/data/__tests__/AssistantMessage.spec.ts +7 -3
  109. package/src/features/help/components/HelpArticleBody.tsx +62 -0
  110. package/src/features/help/components/HelpAskAi.tsx +36 -0
  111. package/src/features/help/components/HelpAssistantSheet.tsx +53 -0
  112. package/src/features/help/components/HelpHeader.tsx +40 -0
  113. package/src/features/help/components/HelpHint.tsx +86 -0
  114. package/src/features/help/components/HelpSearchResultRow.tsx +61 -0
  115. package/src/features/help/components/HelpSideNav.tsx +119 -0
  116. package/src/features/help/components/HelpTOC.tsx +49 -0
  117. package/src/features/help/components/__tests__/HelpAskAi.spec.tsx +68 -0
  118. package/src/features/help/components/__tests__/HelpAssistantSheet.spec.tsx +36 -0
  119. package/src/features/help/components/__tests__/HelpHint.spec.tsx +50 -0
  120. package/src/features/help/components/__tests__/HelpSearchResultRow.spec.tsx +58 -0
  121. package/src/features/help/components/__tests__/HelpSideNav.spec.tsx +50 -0
  122. package/src/features/help/contexts/HelpContext.spec.tsx +26 -0
  123. package/src/features/help/contexts/HelpContext.tsx +24 -0
  124. package/src/features/help/hooks/useHelp.ts +1 -0
  125. package/src/features/help/hooks/useHelpFilter.ts +27 -0
  126. package/src/features/help/i18n-keys.ts +34 -0
  127. package/src/features/help/index.ts +24 -0
  128. package/src/features/help/interfaces/help-content-config.interface.ts +12 -0
  129. package/src/features/help/server-entry.ts +11 -0
  130. package/src/features/help/types/help-article.types.ts +35 -0
  131. package/src/features/help/utils/articleUrl.ts +13 -0
  132. package/src/features/how-to/HowToModule.ts +14 -1
  133. package/src/features/how-to/components/forms/HowToEditor.tsx +108 -4
  134. package/src/features/how-to/data/HowTo.spec.ts +43 -0
  135. package/src/features/how-to/data/HowTo.ts +64 -3
  136. package/src/features/how-to/data/HowToInterface.ts +14 -0
  137. package/src/features/how-to/data/HowToService.ts +61 -0
  138. package/src/index.ts +4 -0
  139. package/dist/chunk-56XBGQGU.mjs.map +0 -1
  140. package/dist/chunk-CFECWLHH.mjs.map +0 -1
  141. package/dist/chunk-HC3JFN3C.js.map +0 -1
  142. package/dist/chunk-RXXZGPC3.js.map +0 -1
  143. package/dist/chunk-VLDLERJN.js.map +0 -1
  144. /package/dist/{BlockNoteEditor-XVIBGXHF.mjs.map → BlockNoteEditor-K7IIWM3S.mjs.map} +0 -0
@@ -0,0 +1,522 @@
1
+ "use client";
2
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
3
+
4
+ var _chunkYBZVWLPHjs = require('../../chunk-YBZVWLPH.js');
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+ var _chunkAKXUNE3Ajs = require('../../chunk-AKXUNE3A.js');
25
+
26
+
27
+ var _chunk6XWW67F2js = require('../../chunk-6XWW67F2.js');
28
+
29
+
30
+ var _chunkU2HR57MYjs = require('../../chunk-U2HR57MY.js');
31
+ require('../../chunk-LXKSUWAV.js');
32
+ require('../../chunk-IBS6NI7D.js');
33
+ require('../../chunk-J5LROFGL.js');
34
+ require('../../chunk-3EPNHTMH.js');
35
+
36
+
37
+ var _chunk7QVYU63Ejs = require('../../chunk-7QVYU63E.js');
38
+
39
+ // src/features/help/contexts/HelpContext.tsx
40
+ var _react = require('react');
41
+ var _jsxruntime = require('react/jsx-runtime');
42
+ var HelpContext = _react.createContext.call(void 0, null);
43
+ function HelpProvider({ children }) {
44
+ const cfg = _chunk6XWW67F2js._getStaticHelpContent.call(void 0, );
45
+ if (!cfg) {
46
+ throw new Error(
47
+ "Help content not configured \u2014 call configureJsonApi({ helpContent: {...} }) before importing help components."
48
+ );
49
+ }
50
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HelpContext.Provider, { value: cfg, children });
51
+ }
52
+ _chunk7QVYU63Ejs.__name.call(void 0, HelpProvider, "HelpProvider");
53
+ function useHelp() {
54
+ const ctx = _react.useContext.call(void 0, HelpContext);
55
+ if (!ctx) {
56
+ throw new Error("useHelp() called outside <HelpProvider>. Wrap your help route group with <HelpProvider>.");
57
+ }
58
+ return ctx;
59
+ }
60
+ _chunk7QVYU63Ejs.__name.call(void 0, useHelp, "useHelp");
61
+
62
+ // src/features/help/components/HelpHeader.tsx
63
+ var _link = require('next/link'); var _link2 = _interopRequireDefault(_link);
64
+ var _image = require('next/image'); var _image2 = _interopRequireDefault(_image);
65
+ var _nextintl = require('next-intl');
66
+
67
+ // src/features/help/components/HelpAskAi.tsx
68
+
69
+ var _lucidereact = require('lucide-react');
70
+
71
+
72
+ // src/features/help/components/HelpAssistantSheet.tsx
73
+
74
+
75
+ function HelpAssistantSheet({ open, onOpenChange }) {
76
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.Sheet, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
77
+ _chunkAKXUNE3Ajs.SheetContent,
78
+ {
79
+ side: "right",
80
+ className: "flex w-full flex-col data-[side=right]:sm:max-w-2xl data-[side=right]:lg:max-w-3xl",
81
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.AssistantProvider, { manageUrl: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HelpAssistantSheetBody, {}) })
82
+ }
83
+ ) });
84
+ }
85
+ _chunk7QVYU63Ejs.__name.call(void 0, HelpAssistantSheet, "HelpAssistantSheet");
86
+ function HelpAssistantSheetBody() {
87
+ const t = _nextintl.useTranslations.call(void 0, );
88
+ const ctx = _chunkAKXUNE3Ajs.useAssistantContext.call(void 0, );
89
+ const showThread = !!ctx.assistant || ctx.sending || ctx.messages.length > 0;
90
+ const send = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (content) => ctx.sendMessage(content, { howToMode: true }), "send");
91
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
92
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAKXUNE3Ajs.SheetHeader, { children: [
93
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.SheetTitle, { children: t("help.askAi.sheet.title") }),
94
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.SheetDescription, { children: t("help.askAi.sheet.subtitle") })
95
+ ] }),
96
+ !showThread ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.AssistantEmptyState, { onSend: send }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
97
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
98
+ _chunkAKXUNE3Ajs.AssistantThread,
99
+ {
100
+ messages: ctx.messages,
101
+ sending: ctx.sending,
102
+ status: ctx.status,
103
+ onSelectFollowUp: send,
104
+ failedMessageIds: ctx.failedMessageIds,
105
+ onRetry: ctx.retrySend
106
+ }
107
+ ),
108
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.AssistantComposer, { onSend: send, disabled: ctx.sending })
109
+ ] })
110
+ ] });
111
+ }
112
+ _chunk7QVYU63Ejs.__name.call(void 0, HelpAssistantSheetBody, "HelpAssistantSheetBody");
113
+
114
+ // src/features/help/components/HelpAskAi.tsx
115
+
116
+ function HelpAskAi() {
117
+ const t = _nextintl.useTranslations.call(void 0, );
118
+ const { currentUser } = _chunkAKXUNE3Ajs.useCurrentUserContext.call(void 0, );
119
+ const [open, setOpen] = _react.useState.call(void 0, false);
120
+ const disabled = !currentUser;
121
+ if (disabled) {
122
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAKXUNE3Ajs.Tooltip, { children: [
123
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAKXUNE3Ajs.TooltipTrigger, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.Button, { variant: "outline", size: "sm", disabled: true }), children: [
124
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.SparklesIcon, { className: "h-4 w-4" }),
125
+ t("help.askAi.button")
126
+ ] }),
127
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.TooltipContent, { children: t("help.askAi.loginTooltip") })
128
+ ] });
129
+ }
130
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
131
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAKXUNE3Ajs.Button, { variant: "outline", size: "sm", onClick: () => setOpen(true), children: [
132
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.SparklesIcon, { className: "h-4 w-4" }),
133
+ t("help.askAi.button")
134
+ ] }),
135
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HelpAssistantSheet, { open, onOpenChange: setOpen })
136
+ ] });
137
+ }
138
+ _chunk7QVYU63Ejs.__name.call(void 0, HelpAskAi, "HelpAskAi");
139
+
140
+ // src/features/help/components/HelpHeader.tsx
141
+
142
+ function HelpHeader() {
143
+ const t = _nextintl.useTranslations.call(void 0, );
144
+ const { currentUser } = _chunkAKXUNE3Ajs.useCurrentUserContext.call(void 0, );
145
+ const { brand } = useHelp();
146
+ const logo = _optionalChain([brand, 'optionalAccess', _ => _.logo]);
147
+ const label = _nullishCoalesce(_optionalChain([brand, 'optionalAccess', _2 => _2.label]), () => ( "Help"));
148
+ const appHref = _nullishCoalesce(_optionalChain([brand, 'optionalAccess', _3 => _3.appHref]), () => ( "/"));
149
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "header", { className: "border-border bg-background flex items-center justify-between border-b px-4 py-3", children: [
150
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _link2.default, { href: "/help", className: "flex items-center gap-2", children: [
151
+ logo ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _image2.default, { src: logo, alt: label, width: 28, height: 28 }) : null,
152
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-base font-semibold", children: [
153
+ label,
154
+ " \xB7 ",
155
+ t("help.footerLink")
156
+ ] })
157
+ ] }),
158
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
159
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HelpAskAi, {}),
160
+ currentUser ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.Button, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: appHref }), nativeButton: false, variant: "outline", size: "sm", children: t("help.header.openApp") }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.Button, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: "/login" }), nativeButton: false, variant: "outline", size: "sm", children: t("help.header.login") })
161
+ ] })
162
+ ] });
163
+ }
164
+ _chunk7QVYU63Ejs.__name.call(void 0, HelpHeader, "HelpHeader");
165
+
166
+ // src/features/help/components/HelpSideNav.tsx
167
+
168
+
169
+
170
+ var _navigation = require('next/navigation');
171
+
172
+ // src/features/help/hooks/useHelpFilter.ts
173
+
174
+ var _fusejs = require('fuse.js'); var _fusejs2 = _interopRequireDefault(_fusejs);
175
+ function useHelpFilter(articles) {
176
+ const [query, setQuery] = _react.useState.call(void 0, "");
177
+ const fuse = _react.useMemo.call(void 0,
178
+ () => new (0, _fusejs2.default)([...articles], {
179
+ keys: [
180
+ { name: "title", weight: 0.5 },
181
+ { name: "summary", weight: 0.3 },
182
+ { name: "tags", weight: 0.1 },
183
+ { name: "headings.text", weight: 0.1 }
184
+ ],
185
+ threshold: 0.4,
186
+ ignoreLocation: true
187
+ }),
188
+ [articles]
189
+ );
190
+ const filtered = _react.useMemo.call(void 0, () => {
191
+ if (!query.trim()) return [...articles];
192
+ return fuse.search(query).map((r) => r.item);
193
+ }, [query, articles, fuse]);
194
+ return { query, setQuery, filtered };
195
+ }
196
+ _chunk7QVYU63Ejs.__name.call(void 0, useHelpFilter, "useHelpFilter");
197
+
198
+ // src/features/help/components/HelpSideNav.tsx
199
+
200
+ function HelpSideNav() {
201
+ const t = _nextintl.useTranslations.call(void 0, );
202
+ const generateUrl = _chunkAKXUNE3Ajs.usePageUrlGenerator.call(void 0, );
203
+ const pathname = _navigation.usePathname.call(void 0, );
204
+ const [articles, setArticles] = _react.useState.call(void 0, []);
205
+ _react.useEffect.call(void 0, () => {
206
+ let active = true;
207
+ _chunkU2HR57MYjs.HowToService.findPublished().then((list) => active && setArticles(list)).catch(() => active && setArticles([]));
208
+ return () => {
209
+ active = false;
210
+ };
211
+ }, []);
212
+ const indexable = _react.useMemo.call(void 0,
213
+ () => articles.map((a) => ({
214
+ id: a.id,
215
+ title: a.name,
216
+ summary: _nullishCoalesce(a.summary, () => ( "")),
217
+ tags: a.tags,
218
+ mode: _nullishCoalesce(a.howToType, () => ( "")),
219
+ slug: _nullishCoalesce(a.slug, () => ( ""))
220
+ })),
221
+ [articles]
222
+ );
223
+ const { query, setQuery, filtered } = useHelpFilter(indexable);
224
+ const filtering = query.trim().length > 0;
225
+ const groups = _react.useMemo.call(void 0,
226
+ () => _chunkYBZVWLPHjs.HELP_MODES.map((mode) => ({
227
+ mode,
228
+ articles: articles.filter((a) => a.howToType === mode && !a.draft).sort((x, y) => (_nullishCoalesce(x.order, () => ( 0))) - (_nullishCoalesce(y.order, () => ( 0))))
229
+ })),
230
+ [articles]
231
+ );
232
+ const isActive = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (mode, slug) => pathname.endsWith(`/help/${mode}/${slug}`), "isActive");
233
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "nav", { "aria-label": "Help navigation", className: "flex h-full flex-col gap-3 overflow-y-auto p-4", children: [
234
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
235
+ "input",
236
+ {
237
+ type: "search",
238
+ value: query,
239
+ onChange: (e) => setQuery(e.target.value),
240
+ placeholder: t("help.sideNav.filterPlaceholder"),
241
+ className: "border-input bg-background w-full rounded-md border px-3 py-2 text-sm"
242
+ }
243
+ ),
244
+ filtering ? filtered.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground text-sm", children: t("help.sideNav.noMatches") }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "space-y-1", children: filtered.map((a) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
245
+ _link2.default,
246
+ {
247
+ href: generateUrl({ page: `/help/${a.mode}/${a.slug}` }),
248
+ className: "hover:bg-muted block rounded px-2 py-1 text-sm " + (isActive(a.mode, a.slug) ? "bg-muted font-medium" : ""),
249
+ children: a.title
250
+ }
251
+ ) }, a.id)) }) : groups.map((group) => {
252
+ if (group.articles.length === 0) return null;
253
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
254
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
255
+ _link2.default,
256
+ {
257
+ href: generateUrl({ page: `/help/${group.mode}` }),
258
+ className: "text-muted-foreground hover:text-foreground mb-1 block text-xs font-semibold tracking-wider uppercase",
259
+ children: t(`help.modes.${group.mode}`)
260
+ }
261
+ ),
262
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "space-y-0.5", children: group.articles.map((a) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
263
+ _link2.default,
264
+ {
265
+ href: generateUrl({ page: `/help/${a.howToType}/${a.slug}` }),
266
+ className: "hover:bg-muted block rounded px-2 py-1 text-sm " + (isActive(_nullishCoalesce(a.howToType, () => ( "")), _nullishCoalesce(a.slug, () => ( ""))) ? "bg-muted font-medium" : ""),
267
+ children: a.name
268
+ }
269
+ ) }, a.id)) })
270
+ ] }, group.mode);
271
+ })
272
+ ] });
273
+ }
274
+ _chunk7QVYU63Ejs.__name.call(void 0, HelpSideNav, "HelpSideNav");
275
+
276
+ // src/features/help/components/HelpArticleBody.tsx
277
+
278
+
279
+
280
+ function HelpArticleBody(props) {
281
+ const t = _nextintl.useTranslations.call(void 0, );
282
+ const format = _nextintl.useFormatter.call(void 0, );
283
+ const generateUrl = _chunkAKXUNE3Ajs.usePageUrlGenerator.call(void 0, );
284
+ const { howToType, title, summary, updatedAt, prev, next, children } = props;
285
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "article", { className: "prose dark:prose-invert max-w-none", children: [
286
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "nav", { className: "text-muted-foreground mb-2 text-xs", children: [
287
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: generateUrl({ page: "/help" }), children: "Help" }),
288
+ " \xB7 ",
289
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: generateUrl({ page: `/help/${howToType}` }), children: t(`help.modes.${howToType}`) })
290
+ ] }),
291
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { children: title }),
292
+ summary ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground !mt-0 text-base", children: summary }) : null,
293
+ children,
294
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "hr", { className: "my-6" }),
295
+ updatedAt ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-muted-foreground text-xs", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: t("help.article.lastUpdated", {
296
+ date: format.dateTime(new Date(updatedAt), { dateStyle: "short" })
297
+ }) }) }) : null,
298
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-4 flex justify-between text-sm", children: [
299
+ prev ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _link2.default, { href: generateUrl({ page: `/help/${prev.howToType}/${prev.slug}` }), className: "hover:underline", children: [
300
+ "\u2190 ",
301
+ t("help.article.previous"),
302
+ ": ",
303
+ prev.title
304
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", {}),
305
+ next ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _link2.default, { href: generateUrl({ page: `/help/${next.howToType}/${next.slug}` }), className: "hover:underline", children: [
306
+ t("help.article.next"),
307
+ ": ",
308
+ next.title,
309
+ " \u2192"
310
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", {})
311
+ ] })
312
+ ] });
313
+ }
314
+ _chunk7QVYU63Ejs.__name.call(void 0, HelpArticleBody, "HelpArticleBody");
315
+
316
+ // src/features/help/components/HelpTOC.tsx
317
+
318
+
319
+
320
+ function HelpTOC({ headings }) {
321
+ const t = _nextintl.useTranslations.call(void 0, );
322
+ const [active, setActive] = _react.useState.call(void 0, null);
323
+ _react.useEffect.call(void 0, () => {
324
+ const observer = new IntersectionObserver(
325
+ (entries) => {
326
+ for (const e of entries) {
327
+ if (e.isIntersecting) setActive(e.target.id);
328
+ }
329
+ },
330
+ { rootMargin: "0px 0px -70% 0px", threshold: 0 }
331
+ );
332
+ headings.forEach((h) => {
333
+ const el = document.getElementById(h.slug);
334
+ if (el) observer.observe(el);
335
+ });
336
+ return () => observer.disconnect();
337
+ }, [headings]);
338
+ if (headings.length === 0) return null;
339
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "nav", { "aria-label": t("help.toc.title"), className: "hidden lg:block", children: [
340
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-muted-foreground mb-2 text-xs font-semibold tracking-wider uppercase", children: t("help.toc.title") }),
341
+ /* @__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: { paddingLeft: `${(h.depth - 2) * 0.75}rem` }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
342
+ "a",
343
+ {
344
+ href: `#${h.slug}`,
345
+ className: "block truncate hover:text-foreground " + (active === h.slug ? "text-foreground font-medium" : "text-muted-foreground"),
346
+ children: h.text
347
+ }
348
+ ) }, h.slug)) })
349
+ ] });
350
+ }
351
+ _chunk7QVYU63Ejs.__name.call(void 0, HelpTOC, "HelpTOC");
352
+
353
+ // src/features/help/components/HelpHint.tsx
354
+
355
+
356
+
357
+
358
+
359
+ function HelpHint({ contextKey }) {
360
+ const t = _nextintl.useTranslations.call(void 0, );
361
+ const generateUrl = _chunkAKXUNE3Ajs.usePageUrlGenerator.call(void 0, );
362
+ const [open, setOpen] = _react.useState.call(void 0, false);
363
+ const [picked, setPicked] = _react.useState.call(void 0, null);
364
+ const [articles, setArticles] = _react.useState.call(void 0, []);
365
+ _react.useEffect.call(void 0, () => {
366
+ let active2 = true;
367
+ _chunkU2HR57MYjs.HowToService.findPublished().then((list) => active2 && setArticles(list)).catch(() => active2 && setArticles([]));
368
+ return () => {
369
+ active2 = false;
370
+ };
371
+ }, []);
372
+ const matches = _react.useMemo.call(void 0,
373
+ () => articles.filter((a) => a.contextualKeys.includes(contextKey) && !a.draft),
374
+ [articles, contextKey]
375
+ );
376
+ if (matches.length === 0) return null;
377
+ const active = _nullishCoalesce(picked, () => ( (matches.length === 1 ? matches[0] : null)));
378
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
379
+ _chunkAKXUNE3Ajs.Sheet,
380
+ {
381
+ open,
382
+ onOpenChange: (o) => {
383
+ setOpen(o);
384
+ if (!o) setPicked(null);
385
+ },
386
+ children: [
387
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.SheetTrigger, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.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" }) }),
388
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAKXUNE3Ajs.SheetContent, { side: "right", className: "w-full max-w-md sm:max-w-lg", children: [
389
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkAKXUNE3Ajs.SheetHeader, { children: [
390
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.SheetTitle, { children: active ? active.name : t("help.hint.pickArticle") }),
391
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.SheetDescription, { children: _nullishCoalesce(_optionalChain([active, 'optionalAccess', _4 => _4.summary]), () => ( "")) })
392
+ ] }),
393
+ active ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-4 space-y-3", children: [
394
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground text-sm", children: active.summary }),
395
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: generateUrl({ page: `/help/${active.howToType}/${active.slug}` }), className: "text-sm", children: t("help.hint.viewArticle") })
396
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "mt-4 space-y-1", children: matches.map((a) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
397
+ "button",
398
+ {
399
+ type: "button",
400
+ onClick: () => setPicked(a),
401
+ className: "hover:bg-muted block w-full rounded px-2 py-1 text-left text-sm",
402
+ children: [
403
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "font-medium", children: a.name }),
404
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-muted-foreground text-xs", children: a.summary })
405
+ ]
406
+ }
407
+ ) }, a.id)) })
408
+ ] })
409
+ ]
410
+ }
411
+ );
412
+ }
413
+ _chunk7QVYU63Ejs.__name.call(void 0, HelpHint, "HelpHint");
414
+
415
+ // src/features/help/components/HelpSearchResultRow.tsx
416
+
417
+
418
+
419
+
420
+
421
+ function HelpSearchResultRow({ result, onSelect }) {
422
+ const t = _nextintl.useTranslations.call(void 0, );
423
+ const generateUrl = _chunkAKXUNE3Ajs.usePageUrlGenerator.call(void 0, );
424
+ const [article, setArticle] = _react.useState.call(void 0, null);
425
+ _react.useEffect.call(void 0, () => {
426
+ let active = true;
427
+ _chunkU2HR57MYjs.HowToService.findOne({ id: result.id }).then((a) => active && setArticle(a)).catch(() => active && setArticle(null));
428
+ return () => {
429
+ active = false;
430
+ };
431
+ }, [result.id]);
432
+ if (!article) {
433
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
434
+ _chunkAKXUNE3Ajs.CommandItem,
435
+ {
436
+ value: result.id,
437
+ disabled: true,
438
+ className: "text-muted-foreground cursor-not-allowed px-3 py-1.5 text-sm italic",
439
+ children: t("help.search.removed")
440
+ }
441
+ );
442
+ }
443
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkAKXUNE3Ajs.CommandItem, { value: result.id, onSelect, className: "cursor-pointer p-0", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
444
+ _link2.default,
445
+ {
446
+ href: generateUrl({ page: `/help/${article.howToType}/${article.slug}` }),
447
+ className: "hover:bg-muted flex w-full items-center gap-3 rounded px-3 py-2",
448
+ children: [
449
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-muted text-muted-foreground flex h-10 w-10 shrink-0 items-center justify-center rounded-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.LifeBuoyIcon, { className: "h-5 w-5" }) }),
450
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-w-0 flex-1 flex-col", children: [
451
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-foreground truncate text-sm font-semibold", children: article.name }),
452
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-muted-foreground truncate text-xs", children: [
453
+ t(`help.modes.${article.howToType}`),
454
+ " \xB7 ",
455
+ article.summary
456
+ ] })
457
+ ] }),
458
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ArrowUpRightIcon, { className: "text-muted-foreground h-5 w-5 shrink-0" })
459
+ ]
460
+ }
461
+ ) });
462
+ }
463
+ _chunk7QVYU63Ejs.__name.call(void 0, HelpSearchResultRow, "HelpSearchResultRow");
464
+
465
+ // src/features/help/utils/articleUrl.ts
466
+ function articleUrl(generateUrl, article) {
467
+ return generateUrl({ page: `/help/${article.mode}/${article.slug}` });
468
+ }
469
+ _chunk7QVYU63Ejs.__name.call(void 0, articleUrl, "articleUrl");
470
+ function modeUrl(generateUrl, mode) {
471
+ return generateUrl({ page: `/help/${mode}` });
472
+ }
473
+ _chunk7QVYU63Ejs.__name.call(void 0, modeUrl, "modeUrl");
474
+
475
+ // src/features/help/i18n-keys.ts
476
+ var HELP_I18N_KEYS = [
477
+ "help.modes.tutorial",
478
+ "help.modes.how-to",
479
+ "help.modes.reference",
480
+ "help.modes.explanation",
481
+ "help.sideNav.filterPlaceholder",
482
+ "help.sideNav.noMatches",
483
+ "help.toc.title",
484
+ "help.article.lastUpdated",
485
+ "help.article.previous",
486
+ "help.article.next",
487
+ "help.article.related",
488
+ "help.askAi.button",
489
+ "help.askAi.loginTooltip",
490
+ "help.askAi.sheet.title",
491
+ "help.askAi.sheet.subtitle",
492
+ "help.header.search",
493
+ "help.header.login",
494
+ "help.header.openApp",
495
+ "help.hint.trigger",
496
+ "help.hint.viewArticle",
497
+ "help.hint.pickArticle",
498
+ "help.landing.heading",
499
+ "help.landing.subheading",
500
+ "help.landing.featuredTutorials",
501
+ "help.landing.browseByMode",
502
+ "help.modeIndex.empty",
503
+ "help.search.removed",
504
+ "help.footerLink"
505
+ ];
506
+
507
+
508
+
509
+
510
+
511
+
512
+
513
+
514
+
515
+
516
+
517
+
518
+
519
+
520
+
521
+ exports.HELP_I18N_KEYS = HELP_I18N_KEYS; exports.HELP_MODES = _chunkYBZVWLPHjs.HELP_MODES; exports.HelpArticleBody = HelpArticleBody; exports.HelpAskAi = HelpAskAi; exports.HelpHeader = HelpHeader; exports.HelpHint = HelpHint; exports.HelpProvider = HelpProvider; exports.HelpSearchResultRow = HelpSearchResultRow; exports.HelpSideNav = HelpSideNav; exports.HelpTOC = HelpTOC; exports.articleUrl = articleUrl; exports.modeUrl = modeUrl; exports.useHelp = useHelp; exports.useHelpFilter = useHelpFilter;
522
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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 { Button } 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\">\n <Link href=\"/help\" className=\"flex items-center gap-2\">\n {logo ? <Image src={logo} alt={label} width={28} height={28} /> : null}\n <span className=\"text-base font-semibold\">\n {label} · {t(\"help.footerLink\")}\n </span>\n </Link>\n <div className=\"flex items-center gap-2\">\n <HelpAskAi />\n {currentUser ? (\n <Button render={<Link href={appHref} />} nativeButton={false} variant=\"outline\" size=\"sm\">\n {t(\"help.header.openApp\")}\n </Button>\n ) : (\n <Button render={<Link href=\"/login\" />} nativeButton={false} variant=\"outline\" size=\"sm\">\n {t(\"help.header.login\")}\n </Button>\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=\"right\"\n className=\"flex w-full flex-col data-[side=right]:sm:max-w-2xl data-[side=right]: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}` })} className=\"hover:underline\">\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}` })} className=\"hover:underline\">\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\";\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 <div className=\"text-muted-foreground mb-2 text-xs font-semibold tracking-wider uppercase\">\n {t(\"help.toc.title\")}\n </div>\n <ul className=\"space-y-1 text-sm\">\n {headings.map((h) => (\n <li key={h.slug} style={{ paddingLeft: `${(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=\"right\" 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-left 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"]}