@elevasis/ui 2.36.0 → 2.38.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 (95) hide show
  1. package/dist/api/index.js +4 -3
  2. package/dist/app/index.css +0 -384
  3. package/dist/app/index.d.ts +75 -2
  4. package/dist/app/index.js +22 -21
  5. package/dist/auth/index.d.ts +91 -28
  6. package/dist/auth/index.js +5 -1
  7. package/dist/charts/index.js +9 -3
  8. package/dist/chunk-4O3VAALW.js +349 -0
  9. package/dist/{chunk-O2Q4VMRN.js → chunk-566XWGPP.js} +76 -109
  10. package/dist/chunk-5EYJ2GIN.js +122 -0
  11. package/dist/chunk-6D4LCJ52.js +10 -0
  12. package/dist/chunk-6ROXVZ3L.js +9 -0
  13. package/dist/{chunk-YYX7OPZQ.js → chunk-73EWE2EW.js} +1 -1
  14. package/dist/{chunk-SIQ3P4OR.js → chunk-7GQFIWP4.js} +8 -756
  15. package/dist/{chunk-VKIZUUPM.js → chunk-7YXZFS56.js} +31 -14
  16. package/dist/{chunk-AKW7KISS.js → chunk-7ZWXTH5J.js} +2 -44
  17. package/dist/chunk-A7IG36LB.js +215 -0
  18. package/dist/chunk-B2DZLPDL.js +39 -0
  19. package/dist/chunk-C6BDBZRO.js +422 -0
  20. package/dist/chunk-CLDCYJQT.js +1 -0
  21. package/dist/{chunk-LUYVRATI.js → chunk-DA6I5VEY.js} +5 -213
  22. package/dist/chunk-H2MEFUQD.js +337 -0
  23. package/dist/chunk-I53EX4VU.js +734 -0
  24. package/dist/chunk-IIMU5YAJ.js +53 -0
  25. package/dist/chunk-JXVNHVK7.js +79 -0
  26. package/dist/chunk-M7Q4UBRY.js +85 -0
  27. package/dist/{chunk-K4UZU3TU.js → chunk-P34FFSOX.js} +1 -1
  28. package/dist/chunk-PGWANFNE.js +112 -0
  29. package/dist/{chunk-F6EFC2MJ.js → chunk-Q64E2TZY.js} +440 -2075
  30. package/dist/chunk-S3XR4II4.js +30 -0
  31. package/dist/chunk-SHZT7ULK.js +425 -0
  32. package/dist/{chunk-GX6XBRRF.js → chunk-TYRUKGGD.js} +2 -1
  33. package/dist/{chunk-R3VCBZDC.js → chunk-X4WBGKJQ.js} +3 -50
  34. package/dist/{chunk-GEFWMU26.js → chunk-X66MVMZT.js} +1 -9
  35. package/dist/{chunk-57OZ3AEG.js → chunk-Y3JQBSKQ.js} +1 -1
  36. package/dist/components/index.d.ts +74 -42
  37. package/dist/components/index.js +34 -19
  38. package/dist/components/navigation/index.js +3 -31
  39. package/dist/features/auth/index.d.ts +97 -99
  40. package/dist/features/auth/index.js +37 -99
  41. package/dist/features/clients/index.js +34 -19
  42. package/dist/features/crm/index.d.ts +65 -0
  43. package/dist/features/crm/index.js +34 -19
  44. package/dist/features/dashboard/index.js +34 -19
  45. package/dist/features/delivery/index.d.ts +65 -0
  46. package/dist/features/delivery/index.js +34 -19
  47. package/dist/features/knowledge/index.js +6 -30
  48. package/dist/features/lead-gen/index.d.ts +1096 -1
  49. package/dist/features/lead-gen/index.js +34 -19
  50. package/dist/features/monitoring/index.js +34 -19
  51. package/dist/features/monitoring/requests/index.js +34 -19
  52. package/dist/features/notes/index.d.ts +72 -0
  53. package/dist/features/notes/index.js +621 -0
  54. package/dist/features/operations/index.d.ts +10 -2
  55. package/dist/features/operations/index.js +34 -19
  56. package/dist/features/right-panel-host/index.d.ts +214 -0
  57. package/dist/features/right-panel-host/index.js +639 -0
  58. package/dist/features/seo/index.js +3 -2
  59. package/dist/features/settings/index.d.ts +68 -35
  60. package/dist/features/settings/index.js +34 -19
  61. package/dist/hooks/access/index.d.ts +90 -0
  62. package/dist/hooks/access/index.js +10 -0
  63. package/dist/hooks/delivery/index.d.ts +65 -0
  64. package/dist/hooks/delivery/index.js +34 -19
  65. package/dist/hooks/index.d.ts +1644 -1651
  66. package/dist/hooks/index.js +34 -19
  67. package/dist/hooks/published.d.ts +1644 -1651
  68. package/dist/hooks/published.js +34 -19
  69. package/dist/hooks/user-notes/index.d.ts +57 -0
  70. package/dist/hooks/user-notes/index.js +3 -0
  71. package/dist/index.d.ts +294 -277
  72. package/dist/index.js +35 -20
  73. package/dist/initialization/index.d.ts +65 -19
  74. package/dist/knowledge/index.d.ts +10 -2
  75. package/dist/knowledge/index.js +173 -28
  76. package/dist/layout/index.js +5 -3
  77. package/dist/organization/index.d.ts +0 -19
  78. package/dist/organization/index.js +34 -19
  79. package/dist/profile/index.d.ts +65 -0
  80. package/dist/provider/index.css +0 -384
  81. package/dist/provider/index.d.ts +75 -2
  82. package/dist/provider/index.js +16 -21
  83. package/dist/provider/published.css +0 -523
  84. package/dist/provider/published.d.ts +75 -2
  85. package/dist/provider/published.js +11 -21
  86. package/dist/supabase/index.d.ts +127 -0
  87. package/dist/test-utils/index.d.ts +2 -21
  88. package/dist/test-utils/index.js +5 -18
  89. package/dist/theme/index.js +3 -1
  90. package/dist/types/index.d.ts +115 -59
  91. package/dist/utils/index.js +2 -1
  92. package/package.json +21 -5
  93. package/src/auth/README.md +6 -6
  94. package/dist/components/navigation/index.css +0 -649
  95. package/dist/features/knowledge/index.css +0 -649
@@ -0,0 +1,621 @@
1
+ import { useUpdateUserNote, useCreateUserNote, useUserNotes, useDeleteUserNote } from '../../chunk-JXVNHVK7.js';
2
+ import { CardHeader } from '../../chunk-S3XR4II4.js';
3
+ import { useInitialization } from '../../chunk-533DUEQY.js';
4
+ import '../../chunk-DD3CCMCZ.js';
5
+ import '../../chunk-2Q2JQSQO.js';
6
+ import '../../chunk-KJ3QUBNU.js';
7
+ import '../../chunk-BRJ3QZ4E.js';
8
+ import '../../chunk-I2KLQ2HA.js';
9
+ import { useState } from 'react';
10
+ import { Box, Group, Text, ScrollArea, Stack, Tooltip, Paper, TextInput, Textarea, Checkbox, Button, Center, Loader, Badge, UnstyledButton, ActionIcon, Menu } from '@mantine/core';
11
+ import { IconPencil, IconPlus, IconNote, IconAlertTriangle, IconUsers, IconLock, IconRobot, IconPinned, IconPinnedOff, IconDotsVertical, IconTrash, IconArrowUp } from '@tabler/icons-react';
12
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
13
+
14
+ function NotesPanelViewShell({ title, icon: Icon, children, headerRightContent }) {
15
+ return /* @__PURE__ */ jsxs(
16
+ Box,
17
+ {
18
+ style: {
19
+ width: "100%",
20
+ height: "100%",
21
+ display: "flex",
22
+ flexDirection: "column",
23
+ background: "var(--right-panel-background, var(--glass-background))",
24
+ backdropFilter: "var(--glass-blur)",
25
+ WebkitBackdropFilter: "var(--glass-blur)",
26
+ border: "1px solid var(--color-border)",
27
+ borderLeft: "none",
28
+ borderRadius: "0 var(--mantine-radius-default) var(--mantine-radius-default) 0",
29
+ overflow: "hidden",
30
+ position: "relative"
31
+ },
32
+ children: [
33
+ /* @__PURE__ */ jsx(
34
+ "div",
35
+ {
36
+ style: {
37
+ width: "100%",
38
+ height: 2,
39
+ flexShrink: 0,
40
+ background: "linear-gradient(90deg, transparent, var(--color-primary), transparent)",
41
+ opacity: 0.4
42
+ }
43
+ }
44
+ ),
45
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", px: "md", py: "xs", style: { flexShrink: 0 }, children: [
46
+ /* @__PURE__ */ jsxs(Group, { gap: 8, wrap: "nowrap", style: { minWidth: 0 }, children: [
47
+ /* @__PURE__ */ jsx(Icon, { size: 16, style: { color: "var(--color-primary)", flexShrink: 0 } }),
48
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, style: { flexShrink: 0 }, children: title })
49
+ ] }),
50
+ headerRightContent && /* @__PURE__ */ jsx(Group, { gap: 8, wrap: "nowrap", children: headerRightContent })
51
+ ] }),
52
+ /* @__PURE__ */ jsx(ScrollArea, { style: { flex: 1 }, scrollbarSize: 6, children: /* @__PURE__ */ jsx(Stack, { gap: "md", p: "sm", children }) })
53
+ ]
54
+ }
55
+ );
56
+ }
57
+ var PRIORITY_BORDER_COLOR = {
58
+ urgent: "var(--mantine-color-red-6)",
59
+ high: "var(--mantine-color-orange-6)",
60
+ normal: "var(--mantine-color-blue-6)",
61
+ low: "var(--mantine-color-gray-6)"
62
+ };
63
+ var PRIORITY_OPTIONS = [
64
+ { value: "low", label: "Low" },
65
+ { value: "normal", label: "Normal" },
66
+ { value: "high", label: "High" },
67
+ { value: "urgent", label: "Urgent" }
68
+ ];
69
+ var PRIORITY_LEGEND_ORDER = ["urgent", "high", "normal", "low"];
70
+ function PriorityLegend() {
71
+ return /* @__PURE__ */ jsx(
72
+ Group,
73
+ {
74
+ gap: 6,
75
+ wrap: "nowrap",
76
+ "aria-label": "Priority legend",
77
+ px: 8,
78
+ py: 4,
79
+ style: {
80
+ border: "1px solid var(--color-border)",
81
+ borderRadius: "var(--mantine-radius-default)",
82
+ background: "var(--glass-background)",
83
+ backdropFilter: "var(--glass-blur)",
84
+ WebkitBackdropFilter: "var(--glass-blur)"
85
+ },
86
+ children: PRIORITY_LEGEND_ORDER.map((p) => /* @__PURE__ */ jsx(Tooltip, { label: p.charAt(0).toUpperCase() + p.slice(1), withArrow: true, children: /* @__PURE__ */ jsx(
87
+ Box,
88
+ {
89
+ "data-priority-dot": p,
90
+ style: {
91
+ width: 8,
92
+ height: 8,
93
+ borderRadius: "50%",
94
+ backgroundColor: PRIORITY_BORDER_COLOR[p],
95
+ boxShadow: `0 0 4px ${PRIORITY_BORDER_COLOR[p]}40`
96
+ }
97
+ }
98
+ ) }, p))
99
+ }
100
+ );
101
+ }
102
+ function PrioritySelector({ value, onChange, disabled }) {
103
+ return /* @__PURE__ */ jsx(Group, { gap: 6, wrap: "nowrap", role: "radiogroup", "aria-label": "Priority", children: PRIORITY_OPTIONS.map((opt) => {
104
+ const color = PRIORITY_BORDER_COLOR[opt.value];
105
+ const selected = value === opt.value;
106
+ return /* @__PURE__ */ jsxs(
107
+ UnstyledButton,
108
+ {
109
+ role: "radio",
110
+ "aria-checked": selected,
111
+ "aria-label": `Priority ${opt.label}`,
112
+ onClick: () => !disabled && onChange(opt.value),
113
+ disabled,
114
+ style: {
115
+ display: "inline-flex",
116
+ alignItems: "center",
117
+ gap: 6,
118
+ padding: "3px 10px",
119
+ fontSize: "var(--mantine-font-size-xs)",
120
+ fontWeight: 600,
121
+ lineHeight: 1.5,
122
+ color: selected ? "#fff" : "var(--mantine-color-dimmed)",
123
+ background: selected ? color : "transparent",
124
+ border: `1px solid ${selected ? color : "var(--color-border)"}`,
125
+ borderRadius: 999,
126
+ cursor: disabled ? "not-allowed" : "pointer",
127
+ opacity: disabled ? 0.6 : 1,
128
+ boxShadow: selected ? `0 0 0 2px ${color}33` : void 0,
129
+ transition: "background 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease"
130
+ },
131
+ children: [
132
+ !selected && /* @__PURE__ */ jsx(
133
+ Box,
134
+ {
135
+ style: {
136
+ width: 6,
137
+ height: 6,
138
+ borderRadius: "50%",
139
+ backgroundColor: color
140
+ }
141
+ }
142
+ ),
143
+ opt.label
144
+ ]
145
+ },
146
+ opt.value
147
+ );
148
+ }) });
149
+ }
150
+ function ScopeChip({ visibility, onToggle, disabled, disabledTooltip }) {
151
+ const isOrg = visibility === "org";
152
+ const Icon = isOrg ? IconUsers : IconLock;
153
+ const label = isOrg ? "Shared with org" : "Just for me";
154
+ const chip = /* @__PURE__ */ jsxs(
155
+ UnstyledButton,
156
+ {
157
+ role: "switch",
158
+ "aria-checked": isOrg,
159
+ "aria-label": `Note scope: ${label}`,
160
+ onClick: () => !disabled && onToggle(),
161
+ disabled,
162
+ style: {
163
+ display: "inline-flex",
164
+ alignItems: "center",
165
+ gap: 6,
166
+ padding: "3px 10px",
167
+ fontSize: "var(--mantine-font-size-xs)",
168
+ fontWeight: 500,
169
+ lineHeight: 1.5,
170
+ color: "var(--color-text-dimmed)",
171
+ background: "transparent",
172
+ border: "1px solid var(--color-border)",
173
+ borderRadius: 999,
174
+ cursor: disabled ? "not-allowed" : "pointer",
175
+ opacity: disabled ? 0.6 : 1,
176
+ maxWidth: "100%",
177
+ transition: "background 120ms ease, border-color 120ms ease, color 120ms ease"
178
+ },
179
+ children: [
180
+ /* @__PURE__ */ jsx(Icon, { size: 12, style: { flexShrink: 0 } }),
181
+ /* @__PURE__ */ jsx(Text, { component: "span", size: "xs", truncate: true, style: { minWidth: 0 }, children: label })
182
+ ]
183
+ }
184
+ );
185
+ if (disabled && disabledTooltip) {
186
+ return /* @__PURE__ */ jsx(Tooltip, { label: disabledTooltip, withArrow: true, position: "top", children: /* @__PURE__ */ jsx("span", { children: chip }) });
187
+ }
188
+ return chip;
189
+ }
190
+ function NoteCard({ note, onPinToggle, onDelete, onEdit }) {
191
+ const isAgent = note.createdBy === "agent";
192
+ const dotColor = PRIORITY_BORDER_COLOR[note.priority] ?? PRIORITY_BORDER_COLOR.normal;
193
+ const isOrgShared = note.visibility === "org";
194
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "sm", "data-priority": note.priority, "aria-label": `Note (${note.priority} priority)`, children: /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
195
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", align: "flex-start", children: [
196
+ /* @__PURE__ */ jsxs(Stack, { gap: 4, style: { flex: 1, minWidth: 0 }, children: [
197
+ note.title && /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, truncate: true, children: note.title }),
198
+ /* @__PURE__ */ jsx(Text, { size: "sm", style: { whiteSpace: "pre-wrap", wordBreak: "break-word" }, children: note.content })
199
+ ] }),
200
+ /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
201
+ /* @__PURE__ */ jsx(
202
+ Box,
203
+ {
204
+ "data-priority-card-dot": note.priority,
205
+ style: {
206
+ width: 8,
207
+ height: 8,
208
+ borderRadius: "50%",
209
+ backgroundColor: dotColor,
210
+ boxShadow: `0 0 4px ${dotColor}40`,
211
+ flexShrink: 0,
212
+ alignSelf: "center"
213
+ }
214
+ }
215
+ ),
216
+ isAgent && /* @__PURE__ */ jsx(Tooltip, { label: `Created by ${note.source ?? "agent"}`, withArrow: true, children: /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(IconRobot, { size: 14, style: { opacity: 0.6 } }) }) }),
217
+ /* @__PURE__ */ jsx(Tooltip, { label: note.pinned ? "Unpin" : "Pin", withArrow: true, children: /* @__PURE__ */ jsx(
218
+ ActionIcon,
219
+ {
220
+ variant: "subtle",
221
+ size: "sm",
222
+ onClick: () => onPinToggle(note.id, !note.pinned),
223
+ "aria-label": note.pinned ? "Unpin note" : "Pin note",
224
+ children: note.pinned ? /* @__PURE__ */ jsx(IconPinned, { size: 14 }) : /* @__PURE__ */ jsx(IconPinnedOff, { size: 14 })
225
+ }
226
+ ) }),
227
+ /* @__PURE__ */ jsxs(Menu, { position: "bottom-end", withinPortal: true, children: [
228
+ /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", "aria-label": "Note options", children: /* @__PURE__ */ jsx(IconDotsVertical, { size: 14 }) }) }),
229
+ /* @__PURE__ */ jsxs(Menu.Dropdown, { children: [
230
+ /* @__PURE__ */ jsx(Menu.Item, { leftSection: /* @__PURE__ */ jsx(IconPencil, { size: 14 }), onClick: onEdit, children: "Edit" }),
231
+ /* @__PURE__ */ jsx(Menu.Item, { color: "red", leftSection: /* @__PURE__ */ jsx(IconTrash, { size: 14 }), onClick: () => onDelete(note.id), children: "Delete" })
232
+ ] })
233
+ ] })
234
+ ] })
235
+ ] }),
236
+ /* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", align: "center", children: [
237
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", style: { flexShrink: 0 }, children: new Date(note.updatedAt).toLocaleDateString() }),
238
+ isOrgShared && note.creatorName && /* @__PURE__ */ jsxs(Fragment, { children: [
239
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", style: { flexShrink: 0 }, children: "\xB7" }),
240
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, "data-testid": "note-creator-attribution", children: note.creatorName })
241
+ ] })
242
+ ] })
243
+ ] }) });
244
+ }
245
+ function EditNoteForm({ note, onClose, currentUserId }) {
246
+ const [title, setTitle] = useState(note.title ?? "");
247
+ const [content, setContent] = useState(note.content);
248
+ const [priority, setPriority] = useState(note.priority);
249
+ const [pinned, setPinned] = useState(note.pinned);
250
+ const [visibility, setVisibility] = useState(note.visibility);
251
+ const { mutate: updateNote, isPending } = useUpdateUserNote();
252
+ const dotColor = PRIORITY_BORDER_COLOR[priority] ?? PRIORITY_BORDER_COLOR.normal;
253
+ const isOwner = currentUserId !== null && note.userId === currentUserId;
254
+ const scopeDisabled = isPending || !isOwner;
255
+ function handleSubmit() {
256
+ if (!content.trim() || !title.trim()) return;
257
+ const patch = {
258
+ id: note.id,
259
+ content: content.trim(),
260
+ title: title.trim(),
261
+ priority,
262
+ pinned
263
+ };
264
+ if (isOwner) {
265
+ patch.visibility = visibility;
266
+ }
267
+ updateNote(patch, {
268
+ onSuccess: () => {
269
+ onClose();
270
+ }
271
+ });
272
+ }
273
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 8, children: [
274
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", align: "center", children: [
275
+ /* @__PURE__ */ jsx(CardHeader, { icon: /* @__PURE__ */ jsx(IconPencil, { size: 16 }), title: "Edit Note", titleOrder: 6, mb: 0 }),
276
+ /* @__PURE__ */ jsx(
277
+ Box,
278
+ {
279
+ "data-priority-card-dot": priority,
280
+ style: {
281
+ width: 8,
282
+ height: 8,
283
+ borderRadius: "50%",
284
+ backgroundColor: dotColor,
285
+ boxShadow: `0 0 4px ${dotColor}40`,
286
+ flexShrink: 0
287
+ }
288
+ }
289
+ )
290
+ ] }),
291
+ /* @__PURE__ */ jsx(
292
+ TextInput,
293
+ {
294
+ size: "xs",
295
+ variant: "filled",
296
+ placeholder: "Title",
297
+ required: true,
298
+ withAsterisk: false,
299
+ value: title,
300
+ onChange: (e) => setTitle(e.currentTarget.value),
301
+ disabled: isPending,
302
+ "aria-label": "Edit note title"
303
+ }
304
+ ),
305
+ /* @__PURE__ */ jsx(
306
+ Textarea,
307
+ {
308
+ size: "xs",
309
+ variant: "filled",
310
+ autosize: true,
311
+ minRows: 3,
312
+ maxRows: 10,
313
+ placeholder: "Note content\u2026",
314
+ value: content,
315
+ onChange: (e) => setContent(e.currentTarget.value),
316
+ disabled: isPending,
317
+ "aria-label": "Edit note content"
318
+ }
319
+ ),
320
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", wrap: "nowrap", gap: "md", children: [
321
+ /* @__PURE__ */ jsx(PrioritySelector, { value: priority, onChange: setPriority, disabled: isPending }),
322
+ /* @__PURE__ */ jsxs(Group, { gap: "md", wrap: "nowrap", children: [
323
+ /* @__PURE__ */ jsx(
324
+ ScopeChip,
325
+ {
326
+ visibility,
327
+ onToggle: () => setVisibility((v) => v === "private" ? "org" : "private"),
328
+ disabled: scopeDisabled,
329
+ disabledTooltip: !isOwner ? "Only the creator can change visibility" : void 0
330
+ }
331
+ ),
332
+ /* @__PURE__ */ jsx(
333
+ Checkbox,
334
+ {
335
+ size: "xs",
336
+ label: "Pin to top",
337
+ checked: pinned,
338
+ onChange: (e) => setPinned(e.currentTarget.checked),
339
+ disabled: isPending
340
+ }
341
+ )
342
+ ] })
343
+ ] }),
344
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "flex-end", mt: 4, children: [
345
+ /* @__PURE__ */ jsx(Button, { size: "xs", variant: "default", onClick: onClose, disabled: isPending, children: "Cancel" }),
346
+ /* @__PURE__ */ jsx(
347
+ Button,
348
+ {
349
+ size: "xs",
350
+ variant: "filled",
351
+ onClick: handleSubmit,
352
+ disabled: isPending || !content.trim() || !title.trim(),
353
+ loading: isPending,
354
+ children: "Save"
355
+ }
356
+ )
357
+ ] })
358
+ ] }) });
359
+ }
360
+ function CreateNoteForm({ onClose }) {
361
+ const [title, setTitle] = useState("");
362
+ const [content, setContent] = useState("");
363
+ const [priority, setPriority] = useState("normal");
364
+ const [pinned, setPinned] = useState(false);
365
+ const [visibility, setVisibility] = useState("private");
366
+ const { mutate: createNote, isPending } = useCreateUserNote();
367
+ const dotColor = PRIORITY_BORDER_COLOR[priority] ?? PRIORITY_BORDER_COLOR.normal;
368
+ function handleSubmit() {
369
+ if (!content.trim() || !title.trim()) return;
370
+ const payload = {
371
+ title: title.trim(),
372
+ content: content.trim(),
373
+ priority,
374
+ pinned,
375
+ visibility
376
+ };
377
+ createNote(payload, {
378
+ onSuccess: () => {
379
+ onClose();
380
+ }
381
+ });
382
+ }
383
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 8, children: [
384
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", align: "center", children: [
385
+ /* @__PURE__ */ jsx(CardHeader, { icon: /* @__PURE__ */ jsx(IconPlus, { size: 16 }), title: "Create Note", titleOrder: 6, mb: 0 }),
386
+ /* @__PURE__ */ jsx(
387
+ Box,
388
+ {
389
+ "data-priority-card-dot": priority,
390
+ style: {
391
+ width: 8,
392
+ height: 8,
393
+ borderRadius: "50%",
394
+ backgroundColor: dotColor,
395
+ boxShadow: `0 0 4px ${dotColor}40`,
396
+ flexShrink: 0
397
+ }
398
+ }
399
+ )
400
+ ] }),
401
+ /* @__PURE__ */ jsx(
402
+ TextInput,
403
+ {
404
+ size: "xs",
405
+ variant: "filled",
406
+ placeholder: "Title",
407
+ required: true,
408
+ withAsterisk: false,
409
+ value: title,
410
+ onChange: (e) => setTitle(e.currentTarget.value),
411
+ disabled: isPending,
412
+ "aria-label": "New note title"
413
+ }
414
+ ),
415
+ /* @__PURE__ */ jsx(
416
+ Textarea,
417
+ {
418
+ size: "xs",
419
+ variant: "filled",
420
+ autosize: true,
421
+ minRows: 3,
422
+ maxRows: 10,
423
+ placeholder: "Note content\u2026",
424
+ value: content,
425
+ onChange: (e) => setContent(e.currentTarget.value),
426
+ disabled: isPending,
427
+ "aria-label": "New note content"
428
+ }
429
+ ),
430
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", wrap: "nowrap", gap: "md", children: [
431
+ /* @__PURE__ */ jsx(PrioritySelector, { value: priority, onChange: setPriority, disabled: isPending }),
432
+ /* @__PURE__ */ jsxs(Group, { gap: "md", wrap: "nowrap", children: [
433
+ /* @__PURE__ */ jsx(
434
+ ScopeChip,
435
+ {
436
+ visibility,
437
+ onToggle: () => setVisibility((v) => v === "private" ? "org" : "private"),
438
+ disabled: isPending
439
+ }
440
+ ),
441
+ /* @__PURE__ */ jsx(
442
+ Checkbox,
443
+ {
444
+ size: "xs",
445
+ label: "Pin to top",
446
+ checked: pinned,
447
+ onChange: (e) => setPinned(e.currentTarget.checked),
448
+ disabled: isPending
449
+ }
450
+ )
451
+ ] })
452
+ ] }),
453
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "flex-end", mt: 4, children: [
454
+ /* @__PURE__ */ jsx(Button, { size: "xs", variant: "default", onClick: onClose, disabled: isPending, children: "Cancel" }),
455
+ /* @__PURE__ */ jsx(
456
+ Button,
457
+ {
458
+ size: "xs",
459
+ variant: "filled",
460
+ onClick: handleSubmit,
461
+ disabled: isPending || !content.trim() || !title.trim(),
462
+ loading: isPending,
463
+ children: "Save"
464
+ }
465
+ )
466
+ ] })
467
+ ] }) });
468
+ }
469
+ function NotesPanelView() {
470
+ const [showForm, setShowForm] = useState(false);
471
+ const [editingId, setEditingId] = useState(null);
472
+ const { data: notes, isLoading, error } = useUserNotes();
473
+ const { mutate: updateNote } = useUpdateUserNote();
474
+ const { mutate: deleteNote } = useDeleteUserNote();
475
+ const { profile } = useInitialization();
476
+ const currentUserId = profile?.id ?? null;
477
+ function handlePinToggle(id, pinned) {
478
+ updateNote({ id, pinned });
479
+ }
480
+ function handleDelete(id) {
481
+ deleteNote(id);
482
+ }
483
+ const headerRight = /* @__PURE__ */ jsxs(Group, { gap: 10, wrap: "nowrap", align: "center", children: [
484
+ /* @__PURE__ */ jsx(PriorityLegend, {}),
485
+ !showForm && /* @__PURE__ */ jsx(
486
+ UnstyledButton,
487
+ {
488
+ onClick: () => setShowForm(true),
489
+ style: {
490
+ fontSize: "var(--mantine-font-size-xs)",
491
+ color: "var(--mantine-color-blue-6)",
492
+ fontWeight: 600
493
+ },
494
+ children: "+ New Note"
495
+ }
496
+ )
497
+ ] });
498
+ return /* @__PURE__ */ jsx(NotesPanelViewShell, { title: "Notes", icon: IconNote, headerRightContent: headerRight, children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
499
+ showForm && /* @__PURE__ */ jsx(CreateNoteForm, { onClose: () => setShowForm(false) }),
500
+ isLoading && /* @__PURE__ */ jsx(Center, { py: "lg", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }),
501
+ error && /* @__PURE__ */ jsx(Text, { size: "sm", c: "red.6", children: "Failed to load notes." }),
502
+ !isLoading && !error && notes?.length === 0 && /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No notes yet. Create one above." }),
503
+ notes?.map(
504
+ (note) => editingId === note.id ? /* @__PURE__ */ jsx(EditNoteForm, { note, currentUserId, onClose: () => setEditingId(null) }, note.id) : /* @__PURE__ */ jsx(
505
+ NoteCard,
506
+ {
507
+ note,
508
+ onPinToggle: handlePinToggle,
509
+ onDelete: handleDelete,
510
+ onEdit: () => setEditingId(note.id)
511
+ },
512
+ note.id
513
+ )
514
+ )
515
+ ] }) });
516
+ }
517
+ function OverviewListRow({ icon, iconColor, iconBackground, title, onClick, meta }) {
518
+ return /* @__PURE__ */ jsxs(
519
+ "div",
520
+ {
521
+ role: onClick ? "button" : void 0,
522
+ tabIndex: onClick ? 0 : void 0,
523
+ onClick,
524
+ onKeyDown: onClick ? (e) => (e.key === "Enter" || e.key === " ") && onClick() : void 0,
525
+ style: {
526
+ display: "flex",
527
+ alignItems: "center",
528
+ gap: 8,
529
+ padding: "6px 4px",
530
+ borderRadius: "var(--mantine-radius-sm)",
531
+ cursor: onClick ? "pointer" : void 0,
532
+ transition: "background 120ms ease"
533
+ },
534
+ children: [
535
+ /* @__PURE__ */ jsx(
536
+ "div",
537
+ {
538
+ style: {
539
+ display: "flex",
540
+ alignItems: "center",
541
+ justifyContent: "center",
542
+ width: 22,
543
+ height: 22,
544
+ borderRadius: "var(--mantine-radius-sm)",
545
+ background: iconBackground,
546
+ color: iconColor,
547
+ flexShrink: 0
548
+ },
549
+ children: icon
550
+ }
551
+ ),
552
+ /* @__PURE__ */ jsx(Text, { size: "xs", style: { flex: 1, minWidth: 0 }, truncate: true, children: title }),
553
+ meta
554
+ ]
555
+ }
556
+ );
557
+ }
558
+ function OverviewList({ children }) {
559
+ return /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children });
560
+ }
561
+ var HIGHLIGHT_PRIORITIES = ["urgent", "high"];
562
+ var PRIORITY_ICON = {
563
+ urgent: IconAlertTriangle,
564
+ high: IconArrowUp,
565
+ normal: IconNote,
566
+ low: IconNote
567
+ };
568
+ function formatRelativeDate(iso) {
569
+ const then = new Date(iso).getTime();
570
+ const diffMs = Date.now() - then;
571
+ const dayMs = 24 * 60 * 60 * 1e3;
572
+ const days = Math.floor(diffMs / dayMs);
573
+ if (days <= 0) return "Today";
574
+ if (days === 1) return "Yesterday";
575
+ if (days < 7) return `${days}d ago`;
576
+ if (days < 30) return `${Math.floor(days / 7)}w ago`;
577
+ return new Date(iso).toLocaleDateString();
578
+ }
579
+ function priorityRow(note, onOpen) {
580
+ const color = PRIORITY_BORDER_COLOR[note.priority];
581
+ const Icon = PRIORITY_ICON[note.priority];
582
+ const display = note.title?.trim() || note.content;
583
+ const priorityLabel = note.priority.charAt(0).toUpperCase() + note.priority.slice(1);
584
+ return /* @__PURE__ */ jsx(
585
+ OverviewListRow,
586
+ {
587
+ icon: /* @__PURE__ */ jsx(Icon, { size: 13 }),
588
+ iconColor: color,
589
+ iconBackground: `${color}1f`,
590
+ iconTooltip: `${priorityLabel} priority`,
591
+ title: display,
592
+ onClick: onOpen,
593
+ meta: /* @__PURE__ */ jsx(Text, { size: "xs", style: { color: "var(--color-text-dimmed)", whiteSpace: "nowrap" }, children: formatRelativeDate(note.updatedAt) })
594
+ },
595
+ note.id
596
+ );
597
+ }
598
+ function PriorityNotesCard({ onNavigateToNotes }) {
599
+ const { data: notes } = useUserNotes();
600
+ const priorityNotes = (notes ?? []).filter((n) => HIGHLIGHT_PRIORITIES.includes(n.priority));
601
+ if (priorityNotes.length === 0) return null;
602
+ const urgentCount = priorityNotes.filter((n) => n.priority === "urgent").length;
603
+ return /* @__PURE__ */ jsxs(Paper, { withBorder: true, p: "md", "data-testid": "priority-notes-card", children: [
604
+ /* @__PURE__ */ jsx(
605
+ CardHeader,
606
+ {
607
+ icon: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 18 }),
608
+ title: "Priority Notes",
609
+ titleOrder: 3,
610
+ mb: "xs",
611
+ rightSection: urgentCount > 0 ? /* @__PURE__ */ jsxs(Badge, { size: "sm", variant: "light", color: "red", children: [
612
+ urgentCount,
613
+ " urgent"
614
+ ] }) : null
615
+ }
616
+ ),
617
+ /* @__PURE__ */ jsx(OverviewList, { children: priorityNotes.map((note) => priorityRow(note, onNavigateToNotes)) })
618
+ ] });
619
+ }
620
+
621
+ export { CreateNoteForm, EditNoteForm, NotesPanelView, NotesPanelViewShell, PRIORITY_BORDER_COLOR, PriorityNotesCard, ScopeChip };
@@ -761,7 +761,11 @@ declare const OrganizationModelSchema: z.ZodObject<{
761
761
  light: z.ZodOptional<z.ZodString>;
762
762
  dark: z.ZodOptional<z.ZodString>;
763
763
  }, z.core.$strip>>;
764
- }, z.core.$strip>>;
764
+ voice: z.ZodOptional<z.ZodString>;
765
+ tagline: z.ZodOptional<z.ZodString>;
766
+ values: z.ZodOptional<z.ZodArray<z.ZodString>>;
767
+ themePresetId: z.ZodOptional<z.ZodString>;
768
+ }, z.core.$loose>>;
765
769
  navigation: z.ZodDefault<z.ZodObject<{
766
770
  sidebar: z.ZodDefault<z.ZodObject<{
767
771
  primary: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<SidebarNode, unknown, z.core.$ZodTypeInternals<SidebarNode, unknown>>>>;
@@ -808,7 +812,11 @@ declare const OrganizationModelSchema: z.ZodObject<{
808
812
  }, z.core.$strip>>;
809
813
  }, z.core.$strip>>;
810
814
  clientBrief: z.ZodDefault<z.ZodString>;
811
- }, z.core.$strip>>;
815
+ organizationName: z.ZodOptional<z.ZodString>;
816
+ productName: z.ZodOptional<z.ZodString>;
817
+ shortName: z.ZodOptional<z.ZodString>;
818
+ description: z.ZodOptional<z.ZodString>;
819
+ }, z.core.$loose>>;
812
820
  customers: z.ZodDefault<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
813
821
  id: z.ZodString;
814
822
  order: z.ZodNumber;