indas-ui 0.1.10 → 0.1.12

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 (44) hide show
  1. package/dist/cjs/components/chat/multimodal-input.js +1 -1
  2. package/dist/cjs/components/dashboard/FilterBar.js +5 -3
  3. package/dist/cjs/components/datagrid/DataGrid.js +3 -3
  4. package/dist/cjs/components/datagrid/rows/FilterRow.js +1 -1
  5. package/dist/cjs/components/draft/DraftModal.js +1 -1
  6. package/dist/cjs/components/forms/date-picker/DateTimePicker.js +1 -1
  7. package/dist/cjs/components/forms/dropdown/Dropdown.js +1 -1
  8. package/dist/cjs/components/forms/file-attachment/FileAttachment.js +1 -1
  9. package/dist/cjs/components/forms/remark-input/RemarkInput.js +3 -3
  10. package/dist/cjs/components/layout/mobile-menu-sheet.js +1 -1
  11. package/dist/cjs/components/layout/top-header.js +1 -1
  12. package/dist/cjs/components/messaging/conversation-list.js +1 -1
  13. package/dist/cjs/components/messaging/create-conversation-modal.js +1 -1
  14. package/dist/cjs/components/messaging/message-input.js +1 -1
  15. package/dist/cjs/components/modals/ImageModal.js +1 -1
  16. package/dist/cjs/components/modals/Modal.js +1 -1
  17. package/dist/cjs/components/ui/buttons/button.js +1 -1
  18. package/dist/cjs/components/ui/form-toggle.js +1 -1
  19. package/dist/cjs/components/ui/forms/input.js +4 -4
  20. package/dist/cjs/components/ui/navigation/tabs.js +2 -2
  21. package/dist/cjs/styles/tokens.css +3 -0
  22. package/dist/components/chat/multimodal-input.js +1 -1
  23. package/dist/components/dashboard/FilterBar.js +5 -3
  24. package/dist/components/datagrid/DataGrid.js +3 -3
  25. package/dist/components/datagrid/rows/FilterRow.js +1 -1
  26. package/dist/components/draft/DraftModal.js +1 -1
  27. package/dist/components/forms/date-picker/DateTimePicker.js +1 -1
  28. package/dist/components/forms/dropdown/Dropdown.d.ts +1 -1
  29. package/dist/components/forms/dropdown/Dropdown.js +1 -1
  30. package/dist/components/forms/file-attachment/FileAttachment.js +1 -1
  31. package/dist/components/forms/remark-input/RemarkInput.js +3 -3
  32. package/dist/components/layout/mobile-menu-sheet.js +1 -1
  33. package/dist/components/layout/top-header.js +1 -1
  34. package/dist/components/messaging/conversation-list.js +1 -1
  35. package/dist/components/messaging/create-conversation-modal.js +1 -1
  36. package/dist/components/messaging/message-input.js +1 -1
  37. package/dist/components/modals/ImageModal.js +1 -1
  38. package/dist/components/modals/Modal.js +1 -1
  39. package/dist/components/ui/buttons/button.js +1 -1
  40. package/dist/components/ui/form-toggle.js +1 -1
  41. package/dist/components/ui/forms/input.js +4 -4
  42. package/dist/components/ui/navigation/tabs.js +2 -2
  43. package/dist/styles/tokens.css +3 -0
  44. package/package.json +1 -1
@@ -22,6 +22,9 @@
22
22
 
23
23
  /* Primary Color System (Main brand/accent) - Default #003366 */
24
24
  --color-primary: 0 51 102; /* Primary brand color #003366 */
25
+ /* What a focused field or button is outlined in. The brand colour unless the app says
26
+ otherwise: an app that keeps its brand colour for primary actions sets a neutral here. */
27
+ --color-focus: var(--color-primary);
25
28
  --color-primary-hover: 0 40 82; /* Primary hover state - darker #003366 */
26
29
  --color-primary-subtle: 250 251 252; /* Very light primary backgrounds (0.02 opacity equivalent) */
27
30
  --color-primary-muted: 102 153 204; /* Muted primary */
@@ -110,7 +110,7 @@ export function MultimodalInput({ onSubmit, onStop, isLoading = false, placehold
110
110
  const removeFile = (index) => {
111
111
  setFiles(prev => prev.filter((_, i) => i !== index));
112
112
  };
113
- return (_jsx("div", { className: cn("bg-[rgb(var(--bg-surface))] shrink-0", compact ? "px-1 py-1" : "border-t border-[rgb(var(--bd-default))] px-4 py-2.5"), children: _jsxs("div", { className: "max-w-3xl mx-auto", children: [disabled && disabledReason && (_jsxs("div", { className: "mb-2 px-3 py-2 rounded-lg bg-amber-500/10 border border-amber-500/30 text-xs text-amber-700 dark:text-amber-400 flex items-center gap-2", children: [_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "shrink-0", children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("line", { x1: "12", y1: "8", x2: "12", y2: "12" }), _jsx("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })] }), _jsx("span", { children: disabledReason })] })), files.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 mb-3", children: files.map((file, index) => (_jsxs("div", { className: "flex items-center gap-2 px-3 py-2 bg-[rgb(var(--bg-app))] border border-[rgb(var(--bd-default))] rounded-lg text-sm", children: [file.type.startsWith('image/') ? (_jsx(ImageIcon, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })) : /\.(xlsx|xls|csv)$/i.test(file.name) ? (_jsx(FileSpreadsheet, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })) : (_jsx(FileIcon, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })), _jsx("span", { className: "text-[rgb(var(--fg-default))] truncate max-w-[150px]", children: file.name }), _jsx("button", { type: "button", onClick: () => removeFile(index), "aria-label": `Remove ${file.name}`, className: "text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] transition-colors", children: _jsx(X, { className: "w-3 h-3" }) })] }, index))) })), _jsxs("div", { className: cn("relative flex items-center gap-1 bg-[rgb(var(--bg-app))]/60 backdrop-blur-xl border border-[rgb(var(--bd-default))] shadow-lg transition-all duration-250 focus-within:border-[rgb(var(--color-primary))] focus-within:shadow-[0_0_0_4px_rgb(var(--color-primary)/0.12),0_20px_25px_-5px_rgba(0,0,0,0.15)] focus-within:-translate-y-px", compact ? "rounded-xl p-1.5" : "rounded-2xl p-2.5"), children: [allowFileUpload && (_jsxs(_Fragment, { children: [_jsx("input", { ref: fileInputRef, type: "file", multiple: multiple, accept: accept, onChange: handleFileSelect, className: "hidden" }), _jsx("button", { onClick: () => fileInputRef.current?.click(), className: "shrink-0 !min-h-0 w-9 h-9 rounded-lg flex items-center justify-center transition-colors text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] hover:bg-[rgb(var(--bg-subtle))]", "aria-label": attachLabel, title: attachLabel, children: attachIcon ?? _jsx(Paperclip, { className: "w-4 h-4" }) })] })), _jsx("textarea", { ref: textareaRef, "data-chat-input": true, value: input, onChange: (e) => setInput(e.target.value), onKeyDown: handleKeyDown, placeholder: disabled ? t('Conversation closed — start a new chat')
113
+ return (_jsx("div", { className: cn("bg-[rgb(var(--bg-surface))] shrink-0", compact ? "px-1 py-1" : "border-t border-[rgb(var(--bd-default))] px-4 py-2.5"), children: _jsxs("div", { className: "max-w-3xl mx-auto", children: [disabled && disabledReason && (_jsxs("div", { className: "mb-2 px-3 py-2 rounded-lg bg-amber-500/10 border border-amber-500/30 text-xs text-amber-700 dark:text-amber-400 flex items-center gap-2", children: [_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "shrink-0", children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("line", { x1: "12", y1: "8", x2: "12", y2: "12" }), _jsx("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })] }), _jsx("span", { children: disabledReason })] })), files.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 mb-3", children: files.map((file, index) => (_jsxs("div", { className: "flex items-center gap-2 px-3 py-2 bg-[rgb(var(--bg-app))] border border-[rgb(var(--bd-default))] rounded-lg text-sm", children: [file.type.startsWith('image/') ? (_jsx(ImageIcon, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })) : /\.(xlsx|xls|csv)$/i.test(file.name) ? (_jsx(FileSpreadsheet, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })) : (_jsx(FileIcon, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })), _jsx("span", { className: "text-[rgb(var(--fg-default))] truncate max-w-[150px]", children: file.name }), _jsx("button", { type: "button", onClick: () => removeFile(index), "aria-label": `Remove ${file.name}`, className: "text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] transition-colors", children: _jsx(X, { className: "w-3 h-3" }) })] }, index))) })), _jsxs("div", { className: cn("relative flex items-center gap-1 bg-[rgb(var(--bg-app))]/60 backdrop-blur-xl border border-[rgb(var(--bd-default))] shadow-lg transition-all duration-250 focus-within:border-[rgb(var(--color-focus))] focus-within:shadow-[0_0_0_4px_rgb(var(--color-focus)/0.12),0_20px_25px_-5px_rgba(0,0,0,0.15)] focus-within:-translate-y-px", compact ? "rounded-xl p-1.5" : "rounded-2xl p-2.5"), children: [allowFileUpload && (_jsxs(_Fragment, { children: [_jsx("input", { ref: fileInputRef, type: "file", multiple: multiple, accept: accept, onChange: handleFileSelect, className: "hidden" }), _jsx("button", { onClick: () => fileInputRef.current?.click(), className: "shrink-0 !min-h-0 w-9 h-9 rounded-lg flex items-center justify-center transition-colors text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] hover:bg-[rgb(var(--bg-subtle))]", "aria-label": attachLabel, title: attachLabel, children: attachIcon ?? _jsx(Paperclip, { className: "w-4 h-4" }) })] })), _jsx("textarea", { ref: textareaRef, "data-chat-input": true, value: input, onChange: (e) => setInput(e.target.value), onKeyDown: handleKeyDown, placeholder: disabled ? t('Conversation closed — start a new chat')
114
114
  : isListening ? t('Listening...')
115
115
  : placeholder, disabled: isListening || disabled, autoFocus: !disabled, rows: 1, className: cn('flex-1 bg-transparent text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))]', 'resize-none outline-none text-sm', compact ? 'px-2 py-1.5 max-h-[120px]' : 'px-3 py-2.5 max-h-[200px]', 'overflow-y-auto', disabled && 'cursor-not-allowed') }), speechSupported && (_jsx("button", { onClick: handleVoiceInput, className: cn('shrink-0 !min-h-0 w-9 h-9 rounded-lg flex items-center justify-center transition-colors', isListening
116
116
  ? 'text-red-500 bg-red-500/10 animate-pulse'
@@ -267,7 +267,7 @@ function Stepper({ value, min, max, onChange }) {
267
267
  onChange(clamped);
268
268
  };
269
269
  const buttonClasses = cn('w-7 h-7 rounded-md flex items-center justify-center transition-colors shrink-0', 'border border-[rgb(var(--bd-default))] text-[rgb(var(--fg-muted))]', 'hover:bg-[rgb(var(--bg-subtle))] disabled:opacity-40 disabled:pointer-events-none');
270
- return (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("button", { onClick: () => onChange(value - 1), disabled: value <= min, className: buttonClasses, children: _jsx(Minus, { className: "w-3.5 h-3.5" }) }), _jsx("input", { value: text, onChange: (e) => setText(e.target.value.replace(/\D/g, '')), onBlur: commit, onKeyDown: (e) => e.key === 'Enter' && e.target.blur(), inputMode: "numeric", className: cn('flex-1 h-7 w-full min-w-0 rounded-md border border-[rgb(var(--bd-default))] bg-transparent', 'text-center text-xs font-semibold text-[rgb(var(--fg-default))]', 'focus:outline-none focus:border-[rgb(var(--color-primary))]') }), _jsx("button", { onClick: () => onChange(value + 1), disabled: value >= max, className: buttonClasses, children: _jsx(Plus, { className: "w-3.5 h-3.5" }) })] }));
270
+ return (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("button", { onClick: () => onChange(value - 1), disabled: value <= min, className: buttonClasses, children: _jsx(Minus, { className: "w-3.5 h-3.5" }) }), _jsx("input", { value: text, onChange: (e) => setText(e.target.value.replace(/\D/g, '')), onBlur: commit, onKeyDown: (e) => e.key === 'Enter' && e.target.blur(), inputMode: "numeric", className: cn('flex-1 h-7 w-full min-w-0 rounded-md border border-[rgb(var(--bd-default))] bg-transparent', 'text-center text-xs font-semibold text-[rgb(var(--fg-default))]', 'focus:outline-none focus:border-[rgb(var(--color-focus))]') }), _jsx("button", { onClick: () => onChange(value + 1), disabled: value >= max, className: buttonClasses, children: _jsx(Plus, { className: "w-3.5 h-3.5" }) })] }));
271
271
  }
272
272
  function OverflowMenu({ showInsights, insightsActive, onInsightsClick, reports, onReportSelect, onShare, onExport }) {
273
273
  const { t } = useLanguage();
@@ -411,7 +411,9 @@ export function FilterBar({ title, contextLabel, description, secondaryToggle, t
411
411
  } }))] }), _jsxs("div", { className: "flex-1 text-center", children: [_jsx("h1", { className: "text-sm font-semibold text-[rgb(var(--fg-default))]", children: title }), contextLabel && (_jsx("span", { className: "text-xs text-[rgb(var(--fg-muted))]", children: contextLabel })), description && _jsx("p", { className: "mt-0.5 text-xs text-[rgb(var(--fg-muted))]", children: description })] }), _jsxs("div", { className: "flex items-center gap-3", children: [!hideFilterButton && (_jsxs("div", { className: "relative", children: [_jsxs("button", { ref: buttonRef, onClick: () => setPopoverOpen(!popoverOpen), className: cn('w-8 h-8 rounded-md flex items-center justify-center transition-colors relative', 'border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))]', 'text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-subtle))] hover:border-[rgb(var(--color-primary))] hover:text-[rgb(var(--color-primary))]', popoverOpen && 'bg-[rgb(var(--color-primary))] text-white border-[rgb(var(--color-primary))] hover:bg-[rgb(var(--color-primary))]'), title: "Filters", children: [_jsx(ListFilter, { className: "w-4 h-4" }), hasActiveFilters && !popoverOpen && (_jsx("span", { className: "absolute -top-1 -right-1 w-2 h-2 bg-[rgb(var(--color-primary))] rounded-full" }))] }), popoverOpen && (_jsxs("div", { ref: popoverRef, className: cn('absolute top-full right-0 mt-2 z-50', 'w-[95vw] sm:w-auto', 'bg-[rgb(var(--bg-surface))] rounded-xl shadow-xl border border-[rgb(var(--bd-default))]', 'overflow-hidden'), children: [_jsxs("div", { className: "px-3 py-2 border-b border-[rgb(var(--bd-default))] flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-semibold text-[rgb(var(--fg-default))]", children: "Filters" }), _jsx("button", { onClick: () => setPopoverOpen(false), className: "w-5 h-5 rounded flex items-center justify-center hover:bg-[rgb(var(--bg-subtle))] transition-colors", children: _jsx(X, { className: "w-3 h-3 text-[rgb(var(--fg-muted))]" }) })] }), _jsxs("div", { className: "p-3 space-y-3", children: [filters.length > 0 && (_jsx("div", { className: "grid gap-3", style: { gridTemplateColumns: `repeat(${filters.length}, minmax(140px, 1fr))` }, children: filters.map((filter) => (_jsxs("div", { children: [_jsx("label", { className: "text-[10px] font-semibold text-[rgb(var(--fg-muted))] uppercase tracking-wider mb-1 block", children: filter.label }), _jsx(Dropdown, { options: filter.options, multiSelect: filter.type === 'multiselect', value: filterValues[filter.id] ?? (filter.type === 'multiselect' ? [] : ''), onValueChange: (value) => onFilterChange?.(filter.id, value), placeholder: filter.placeholder || `All ${filter.label}s`, searchable: true, className: "w-full" })] }, filter.id))) })), children, !hideDateRange && (_jsx(DatePicker, { mode: "range", value: dateRangeValue, onChange: handleDateRangeChange, inline: true }))] })] }))] })), forecast && onForecastChange && (_jsx(ForecastControl, { forecast: forecast, onForecastChange: onForecastChange, timeFilter: timeFilter, onTimeFilterChange: onTimeFilterChange })), showApplyButton && (_jsx("button", { onClick: onApply, className: cn('h-8 px-4 rounded-md flex items-center gap-1.5', 'bg-[rgb(var(--color-primary))] text-white', 'text-xs font-semibold', 'shadow-sm hover:shadow-md transition-all', 'hover:brightness-110'), children: "Apply" })), (reports.length > 0 || onShare || onExport) && (_jsx(OverflowMenu, { reports: reports, onReportSelect: onReportSelect, onShare: onShare, onExport: onExport }))] })] }) }) }));
412
412
  }
413
413
  // Default layout: Title centered, controls on right
414
- return (_jsxs("header", { className: cn('bg-[rgb(var(--bg-surface))] border-b border-[rgb(var(--bd-default))]', 'px-4 py-3 lg:px-6', className), children: [_jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-2", children: [_jsxs("div", { className: "flex-auto min-w-0 flex items-center gap-2.5", children: [_jsx("h1", { className: "text-base sm:text-xl font-bold text-[rgb(var(--fg-default))] leading-tight truncate", children: title }), contextLabel && (_jsxs("span", { className: "hidden sm:inline-flex items-center gap-1.5 shrink-0 h-6 px-2.5 rounded-full border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] text-xs font-medium text-[rgb(var(--fg-muted))]", children: [_jsx(CalendarDays, { className: "w-3.5 h-3.5" }), contextLabel] }))] }), _jsxs("div", { className: "ml-auto flex flex-wrap items-center justify-end gap-x-3 gap-y-2", children: [secondaryToggle && (_jsxs(_Fragment, { children: [_jsx("div", { ref: toggleRef, className: "hidden sm:block", children: _jsx(Tabs, { tabs: secondaryToggle.options.map(opt => ({ id: opt.value, label: opt.label })), activeTab: secondaryToggle.value, onTabChange: secondaryToggle.onChange, size: "sm" }) }), _jsx("div", { className: cn('hidden h-4 w-px bg-[rgb(var(--bd-default))] self-center', !tabsWrapped && 'sm:block') })] })), !hideTimeFilter && (_jsx("div", { ref: timeTabsRef, className: "hidden sm:block", children: _jsx(Tabs, { tabs: timeOptions.map(opt => ({ id: opt.value, label: opt.label, dropdownOptions: opt.dropdownOptions, quickOptions: opt.quickOptions })), activeTab: timeFilter, onTabChange: (tabId) => onTimeFilterChange?.(tabId), variant: "rounded", size: "sm", dropdownValues: {
414
+ return (_jsxs("header", { className: cn('bg-[rgb(var(--bg-surface))] border-b border-[rgb(var(--bd-default))]', 'px-4 py-3 lg:px-6', className), children: [_jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-2", children: [_jsxs("div", { className: "flex-auto min-w-0 flex items-center gap-2.5", children: [_jsx("h1", { className: "text-base sm:text-xl font-bold text-[rgb(var(--fg-default))] leading-tight truncate", children: title }), contextLabel && (
415
+ /* Beside the title at every width: on a phone it sat on a line of its own under the title. */
416
+ _jsxs("span", { className: "inline-flex items-center gap-1.5 shrink-0 h-6 px-2.5 rounded-full border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] text-xs font-medium text-[rgb(var(--fg-muted))]", children: [_jsx(CalendarDays, { className: "w-3.5 h-3.5" }), contextLabel] }))] }), _jsxs("div", { className: "ml-auto flex flex-wrap items-center justify-end gap-x-3 gap-y-2", children: [secondaryToggle && (_jsxs(_Fragment, { children: [_jsx("div", { ref: toggleRef, className: "hidden sm:block", children: _jsx(Tabs, { tabs: secondaryToggle.options.map(opt => ({ id: opt.value, label: opt.label })), activeTab: secondaryToggle.value, onTabChange: secondaryToggle.onChange, size: "sm" }) }), _jsx("div", { className: cn('hidden h-4 w-px bg-[rgb(var(--bd-default))] self-center', !tabsWrapped && 'sm:block') })] })), !hideTimeFilter && (_jsx("div", { ref: timeTabsRef, className: "hidden sm:block", children: _jsx(Tabs, { tabs: timeOptions.map(opt => ({ id: opt.value, label: opt.label, dropdownOptions: opt.dropdownOptions, quickOptions: opt.quickOptions })), activeTab: timeFilter, onTabChange: (tabId) => onTimeFilterChange?.(tabId), variant: "rounded", size: "sm", dropdownValues: {
415
417
  Day: timeFilterSelection?.days || [],
416
418
  Week: timeFilterSelection?.weeks || [],
417
419
  Month: timeFilterSelection?.months || [],
@@ -430,7 +432,7 @@ export function FilterBar({ title, contextLabel, description, secondaryToggle, t
430
432
  onTimeFilterSelectionChange?.(newSelection);
431
433
  } }) })), _jsxs("div", { className: "flex items-center gap-0.5 rounded-lg border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))] p-0.5", children: [!hideFilterButton && (_jsxs("div", { className: "relative", children: [_jsxs("button", { ref: buttonRef, onClick: () => setPopoverOpen(!popoverOpen), className: cn('w-7 h-7 rounded-md flex items-center justify-center transition-colors relative', popoverOpen
432
434
  ? 'bg-[rgb(var(--color-primary))] text-white shadow-sm'
433
- : 'text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] hover:bg-[rgb(var(--bg-subtle))]'), title: "Filters", children: [_jsx(ListFilter, { className: "w-4 h-4" }), hasActiveFilters && !popoverOpen && (_jsx("span", { className: "absolute -top-1 -right-1 w-2 h-2 bg-[rgb(var(--color-primary))] rounded-full" }))] }), popoverOpen && (_jsxs("div", { ref: popoverRef, className: cn('absolute top-full right-0 mt-2 z-50', 'w-[95vw] sm:w-auto', 'bg-[rgb(var(--bg-surface))] rounded-xl shadow-xl border border-[rgb(var(--bd-default))]', 'overflow-hidden'), children: [_jsxs("div", { className: "px-3 py-2 border-b border-[rgb(var(--bd-default))] flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-semibold text-[rgb(var(--fg-default))]", children: "Filters" }), _jsx("button", { onClick: () => setPopoverOpen(false), className: "w-5 h-5 rounded flex items-center justify-center hover:bg-[rgb(var(--bg-subtle))] transition-colors", children: _jsx(X, { className: "w-3 h-3 text-[rgb(var(--fg-muted))]" }) })] }), _jsxs("div", { className: "p-3 space-y-3", children: [filters.length > 0 && (_jsx("div", { className: "grid gap-3", style: { gridTemplateColumns: `repeat(${Math.min(filters.length, 3)}, minmax(140px, 1fr))` }, children: filters.map((filter) => (_jsxs("div", { children: [_jsx("label", { className: "text-[10px] font-semibold text-[rgb(var(--fg-muted))] uppercase tracking-wider mb-1 block", children: filter.label }), _jsx(Dropdown, { options: filter.options, multiSelect: filter.type === 'multiselect', value: filterValues[filter.id] ?? (filter.type === 'multiselect' ? [] : ''), onValueChange: (value) => onFilterChange?.(filter.id, value), placeholder: filter.placeholder || `All ${filter.label}s`, searchable: true, className: "w-full" })] }, filter.id))) })), children, !hideDateRange && (_jsx(DatePicker, { mode: "range", value: dateRangeValue, onChange: handleDateRangeChange, inline: true }))] })] }))] })), forecast && onForecastChange && (_jsx(ForecastControl, { forecast: forecast, onForecastChange: onForecastChange, timeFilter: timeFilter, onTimeFilterChange: onTimeFilterChange, bare: true })), (showInsights || reports.length > 0 || onShare || onExport) && (_jsx(OverflowMenu, { showInsights: showInsights, insightsActive: insightsActive, onInsightsClick: onInsightsClick, reports: reports, onReportSelect: onReportSelect, onShare: onShare, onExport: onExport }))] }), showApplyButton && (_jsx("button", { onClick: onApply, className: cn('h-8 px-4 rounded-md flex items-center gap-1.5', 'bg-[rgb(var(--color-primary))] text-white', 'text-xs font-semibold', 'shadow-sm hover:shadow-md transition-all', 'hover:brightness-110'), children: "Apply" }))] })] }), contextLabel && (_jsxs("span", { className: "sm:hidden mt-2 inline-flex items-center gap-1.5 h-6 px-2.5 rounded-full border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] text-xs font-medium text-[rgb(var(--fg-muted))]", children: [_jsx(CalendarDays, { className: "w-3.5 h-3.5" }), contextLabel] })), (!hideTimeFilter || secondaryToggle) && (_jsxs("div", { className: "sm:hidden mt-2 flex flex-col items-start gap-2", children: [secondaryToggle && (_jsx(Tabs, { tabs: secondaryToggle.options.map(opt => ({ id: opt.value, label: opt.label })), activeTab: secondaryToggle.value, onTabChange: secondaryToggle.onChange, size: "sm" })), !hideTimeFilter && (_jsx(Tabs, { tabs: timeOptions.map(opt => ({ id: opt.value, label: opt.label, dropdownOptions: opt.dropdownOptions, quickOptions: opt.quickOptions })), activeTab: timeFilter, onTabChange: (tabId) => onTimeFilterChange?.(tabId), variant: "rounded", size: "sm", dropdownValues: {
435
+ : 'text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] hover:bg-[rgb(var(--bg-subtle))]'), title: "Filters", children: [_jsx(ListFilter, { className: "w-4 h-4" }), hasActiveFilters && !popoverOpen && (_jsx("span", { className: "absolute -top-1 -right-1 w-2 h-2 bg-[rgb(var(--color-primary))] rounded-full" }))] }), popoverOpen && (_jsxs("div", { ref: popoverRef, className: cn('absolute top-full right-0 mt-2 z-50', 'w-[95vw] sm:w-auto', 'bg-[rgb(var(--bg-surface))] rounded-xl shadow-xl border border-[rgb(var(--bd-default))]', 'overflow-hidden'), children: [_jsxs("div", { className: "px-3 py-2 border-b border-[rgb(var(--bd-default))] flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-semibold text-[rgb(var(--fg-default))]", children: "Filters" }), _jsx("button", { onClick: () => setPopoverOpen(false), className: "w-5 h-5 rounded flex items-center justify-center hover:bg-[rgb(var(--bg-subtle))] transition-colors", children: _jsx(X, { className: "w-3 h-3 text-[rgb(var(--fg-muted))]" }) })] }), _jsxs("div", { className: "p-3 space-y-3", children: [filters.length > 0 && (_jsx("div", { className: "grid gap-3", style: { gridTemplateColumns: `repeat(${Math.min(filters.length, 3)}, minmax(140px, 1fr))` }, children: filters.map((filter) => (_jsxs("div", { children: [_jsx("label", { className: "text-[10px] font-semibold text-[rgb(var(--fg-muted))] uppercase tracking-wider mb-1 block", children: filter.label }), _jsx(Dropdown, { options: filter.options, multiSelect: filter.type === 'multiselect', value: filterValues[filter.id] ?? (filter.type === 'multiselect' ? [] : ''), onValueChange: (value) => onFilterChange?.(filter.id, value), placeholder: filter.placeholder || `All ${filter.label}s`, searchable: true, className: "w-full" })] }, filter.id))) })), children, !hideDateRange && (_jsx(DatePicker, { mode: "range", value: dateRangeValue, onChange: handleDateRangeChange, inline: true }))] })] }))] })), forecast && onForecastChange && (_jsx(ForecastControl, { forecast: forecast, onForecastChange: onForecastChange, timeFilter: timeFilter, onTimeFilterChange: onTimeFilterChange, bare: true })), (showInsights || reports.length > 0 || onShare || onExport) && (_jsx(OverflowMenu, { showInsights: showInsights, insightsActive: insightsActive, onInsightsClick: onInsightsClick, reports: reports, onReportSelect: onReportSelect, onShare: onShare, onExport: onExport }))] }), showApplyButton && (_jsx("button", { onClick: onApply, className: cn('h-8 px-4 rounded-md flex items-center gap-1.5', 'bg-[rgb(var(--color-primary))] text-white', 'text-xs font-semibold', 'shadow-sm hover:shadow-md transition-all', 'hover:brightness-110'), children: "Apply" }))] })] }), (!hideTimeFilter || secondaryToggle) && (_jsxs("div", { className: "sm:hidden mt-2 -mx-1 flex items-center gap-2 overflow-x-auto px-1 pb-0.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden [&>*]:shrink-0", children: [secondaryToggle && (_jsx(Tabs, { tabs: secondaryToggle.options.map(opt => ({ id: opt.value, label: opt.label })), activeTab: secondaryToggle.value, onTabChange: secondaryToggle.onChange, size: "sm" })), !hideTimeFilter && (_jsx(Tabs, { tabs: timeOptions.map(opt => ({ id: opt.value, label: opt.label, dropdownOptions: opt.dropdownOptions, quickOptions: opt.quickOptions })), activeTab: timeFilter, onTabChange: (tabId) => onTimeFilterChange?.(tabId), variant: "rounded", size: "sm", dropdownValues: {
434
436
  Day: timeFilterSelection?.days || [],
435
437
  Week: timeFilterSelection?.weeks || [],
436
438
  Month: timeFilterSelection?.months || [],
@@ -1316,7 +1316,7 @@ enableFilterRow = false, initialColumnFilters, }) {
1316
1316
  }
1317
1317
  }, className: `px-2 sm:px-4 py-1 sm:py-1.5 text-[10px] sm:text-xs font-medium rounded-full transition-all duration-150 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary/50 whitespace-nowrap ${viewMode === 'selected'
1318
1318
  ? 'bg-primary text-white shadow-sm'
1319
- : 'text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))] hover:text-[rgb(var(--fg-default))]'}`, "aria-label": `View selected items (${safeSelectedCount} selected)`, children: [_jsx("span", { className: "hidden sm:inline", children: "Selected " }), "(", safeSelectedCount, ")"] })] }, "view-toggle")), preDateActions, enableSearch && (_jsxs("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [_jsx("div", { className: "min-w-0 flex-1", children: effectiveSearchType === 'advanced' ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { delayDuration: 100, children: _jsxs("div", { className: "flex items-center h-8 rounded-full border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))] px-3 focus-within:border-[rgb(var(--color-primary))] focus-within:ring-1 focus-within:ring-[rgb(var(--color-primary)/0.2)] transition-all", children: [_jsxs("div", { className: "flex items-center gap-1.5 flex-1 min-w-0", children: [speechSupported && (_jsx("button", { type: "button", onClick: handleVoiceSearch, className: `flex-shrink-0 transition-colors ${isListening ? 'text-[rgb(var(--color-error))] animate-pulse' : 'text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))]'}`, title: isListening ? 'Stop listening' : 'Voice search', children: isListening ? _jsx(MicOff, { className: "h-3.5 w-3.5" }) : _jsx(Mic, { className: "h-3.5 w-3.5" }) })), _jsx("input", { ref: searchInputRef, placeholder: speechSupported ? 'Type or speak to search...' : 'Search...', value: searchValue, onChange: (e) => handleGlobalSearchChange(e.target.value), className: "flex-1 min-w-0 w-full bg-transparent border-none outline-none text-xs text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))]" })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0 ml-2", children: [_jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))]" }), enableDateFilter && (_jsx(DatePicker, { mode: "range", value: { from: dateFrom || undefined, to: dateTo || undefined }, onChange: (range) => {
1319
+ : 'text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))] hover:text-[rgb(var(--fg-default))]'}`, "aria-label": `View selected items (${safeSelectedCount} selected)`, children: [_jsx("span", { className: "hidden sm:inline", children: "Selected " }), "(", safeSelectedCount, ")"] })] }, "view-toggle")), preDateActions, enableSearch && (_jsxs("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [_jsx("div", { className: "min-w-0 flex-1", children: effectiveSearchType === 'advanced' ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { delayDuration: 100, children: _jsxs("div", { className: "flex items-center h-8 rounded-full border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))] px-3 focus-within:border-[rgb(var(--color-focus))] focus-within:ring-1 focus-within:ring-[rgb(var(--color-focus)/0.2)] transition-all", children: [_jsxs("div", { className: "flex items-center gap-1.5 flex-1 min-w-0", children: [speechSupported && (_jsx("button", { type: "button", onClick: handleVoiceSearch, className: `flex-shrink-0 transition-colors ${isListening ? 'text-[rgb(var(--color-error))] animate-pulse' : 'text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))]'}`, title: isListening ? 'Stop listening' : 'Voice search', children: isListening ? _jsx(MicOff, { className: "h-3.5 w-3.5" }) : _jsx(Mic, { className: "h-3.5 w-3.5" }) })), _jsx("input", { ref: searchInputRef, placeholder: speechSupported ? 'Type or speak to search...' : 'Search...', value: searchValue, onChange: (e) => handleGlobalSearchChange(e.target.value), className: "flex-1 min-w-0 w-full bg-transparent border-none outline-none text-xs text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))]" })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0 ml-2", children: [_jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))]" }), enableDateFilter && (_jsx(DatePicker, { mode: "range", value: { from: dateFrom || undefined, to: dateTo || undefined }, onChange: (range) => {
1320
1320
  if (range && typeof range === 'object' && 'from' in range) {
1321
1321
  onDateFromChange?.(range.from || null);
1322
1322
  onDateToChange?.(range.to || null);
@@ -1342,7 +1342,7 @@ enableFilterRow = false, initialColumnFilters, }) {
1342
1342
  }, "aria-label": "Auto-size all columns to fit content", children: "Auto-size" })] })] }) }), enableColumnFreezing && frozenColumns.length > 0 && (_jsx("div", { className: "px-2 py-1", children: _jsx("div", { className: "bg-[rgb(var(--color-primary-subtle))] rounded-md p-1 space-y-0.5", children: frozenColumns.map((column) => (_jsxs("div", { className: "flex items-center justify-between px-2 py-1.5 hover:bg-[rgb(var(--bg-selected))]/50 rounded group cursor-pointer", children: [_jsxs("div", { className: "flex items-center space-x-2 flex-1", children: [_jsx("input", { type: "checkbox", checked: column.getIsVisible(), onChange: (e) => {
1343
1343
  e.stopPropagation();
1344
1344
  column.toggleVisibility(e.target.checked);
1345
- }, className: "w-3 h-3 rounded border-[rgb(var(--bd-default))] text-[rgb(var(--color-primary))] focus:ring-[rgb(var(--color-primary))] cursor-pointer" }), _jsx("span", { className: "text-sm font-medium text-[rgb(var(--fg-default))] capitalize truncate", children: column.id })] }), _jsx(Button, { variant: "ghost", size: "sm", className: "h-7 w-7 p-0 text-[rgb(var(--color-primary))] hover:text-[rgb(var(--color-primary-hover))] hover:bg-[rgb(var(--bg-selected))] opacity-70 group-hover:opacity-100 transition-opacity cursor-pointer", onClick: (e) => {
1345
+ }, className: "w-3 h-3 rounded border-[rgb(var(--bd-default))] text-[rgb(var(--color-primary))] focus:ring-[rgb(var(--color-focus))] cursor-pointer" }), _jsx("span", { className: "text-sm font-medium text-[rgb(var(--fg-default))] capitalize truncate", children: column.id })] }), _jsx(Button, { variant: "ghost", size: "sm", className: "h-7 w-7 p-0 text-[rgb(var(--color-primary))] hover:text-[rgb(var(--color-primary-hover))] hover:bg-[rgb(var(--bg-selected))] opacity-70 group-hover:opacity-100 transition-opacity cursor-pointer", onClick: (e) => {
1346
1346
  e.stopPropagation();
1347
1347
  const newFrozenColumns = new Set(frozenColumnsState);
1348
1348
  newFrozenColumns.delete(column.id);
@@ -1352,7 +1352,7 @@ enableFilterRow = false, initialColumnFilters, }) {
1352
1352
  return (_jsxs("div", { className: "flex items-center justify-between px-2 py-1.5 hover:bg-[rgb(var(--bg-subtle))] rounded group cursor-pointer", children: [_jsxs("div", { className: "flex items-center space-x-2 flex-1", children: [_jsx("input", { type: "checkbox", checked: column.getIsVisible(), onChange: (e) => {
1353
1353
  e.stopPropagation();
1354
1354
  column.toggleVisibility(e.target.checked);
1355
- }, className: "w-3 h-3 rounded border-[rgb(var(--bd-default))] text-[rgb(var(--color-primary))] focus:ring-[rgb(var(--color-primary))] cursor-pointer" }), _jsx("span", { className: "text-sm text-[rgb(var(--fg-default))] capitalize truncate", children: column.id })] }), enableColumnFreezing && !isSelectColumn && (_jsx(Button, { variant: "ghost", size: "sm", className: "h-7 w-7 p-0 text-[rgb(var(--color-icon))] hover:text-[rgb(var(--color-icon-hover))] hover:bg-[rgb(var(--bg-hover))] opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer", onClick: (e) => {
1355
+ }, className: "w-3 h-3 rounded border-[rgb(var(--bd-default))] text-[rgb(var(--color-primary))] focus:ring-[rgb(var(--color-focus))] cursor-pointer" }), _jsx("span", { className: "text-sm text-[rgb(var(--fg-default))] capitalize truncate", children: column.id })] }), enableColumnFreezing && !isSelectColumn && (_jsx(Button, { variant: "ghost", size: "sm", className: "h-7 w-7 p-0 text-[rgb(var(--color-icon))] hover:text-[rgb(var(--color-icon-hover))] hover:bg-[rgb(var(--bg-hover))] opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer", onClick: (e) => {
1356
1356
  e.stopPropagation();
1357
1357
  const newFrozenColumns = new Set(frozenColumnsState);
1358
1358
  newFrozenColumns.add(column.id);
@@ -133,7 +133,7 @@ function FilterCell({ header, isFrozen, isPinnedRight, leftPosition, rightPositi
133
133
  })
134
134
  }, className: cn('px-1 text-left align-middle', 'bg-[color-mix(in_srgb,rgb(var(--color-primary))_5%,white)]', 'dark:bg-[color-mix(in_srgb,rgb(var(--color-primary))_5%,rgb(var(--bg-surface)))]'), children: skipFilter ? (
135
135
  // Empty cell for select/action columns
136
- _jsx("div", { className: "h-full" })) : (_jsxs("div", { className: "relative flex items-center h-full", children: [_jsx("div", { className: "absolute left-1.5 top-1/2 -translate-y-1/2 pointer-events-none opacity-50", children: isDate ? (_jsx(Calendar, { className: "h-3 w-3 text-[rgb(var(--color-icon))]" })) : (_jsx(Search, { className: "h-3 w-3 text-[rgb(var(--color-icon))]" })) }), _jsx("input", { ref: inputRef, type: isNumber ? 'number' : 'text', value: localValue, onChange: handleChange, placeholder: "", className: cn('w-full h-6 pl-6 pr-5 text-xs', 'bg-[rgb(var(--bg-surface))] rounded', 'focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-primary))] focus:border-[rgb(var(--color-primary))]', 'placeholder:text-[rgb(var(--fg-muted))]', 'text-[rgb(var(--fg-default))]',
136
+ _jsx("div", { className: "h-full" })) : (_jsxs("div", { className: "relative flex items-center h-full", children: [_jsx("div", { className: "absolute left-1.5 top-1/2 -translate-y-1/2 pointer-events-none opacity-50", children: isDate ? (_jsx(Calendar, { className: "h-3 w-3 text-[rgb(var(--color-icon))]" })) : (_jsx(Search, { className: "h-3 w-3 text-[rgb(var(--color-icon))]" })) }), _jsx("input", { ref: inputRef, type: isNumber ? 'number' : 'text', value: localValue, onChange: handleChange, placeholder: "", className: cn('w-full h-6 pl-6 pr-5 text-xs', 'bg-[rgb(var(--bg-surface))] rounded', 'focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-focus))] focus:border-[rgb(var(--color-focus))]', 'placeholder:text-[rgb(var(--fg-muted))]', 'text-[rgb(var(--fg-default))]',
137
137
  // Highlight active filter
138
138
  localValue
139
139
  ? 'border-2 border-[rgb(var(--color-primary))] bg-[color-mix(in_srgb,rgb(var(--color-primary))_5%,rgb(var(--bg-surface)))]'
@@ -156,7 +156,7 @@ export function DraftModal({ open, onClose, drafts, onLoad, onDelete, isLoading
156
156
  // Early return after all hooks to comply with Rules of Hooks
157
157
  if (!open)
158
158
  return null;
159
- return (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm", children: _jsxs("div", { className: "bg-[rgb(var(--bg-surface))] rounded-lg shadow-2xl w-full max-w-4xl max-h-[85vh] flex flex-col", children: [_jsxs("div", { className: "px-6 py-3 border-b border-[rgb(var(--bd-default))] flex items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx(FileText, { className: "w-5 h-5 text-[rgb(var(--color-primary))]" }), _jsx("h2", { className: "text-base font-semibold text-[rgb(var(--fg-default))]", children: "Saved Drafts" }), _jsxs("span", { className: "text-xs text-[rgb(var(--fg-muted))]", children: ["(", drafts.length, ")"] })] }), _jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-[rgb(var(--fg-muted))]" }), _jsx("input", { type: "text", placeholder: "Search...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "\n w-full pl-9 pr-3 py-1.5 rounded-lg text-sm\n bg-[rgb(var(--bg-default))]\n border border-[rgb(var(--bd-default))]\n text-[rgb(var(--fg-default))]\n placeholder:text-[rgb(var(--fg-muted))]\n focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-primary))]\n " })] }), _jsx("div", { className: "flex-shrink-0 w-36", children: _jsx(Dropdown, { options: SORT_OPTIONS, value: sortBy, onValueChange: (val) => setSortBy(val), size: "sm", autoWidth: true }) }), _jsx("button", { onClick: onClose, className: "p-1.5 rounded-lg hover:bg-[rgb(var(--bg-muted))] text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] transition-colors flex-shrink-0", children: _jsx(X, { className: "w-5 h-5" }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-6 py-4", children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-16", children: _jsxs("div", { className: "text-center", children: [_jsx("div", { className: "w-12 h-12 rounded-full border-4 border-[rgb(var(--color-primary)_/_0.2)] border-t-[rgb(var(--color-primary))] animate-spin mx-auto mb-3" }), _jsx("p", { className: "text-[rgb(var(--fg-muted))]", children: "Loading drafts..." })] }) })) : filteredAndSortedDrafts.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [_jsx(FileText, { className: "w-16 h-16 text-[rgb(var(--fg-muted))] mb-4 opacity-50" }), _jsx("p", { className: "text-lg font-medium text-[rgb(var(--fg-default))] mb-1", children: searchQuery ? 'No matching drafts' : 'No drafts saved yet' }), _jsx("p", { className: "text-sm text-[rgb(var(--fg-muted))]", children: searchQuery ? 'Try a different search term' : 'Start by clicking "Save Draft" button' })] })) : (_jsx("div", { className: "space-y-3", children: paginatedDrafts.map((draft) => {
159
+ return (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm", children: _jsxs("div", { className: "bg-[rgb(var(--bg-surface))] rounded-lg shadow-2xl w-full max-w-4xl max-h-[85vh] flex flex-col", children: [_jsxs("div", { className: "px-6 py-3 border-b border-[rgb(var(--bd-default))] flex items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx(FileText, { className: "w-5 h-5 text-[rgb(var(--color-primary))]" }), _jsx("h2", { className: "text-base font-semibold text-[rgb(var(--fg-default))]", children: "Saved Drafts" }), _jsxs("span", { className: "text-xs text-[rgb(var(--fg-muted))]", children: ["(", drafts.length, ")"] })] }), _jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-[rgb(var(--fg-muted))]" }), _jsx("input", { type: "text", placeholder: "Search...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "\n w-full pl-9 pr-3 py-1.5 rounded-lg text-sm\n bg-[rgb(var(--bg-default))]\n border border-[rgb(var(--bd-default))]\n text-[rgb(var(--fg-default))]\n placeholder:text-[rgb(var(--fg-muted))]\n focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-focus))]\n " })] }), _jsx("div", { className: "flex-shrink-0 w-36", children: _jsx(Dropdown, { options: SORT_OPTIONS, value: sortBy, onValueChange: (val) => setSortBy(val), size: "sm", autoWidth: true }) }), _jsx("button", { onClick: onClose, className: "p-1.5 rounded-lg hover:bg-[rgb(var(--bg-muted))] text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] transition-colors flex-shrink-0", children: _jsx(X, { className: "w-5 h-5" }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-6 py-4", children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-16", children: _jsxs("div", { className: "text-center", children: [_jsx("div", { className: "w-12 h-12 rounded-full border-4 border-[rgb(var(--color-primary)_/_0.2)] border-t-[rgb(var(--color-primary))] animate-spin mx-auto mb-3" }), _jsx("p", { className: "text-[rgb(var(--fg-muted))]", children: "Loading drafts..." })] }) })) : filteredAndSortedDrafts.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [_jsx(FileText, { className: "w-16 h-16 text-[rgb(var(--fg-muted))] mb-4 opacity-50" }), _jsx("p", { className: "text-lg font-medium text-[rgb(var(--fg-default))] mb-1", children: searchQuery ? 'No matching drafts' : 'No drafts saved yet' }), _jsx("p", { className: "text-sm text-[rgb(var(--fg-muted))]", children: searchQuery ? 'Try a different search term' : 'Start by clicking "Save Draft" button' })] })) : (_jsx("div", { className: "space-y-3", children: paginatedDrafts.map((draft) => {
160
160
  const progress = calculateProgress(draft);
161
161
  const preview = draft.previewData || {};
162
162
  return (_jsx("div", { className: "\n group relative p-3 rounded-lg\n bg-[rgb(var(--bg-default))]\n border border-[rgb(var(--bd-default))]\n hover:border-[rgb(var(--color-primary))]\n hover:shadow-lg\n transition-all duration-200\n ", children: _jsx("div", { className: "flex items-start gap-4", children: _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h3", { className: "font-semibold text-[rgb(var(--fg-default))] truncate text-base", children: draft.draftName || 'Untitled Draft' }), _jsxs("div", { className: "flex items-center gap-2 mt-1 text-xs text-[rgb(var(--fg-muted))]", children: [_jsx("span", { children: formatRelativeTime(draft.lastSaved) }), _jsxs("span", { className: "hidden group-hover:inline", children: ["\u2022 ", formatFullDate(draft.lastSaved)] }), draft.isAutoSave && (_jsx("span", { className: "text-[10px] px-2 py-0.5 rounded-full bg-[rgb(var(--color-primary)_/_0.1)] text-[rgb(var(--color-primary))] font-medium", children: "AUTO-SAVE" }))] })] }), _jsxs("div", { className: "flex items-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity", children: [_jsxs("button", { onClick: () => handleLoad(draft.draftId), className: "\n px-4 py-2 rounded-lg text-sm font-medium\n bg-[rgb(var(--color-primary))]\n text-white\n hover:opacity-90\n transition-opacity\n flex items-center gap-2\n ", children: [_jsx(Download, { className: "w-4 h-4" }), "Load"] }), _jsx("button", { onClick: () => handleDelete(draft.draftId), disabled: deletingId === draft.draftId, className: "\n p-2 rounded-lg\n text-[rgb(var(--fg-muted))]\n hover:text-red-600\n hover:bg-red-50\n transition-colors\n disabled:opacity-50\n ", title: "Delete draft", children: deletingId === draft.draftId ? (_jsx("div", { className: "w-4 h-4 rounded-full border-2 border-red-200 border-t-red-600 animate-spin" })) : (_jsx(Trash2, { className: "w-4 h-4" })) })] })] }), _jsxs("div", { className: "grid grid-cols-2 gap-x-6 gap-y-1 mt-2 text-sm", children: [preview.jobName && (_jsx("div", { className: "text-[rgb(var(--fg-muted))] truncate", children: preview.jobName }, "job")), preview.clientName && (_jsx("div", { className: "text-[rgb(var(--fg-muted))] truncate", children: preview.clientName }, "client")), preview.category && (_jsx("div", { className: "text-[rgb(var(--fg-muted))] truncate", children: preview.category }, "category")), preview.totalCost !== undefined && preview.totalCost > 0 && (_jsxs("div", { className: "font-medium text-[rgb(var(--color-primary))]", children: [currencySymbol, preview.totalCost.toLocaleString('en-IN')] }, "cost"))] }), progress > 0 && (_jsxs("div", { className: "mt-2", children: [_jsxs("div", { className: "flex items-center justify-between text-xs text-[rgb(var(--fg-muted))] mb-1", children: [_jsx("span", { children: "Progress" }), _jsxs("span", { className: "font-medium", children: [progress, "%"] })] }), _jsx("div", { className: "h-1.5 bg-[rgb(var(--bg-muted))] rounded-full overflow-hidden", children: _jsx("div", { className: "h-full bg-[rgb(var(--color-primary))] transition-all duration-500 rounded-full", style: { width: `${progress}%` } }) })] }))] }) }) }, draft.draftId));
@@ -129,7 +129,7 @@ export function DateTimePicker({ value, onChange, placeholder = 'Select date & t
129
129
  e.preventDefault();
130
130
  onChange(value === 0 ? max : value - 1);
131
131
  }
132
- }, className: "w-14 text-center text-lg font-semibold border border-[rgb(var(--bd-default))] rounded-lg px-2 py-1 focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-primary))] focus:border-transparent transition-all hover:border-[rgb(var(--color-primary))]", "aria-label": label }), _jsx("span", { className: "text-[10px] text-[rgb(var(--fg-muted))] mt-0.5", children: label })] }), _jsx("button", { onClick: () => onChange(value === 0 ? max : value - 1), className: "h-6 w-full flex items-center justify-center text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--color-primary))] hover:bg-[rgb(var(--bg-hover))] rounded transition-colors active:scale-95", "aria-label": `Decrease ${label}`, children: _jsx(ChevronLeft, { className: "h-4 w-4 -rotate-90" }) })] }));
132
+ }, className: "w-14 text-center text-lg font-semibold border border-[rgb(var(--bd-default))] rounded-lg px-2 py-1 focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-focus))] focus:border-transparent transition-all hover:border-[rgb(var(--color-primary))]", "aria-label": label }), _jsx("span", { className: "text-[10px] text-[rgb(var(--fg-muted))] mt-0.5", children: label })] }), _jsx("button", { onClick: () => onChange(value === 0 ? max : value - 1), className: "h-6 w-full flex items-center justify-center text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--color-primary))] hover:bg-[rgb(var(--bg-hover))] rounded transition-colors active:scale-95", "aria-label": `Decrease ${label}`, children: _jsx(ChevronLeft, { className: "h-4 w-4 -rotate-90" }) })] }));
133
133
  return (_jsxs("div", { className: cn('relative w-full', className), children: [label && (_jsx("label", { className: "block text-sm font-medium text-[rgb(var(--fg-default))] mb-2", children: label })), _jsxs(Popover.Root, { open: isOpen, onOpenChange: setIsOpen, children: [_jsx(Popover.Trigger, { asChild: true, children: _jsx("div", { className: "relative", children: _jsx(Input, { value: inputValue, onChange: (e) => setInputValue(e.target.value), placeholder: placeholder, disabled: disabled, error: error, className: cn('pl-2 pr-9 text-xs w-full', error && 'border-red-300'), onFocus: () => !disabled && setIsOpen(true), rightIcon: Calendar, onRightIconClick: () => !disabled && setIsOpen(!isOpen), readOnly: true }) }) }), _jsx(Popover.Portal, { container: typeof document !== 'undefined' ? document.body : undefined, children: _jsxs(Popover.Content, { className: cn('z-[300] bg-white rounded-xl shadow-2xl border border-gray-200/50 backdrop-blur-sm', 'data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95', 'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95', 'w-[95vw] sm:w-[380px] max-w-[calc(100vw-2rem)] p-3 sm:p-4'), side: "bottom", align: "start", sideOffset: 8, avoidCollisions: true, collisionPadding: 16, onOpenAutoFocus: (e) => e.preventDefault(), children: [_jsxs("div", { className: "flex items-center justify-between mb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Calendar, { className: "h-4 w-4 text-[rgb(var(--color-primary))]" }), _jsx("span", { className: "text-sm font-semibold text-[rgb(var(--fg-default))]", children: "Select Date & Time" })] }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setIsOpen(false), className: "h-6 w-6 p-0 hover:bg-red-50 hover:text-red-600 transition-all duration-200", children: _jsx(X, { className: "h-3 w-3" }) })] }), _jsx(CalendarView, { currentMonth: selectedDate || new Date(), selectedDate: selectedDate, onDateClick: handleDateClick, onMonthChange: handleMonthChange, minDate: minDate, maxDate: maxDate, showNavigation: true }), _jsxs("div", { className: "border-t border-[rgb(var(--bd-default))] pt-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-3", children: [_jsx(Clock, { className: "h-4 w-4 text-[rgb(var(--color-primary))]" }), _jsx("span", { className: "text-sm font-semibold text-[rgb(var(--fg-default))]", children: "Time" })] }), _jsxs("div", { className: "flex items-center justify-center gap-2", children: [renderTimeInput(hours, setHours, timeFormat === '12h' ? 12 : 23, 'Hours'), _jsx("span", { className: "text-2xl font-bold text-[rgb(var(--fg-muted))] mb-5", children: ":" }), renderTimeInput(minutes, setMinutes, 59, 'Mins'), timeFormat === '12h' && (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-px h-16 bg-[rgb(var(--bd-default))] mx-2" }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("button", { onClick: () => setPeriod('AM'), className: cn('px-3 py-1.5 text-sm font-semibold rounded-lg transition-all duration-200', period === 'AM'
134
134
  ? 'bg-[rgb(var(--color-primary))] text-white shadow-md'
135
135
  : 'bg-[rgb(var(--bg-subtle))] text-[rgb(var(--fg-default))] hover:bg-[rgb(var(--bg-hover))]'), children: "AM" }), _jsx("button", { onClick: () => setPeriod('PM'), className: cn('px-3 py-1.5 text-sm font-semibold rounded-lg transition-all duration-200', period === 'PM'
@@ -38,7 +38,7 @@ export declare function ClearButton({ onClear, disabled, className }: ClearButto
38
38
  export declare const dropdownSharedStyles: {
39
39
  readonly trigger: {
40
40
  readonly base: "flex items-center justify-between rounded-md border bg-bg-surface cursor-pointer transition-all duration-200";
41
- readonly focus: "focus-within:outline-none focus-within:border-[rgb(var(--color-primary))]";
41
+ readonly focus: "focus-within:outline-none focus-within:border-[rgb(var(--color-focus))]";
42
42
  readonly error: "border-[rgb(var(--color-error))] focus-within:border-[rgb(var(--color-error))]";
43
43
  readonly normal: "border-[rgb(var(--bd-default))] hover:border-[rgb(var(--bd-hover))]";
44
44
  readonly disabled: "cursor-not-allowed opacity-50";
@@ -110,7 +110,7 @@ export const dropdownSharedStyles = {
110
110
  // Trigger (button) styles
111
111
  trigger: {
112
112
  base: "flex items-center justify-between rounded-md border bg-bg-surface cursor-pointer transition-all duration-200",
113
- focus: "focus-within:outline-none focus-within:border-[rgb(var(--color-primary))]",
113
+ focus: "focus-within:outline-none focus-within:border-[rgb(var(--color-focus))]",
114
114
  error: "border-[rgb(var(--color-error))] focus-within:border-[rgb(var(--color-error))]",
115
115
  normal: "border-[rgb(var(--bd-default))] hover:border-[rgb(var(--bd-hover))]",
116
116
  disabled: "cursor-not-allowed opacity-50",
@@ -872,7 +872,7 @@ acceptedFileTypes = [], label = "File Attachment", className, disabled = false,
872
872
  setSelectedEmail(null);
873
873
  setEmailSearchQuery('');
874
874
  }
875
- }, children: _jsxs(ModalContent, { size: "lg", hideCloseButton: true, disableOutsideClick: true, className: "p-0 flex flex-col overflow-hidden max-w-2xl w-[90vw] h-[75vh] max-h-[650px]", children: [_jsx(ModalHeader, { className: "px-5 py-3 border-b border-[rgb(var(--bd-default))] flex-shrink-0 bg-[rgb(var(--bg-surface))]", children: _jsxs("div", { className: "flex items-center justify-between w-full gap-3", children: [_jsxs("div", { className: "flex items-center gap-3 flex-shrink-0", children: [_jsx("div", { className: "w-9 h-9 rounded-lg bg-[rgba(var(--color-primary),0.1)] flex items-center justify-center", children: _jsx(Mail, { className: "h-4.5 w-4.5 text-[rgb(var(--color-primary))]" }) }), _jsxs("div", { children: [_jsx(ModalTitle, { className: "text-sm", children: "Import from Email" }), emailState.emails.length > 0 && (_jsxs("p", { className: "text-xs text-[rgb(var(--fg-muted))] mt-0.5", children: [emailState.emails.length, " emails"] }))] })] }), _jsxs("div", { className: "flex-1 min-w-0 relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }), _jsx("input", { type: "text", placeholder: "Search by subject, sender, or content...", value: emailSearchQuery, onChange: (e) => setEmailSearchQuery(e.target.value), className: "w-full pl-9 pr-8 py-1.5 rounded-md border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-default))] text-xs text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-primary))] focus:border-transparent" }), emailSearchQuery && (_jsx("button", { onClick: () => setEmailSearchQuery(''), className: "absolute right-2.5 top-1/2 -translate-y-1/2 p-0.5 rounded hover:bg-[rgb(var(--bg-hover))]", children: _jsx(X, { className: "h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }) }))] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("button", { onClick: () => emailActions?.fetchEmails?.(), disabled: emailState.loading, className: "p-1.5 rounded-md hover:bg-[rgb(var(--bg-hover))] text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] transition-colors disabled:opacity-50", "aria-label": "Refresh emails", children: _jsx(RefreshCw, { className: cn("h-4 w-4", emailState.loading && "animate-spin") }) }), _jsx("button", { onClick: () => {
875
+ }, children: _jsxs(ModalContent, { size: "lg", hideCloseButton: true, disableOutsideClick: true, className: "p-0 flex flex-col overflow-hidden max-w-2xl w-[90vw] h-[75vh] max-h-[650px]", children: [_jsx(ModalHeader, { className: "px-5 py-3 border-b border-[rgb(var(--bd-default))] flex-shrink-0 bg-[rgb(var(--bg-surface))]", children: _jsxs("div", { className: "flex items-center justify-between w-full gap-3", children: [_jsxs("div", { className: "flex items-center gap-3 flex-shrink-0", children: [_jsx("div", { className: "w-9 h-9 rounded-lg bg-[rgba(var(--color-primary),0.1)] flex items-center justify-center", children: _jsx(Mail, { className: "h-4.5 w-4.5 text-[rgb(var(--color-primary))]" }) }), _jsxs("div", { children: [_jsx(ModalTitle, { className: "text-sm", children: "Import from Email" }), emailState.emails.length > 0 && (_jsxs("p", { className: "text-xs text-[rgb(var(--fg-muted))] mt-0.5", children: [emailState.emails.length, " emails"] }))] })] }), _jsxs("div", { className: "flex-1 min-w-0 relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }), _jsx("input", { type: "text", placeholder: "Search by subject, sender, or content...", value: emailSearchQuery, onChange: (e) => setEmailSearchQuery(e.target.value), className: "w-full pl-9 pr-8 py-1.5 rounded-md border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-default))] text-xs text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))] focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-focus))] focus:border-transparent" }), emailSearchQuery && (_jsx("button", { onClick: () => setEmailSearchQuery(''), className: "absolute right-2.5 top-1/2 -translate-y-1/2 p-0.5 rounded hover:bg-[rgb(var(--bg-hover))]", children: _jsx(X, { className: "h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }) }))] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("button", { onClick: () => emailActions?.fetchEmails?.(), disabled: emailState.loading, className: "p-1.5 rounded-md hover:bg-[rgb(var(--bg-hover))] text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] transition-colors disabled:opacity-50", "aria-label": "Refresh emails", children: _jsx(RefreshCw, { className: cn("h-4 w-4", emailState.loading && "animate-spin") }) }), _jsx("button", { onClick: () => {
876
876
  setShowEmailImportModal(false);
877
877
  setSelectedEmail(null);
878
878
  setEmailSearchQuery('');
@@ -138,11 +138,11 @@ export function RemarkTrail({ remarks, onAdd, canAdd = true, loading = false, on
138
138
  e.preventDefault();
139
139
  commitEdit();
140
140
  } if (e.key === 'Escape')
141
- setEditingSeq(null); }, autoFocus: true, className: "flex-1 text-xs rounded border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))] px-2 py-1 text-[rgb(var(--fg-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-primary))]" }), _jsx("button", { type: "button", onClick: commitEdit, title: t('Save'), className: "p-1 rounded bg-[rgb(var(--color-primary))] text-white hover:opacity-90", children: _jsx(Check, { className: "h-3 w-3" }) }), _jsx("button", { type: "button", onClick: () => setEditingSeq(null), title: t('Cancel'), className: "p-1 rounded text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))]", children: _jsx(X, { className: "h-3 w-3" }) })] })) : (r.text && _jsx("p", { className: "mt-0.5 text-[rgb(var(--fg-default))] whitespace-pre-wrap break-words leading-snug", children: r.text })), !isEditing && r.files && r.files.length > 0 && (_jsx("div", { className: "mt-1 flex flex-wrap gap-1.5", children: r.files.map((f, i) => (_jsxs("a", { href: f.url, target: "_blank", rel: "noopener noreferrer", title: f.name, className: "inline-flex items-center gap-1 max-w-[12rem] rounded-md border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] px-1.5 py-0.5 text-[10px] text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--color-primary))] hover:border-[rgb(var(--color-primary))]/40 transition-colors", children: [_jsx(FileText, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "truncate", children: f.name })] }, i))) }))] }, r.seq));
141
+ setEditingSeq(null); }, autoFocus: true, className: "flex-1 text-xs rounded border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))] px-2 py-1 text-[rgb(var(--fg-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-focus))]" }), _jsx("button", { type: "button", onClick: commitEdit, title: t('Save'), className: "p-1 rounded bg-[rgb(var(--color-primary))] text-white hover:opacity-90", children: _jsx(Check, { className: "h-3 w-3" }) }), _jsx("button", { type: "button", onClick: () => setEditingSeq(null), title: t('Cancel'), className: "p-1 rounded text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))]", children: _jsx(X, { className: "h-3 w-3" }) })] })) : (r.text && _jsx("p", { className: "mt-0.5 text-[rgb(var(--fg-default))] whitespace-pre-wrap break-words leading-snug", children: r.text })), !isEditing && r.files && r.files.length > 0 && (_jsx("div", { className: "mt-1 flex flex-wrap gap-1.5", children: r.files.map((f, i) => (_jsxs("a", { href: f.url, target: "_blank", rel: "noopener noreferrer", title: f.name, className: "inline-flex items-center gap-1 max-w-[12rem] rounded-md border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] px-1.5 py-0.5 text-[10px] text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--color-primary))] hover:border-[rgb(var(--color-primary))]/40 transition-colors", children: [_jsx(FileText, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "truncate", children: f.name })] }, i))) }))] }, r.seq));
142
142
  }) })) }), onAdd && (_jsxs("div", { className: "border-t border-[rgb(var(--bd-subtle))] px-2 py-1.5 space-y-1.5", children: [pendingFiles.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5", children: pendingFiles.map((f, i) => (_jsxs("span", { className: "inline-flex items-center gap-1 max-w-[12rem] rounded-md border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] pl-1.5 pr-1 py-0.5 text-[10px] text-[rgb(var(--fg-muted))]", children: [_jsx(FileText, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "truncate", children: f.name }), _jsx("button", { type: "button", onClick: () => setPendingFiles(prev => prev.filter((_, idx) => idx !== i)), title: t('Remove'), className: "p-0.5 rounded-full hover:text-[rgb(var(--color-error))]", children: _jsx(X, { className: "h-2.5 w-2.5" }) })] }, i))) })), _jsxs("div", { className: "flex items-center gap-1.5", children: [onUploadFiles && (_jsxs(_Fragment, { children: [_jsx("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", onChange: handlePickFiles }), _jsx("button", { type: "button", onClick: () => fileInputRef.current?.click(), disabled: !canAdd || saving || uploading, title: t('Attach files'), className: "p-1.5 rounded border border-[rgb(var(--bd-default))] text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--color-primary))] hover:border-[rgb(var(--color-primary))]/50 disabled:opacity-50 transition-colors shrink-0", children: uploading ? _jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : _jsx(Paperclip, { className: "h-3.5 w-3.5" }) })] })), _jsx("input", { value: text, onChange: (e) => setText(e.target.value), onKeyDown: (e) => { if (e.key === 'Enter' && !e.shiftKey) {
143
143
  e.preventDefault();
144
144
  handleAdd();
145
- } }, disabled: !canAdd || saving, placeholder: t('Add a note...'), className: "flex-1 text-xs rounded border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))] px-2 py-1 text-[rgb(var(--fg-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-primary))] disabled:opacity-60" }), _jsx("button", { onClick: handleAdd, disabled: !canAdd || saving || uploading || (!text.trim() && pendingFiles.length === 0), title: t('Add'), className: "p-1.5 rounded bg-[rgb(var(--color-primary))] text-white disabled:opacity-50 hover:opacity-90 transition-opacity shrink-0", children: _jsx(Send, { className: "h-3.5 w-3.5" }) })] })] }))] }));
145
+ } }, disabled: !canAdd || saving, placeholder: t('Add a note...'), className: "flex-1 text-xs rounded border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))] px-2 py-1 text-[rgb(var(--fg-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-focus))] disabled:opacity-60" }), _jsx("button", { onClick: handleAdd, disabled: !canAdd || saving || uploading || (!text.trim() && pendingFiles.length === 0), title: t('Add'), className: "p-1.5 rounded bg-[rgb(var(--color-primary))] text-white disabled:opacity-50 hover:opacity-90 transition-opacity shrink-0", children: _jsx(Send, { className: "h-3.5 w-3.5" }) })] })] }))] }));
146
146
  }
147
147
  export function RemarkInput({ value, onChange, module, documentId, documentName, documentNo, actionUrl, stage = 'General', session, label, placeholder, rows = 1, showTrail = false, onUploadFiles, disabled = false, className, inputClassName, error = false, required = false, }) {
148
148
  const { t } = useLanguage();
@@ -254,5 +254,5 @@ export function RemarkInput({ value, onChange, module, documentId, documentName,
254
254
  userResized.current = true;
255
255
  }, placeholder: placeholder ?? t('Add remarks or notes...'), rows: rows, disabled: disabled, className: cn('w-full text-sm rounded-md border bg-[rgb(var(--bg-surface))] px-3 py-2 pr-9 text-[rgb(var(--fg-default))]', error
256
256
  ? 'border-[rgb(var(--color-error))] placeholder:text-[rgb(var(--fg-subtle))]'
257
- : 'border-[rgb(var(--bd-default))] placeholder:text-[rgb(var(--fg-subtle))]', 'transition-[height,box-shadow,border-color] duration-150 ease-out', 'focus:outline-none focus:border-[rgb(var(--color-primary))] focus:ring-2 focus:ring-[rgb(var(--color-primary))]/30', 'resize-y overflow-auto min-h-[2.25rem] disabled:opacity-60', inputClassName) }), hasDoc && showTrail && !label && (_jsxs("button", { type: "button", onClick: openTrail, title: t('View remark trail'), className: "absolute top-1.5 right-1.5 inline-flex h-5 w-5 items-center justify-center rounded-full border border-[rgb(var(--bd-default))] text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--color-primary))] hover:border-[rgb(var(--color-primary))]/50 hover:bg-[rgb(var(--color-primary-subtle))] transition-colors", children: [_jsx(Info, { className: "h-3 w-3" }), count > 0 && _jsx("span", { className: "absolute -top-1 -right-1 h-2 w-2 rounded-full bg-[rgb(var(--color-primary))]" })] }))] }), _jsx(Modal, { open: trailOpen, onOpenChange: setTrailOpen, children: _jsxs(ModalContent, { size: "md", hideCloseButton: true, className: "p-0 overflow-hidden max-h-[80vh]", children: [_jsx(ModalTitle, { className: "sr-only", children: t('Remarks') }), _jsx(RemarkTrail, { remarks: displayRemarks, loading: loading, onAdd: hasDoc ? handleAdd : undefined, onClose: () => setTrailOpen(false), documentNo: documentNo, currentUserId: currentUserId, onEdit: hasDoc ? handleEdit : undefined, onDelete: hasDoc ? handleDelete : undefined, onUploadFiles: onUploadFiles, className: "max-h-[80vh] border-0 rounded-none" })] }) })] }));
257
+ : 'border-[rgb(var(--bd-default))] placeholder:text-[rgb(var(--fg-subtle))]', 'transition-[height,box-shadow,border-color] duration-150 ease-out', 'focus:outline-none focus:border-[rgb(var(--color-focus))] focus:ring-2 focus:ring-[rgb(var(--color-focus))]/30', 'resize-y overflow-auto min-h-[2.25rem] disabled:opacity-60', inputClassName) }), hasDoc && showTrail && !label && (_jsxs("button", { type: "button", onClick: openTrail, title: t('View remark trail'), className: "absolute top-1.5 right-1.5 inline-flex h-5 w-5 items-center justify-center rounded-full border border-[rgb(var(--bd-default))] text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--color-primary))] hover:border-[rgb(var(--color-primary))]/50 hover:bg-[rgb(var(--color-primary-subtle))] transition-colors", children: [_jsx(Info, { className: "h-3 w-3" }), count > 0 && _jsx("span", { className: "absolute -top-1 -right-1 h-2 w-2 rounded-full bg-[rgb(var(--color-primary))]" })] }))] }), _jsx(Modal, { open: trailOpen, onOpenChange: setTrailOpen, children: _jsxs(ModalContent, { size: "md", hideCloseButton: true, className: "p-0 overflow-hidden max-h-[80vh]", children: [_jsx(ModalTitle, { className: "sr-only", children: t('Remarks') }), _jsx(RemarkTrail, { remarks: displayRemarks, loading: loading, onAdd: hasDoc ? handleAdd : undefined, onClose: () => setTrailOpen(false), documentNo: documentNo, currentUserId: currentUserId, onEdit: hasDoc ? handleEdit : undefined, onDelete: hasDoc ? handleDelete : undefined, onUploadFiles: onUploadFiles, className: "max-h-[80vh] border-0 rounded-none" })] }) })] }));
258
258
  }
@@ -143,7 +143,7 @@ export function MobileMenuSheet({ open, onClose }) {
143
143
  const getInitials = (name) => {
144
144
  return name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2);
145
145
  };
146
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: cn('fixed inset-0 z-[60] bg-black/50 transition-opacity duration-300 lg:hidden', open ? 'opacity-100' : 'opacity-0 pointer-events-none'), onClick: onClose }), _jsxs("div", { className: cn('fixed inset-x-0 bottom-0 z-[61] lg:hidden', 'bg-[rgb(var(--bg-surface))] rounded-t-2xl shadow-2xl', 'transform transition-transform duration-300 ease-out', 'max-h-[85vh] flex flex-col', open ? 'translate-y-0' : 'translate-y-full'), children: [_jsx("div", { className: "flex justify-center pt-2.5 pb-1", children: _jsx("div", { className: "w-9 h-1 rounded-full bg-[rgb(var(--bd-default))]" }) }), _jsxs("div", { className: "flex items-center gap-3 px-4 py-2.5 border-b border-[rgb(var(--bd-default))]", children: [_jsx("div", { className: "w-8 h-8 rounded-full bg-[rgb(var(--bg-subtle))] border border-[rgb(var(--bd-default))] flex items-center justify-center flex-shrink-0", children: _jsx("span", { className: "text-xs font-semibold text-[rgb(var(--fg-muted))]", children: getInitials(userName) }) }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: "text-sm font-semibold text-[rgb(var(--fg-default))] truncate leading-tight", children: userName }), userRole && (_jsx("p", { className: "text-[0.65rem] text-[rgb(var(--fg-muted))] truncate", children: userRole }))] }), _jsx("button", { onClick: onClose, className: "p-2 -mr-1 rounded-lg text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))] transition-colors", children: _jsx(X, { className: "h-4.5 w-4.5" }) })] }), _jsx("div", { className: "px-4 py-2.5", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }), _jsx("input", { ref: searchRef, type: "text", placeholder: t('Search modules...'), value: searchQuery, onChange: e => setSearchQuery(e.target.value), className: "w-full pl-9 pr-8 py-2 text-sm rounded-lg border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))] focus:outline-none focus:border-[rgb(var(--color-primary))] transition-colors" }), searchQuery && (_jsx("button", { onClick: () => { setSearchQuery(''); searchRef.current?.focus(); }, className: "absolute right-2.5 top-1/2 -translate-y-1/2 p-0.5 rounded text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))]", children: _jsx(X, { className: "h-3.5 w-3.5" }) }))] }) }), _jsx("div", { className: "flex-1 overflow-y-auto px-2 pb-2", children: filteredGroups.length === 0 ? (_jsxs("div", { className: "py-12 text-center", children: [_jsx(Search, { className: "h-8 w-8 mx-auto mb-2 text-[rgb(var(--fg-muted))] opacity-30" }), _jsx("p", { className: "text-sm text-[rgb(var(--fg-muted))]", children: t('No modules found') })] })) : (filteredGroups.map(group => {
146
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: cn('fixed inset-0 z-[60] bg-black/50 transition-opacity duration-300 lg:hidden', open ? 'opacity-100' : 'opacity-0 pointer-events-none'), onClick: onClose }), _jsxs("div", { className: cn('fixed inset-x-0 bottom-0 z-[61] lg:hidden', 'bg-[rgb(var(--bg-surface))] rounded-t-2xl shadow-2xl', 'transform transition-transform duration-300 ease-out', 'max-h-[85vh] flex flex-col', open ? 'translate-y-0' : 'translate-y-full'), children: [_jsx("div", { className: "flex justify-center pt-2.5 pb-1", children: _jsx("div", { className: "w-9 h-1 rounded-full bg-[rgb(var(--bd-default))]" }) }), _jsxs("div", { className: "flex items-center gap-3 px-4 py-2.5 border-b border-[rgb(var(--bd-default))]", children: [_jsx("div", { className: "w-8 h-8 rounded-full bg-[rgb(var(--bg-subtle))] border border-[rgb(var(--bd-default))] flex items-center justify-center flex-shrink-0", children: _jsx("span", { className: "text-xs font-semibold text-[rgb(var(--fg-muted))]", children: getInitials(userName) }) }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: "text-sm font-semibold text-[rgb(var(--fg-default))] truncate leading-tight", children: userName }), userRole && (_jsx("p", { className: "text-[0.65rem] text-[rgb(var(--fg-muted))] truncate", children: userRole }))] }), _jsx("button", { onClick: onClose, className: "p-2 -mr-1 rounded-lg text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))] transition-colors", children: _jsx(X, { className: "h-4.5 w-4.5" }) })] }), _jsx("div", { className: "px-4 py-2.5", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }), _jsx("input", { ref: searchRef, type: "text", placeholder: t('Search modules...'), value: searchQuery, onChange: e => setSearchQuery(e.target.value), className: "w-full pl-9 pr-8 py-2 text-sm rounded-lg border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))] focus:outline-none focus:border-[rgb(var(--color-focus))] transition-colors" }), searchQuery && (_jsx("button", { onClick: () => { setSearchQuery(''); searchRef.current?.focus(); }, className: "absolute right-2.5 top-1/2 -translate-y-1/2 p-0.5 rounded text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))]", children: _jsx(X, { className: "h-3.5 w-3.5" }) }))] }) }), _jsx("div", { className: "flex-1 overflow-y-auto px-2 pb-2", children: filteredGroups.length === 0 ? (_jsxs("div", { className: "py-12 text-center", children: [_jsx(Search, { className: "h-8 w-8 mx-auto mb-2 text-[rgb(var(--fg-muted))] opacity-30" }), _jsx("p", { className: "text-sm text-[rgb(var(--fg-muted))]", children: t('No modules found') })] })) : (filteredGroups.map(group => {
147
147
  const GroupIcon = getGroupIcon(group.groupName);
148
148
  const isExpanded = expandedGroups.includes(group.groupName);
149
149
  return (_jsxs("div", { className: "mb-0.5", children: [_jsxs("button", { onClick: () => toggleGroup(group.groupName), className: "w-full flex items-center gap-2.5 px-3 py-2.5 rounded-lg text-left hover:bg-[rgb(var(--bg-hover))] transition-colors min-h-[2.75rem]", children: [_jsx(GroupIcon, { className: "h-4 w-4 text-[rgb(var(--fg-muted))] flex-shrink-0" }), _jsx("span", { className: "text-xs font-semibold text-[rgb(var(--fg-muted))] uppercase tracking-wide flex-1", children: t(group.groupName) }), _jsx(ChevronRight, { className: cn('h-3.5 w-3.5 text-[rgb(var(--fg-muted))]/50 transition-transform duration-200', isExpanded && 'rotate-90') })] }), isExpanded && (_jsx("div", { className: "ml-5 pl-3 border-l-2 border-[rgb(var(--bd-default))]/50 mb-1", children: group.modules.map(mod => {
@@ -185,7 +185,7 @@ export function TopHeader({ className, sidebarCollapsed = true, onToggleSidebar,
185
185
  })(), showNotificationDropdown && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40", onClick: () => {
186
186
  setShowNotificationDropdown(false);
187
187
  setNotificationSearchQuery('');
188
- } }), _jsxs("div", { className: cn("z-50 bg-[rgb(var(--bg-surface))] rounded-2xl shadow-2xl border border-[rgb(var(--bd-default))] overflow-hidden", "fixed top-14 left-2 right-2 sm:absolute sm:top-auto sm:left-auto sm:right-0 sm:mt-2 sm:w-[28rem]"), children: [_jsxs("div", { className: "px-5 pt-5 pb-0 bg-[rgb(var(--bg-surface))]", children: [_jsxs("div", { className: "flex items-center gap-3 mb-4", children: [_jsx("h3", { className: "text-lg font-bold text-[rgb(var(--fg-default))] flex-shrink-0", children: "Notifications" }), _jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[rgb(var(--fg-muted))]" }), _jsx("input", { type: "text", placeholder: "Search...", value: notificationSearchQuery, onChange: (e) => setNotificationSearchQuery(e.target.value), className: "w-full pl-9 pr-3 py-1.5 text-sm rounded-lg border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))] focus:outline-none focus:border-[rgb(var(--color-primary))] focus:bg-[rgb(var(--bg-surface))] transition-colors" })] }), _jsx("button", { onClick: (e) => {
188
+ } }), _jsxs("div", { className: cn("z-50 bg-[rgb(var(--bg-surface))] rounded-2xl shadow-2xl border border-[rgb(var(--bd-default))] overflow-hidden", "fixed top-14 left-2 right-2 sm:absolute sm:top-auto sm:left-auto sm:right-0 sm:mt-2 sm:w-[28rem]"), children: [_jsxs("div", { className: "px-5 pt-5 pb-0 bg-[rgb(var(--bg-surface))]", children: [_jsxs("div", { className: "flex items-center gap-3 mb-4", children: [_jsx("h3", { className: "text-lg font-bold text-[rgb(var(--fg-default))] flex-shrink-0", children: "Notifications" }), _jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[rgb(var(--fg-muted))]" }), _jsx("input", { type: "text", placeholder: "Search...", value: notificationSearchQuery, onChange: (e) => setNotificationSearchQuery(e.target.value), className: "w-full pl-9 pr-3 py-1.5 text-sm rounded-lg border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))] focus:outline-none focus:border-[rgb(var(--color-focus))] focus:bg-[rgb(var(--bg-surface))] transition-colors" })] }), _jsx("button", { onClick: (e) => {
189
189
  e.stopPropagation();
190
190
  setShowNotificationDropdown(false);
191
191
  router.push('/settings?tab=notifications');
@@ -97,7 +97,7 @@ export function ConversationList({ currentUserId, onSelectRoom, onNewConversatio
97
97
  const handleSelectRoom = useCallback((room) => {
98
98
  onSelectRoom(room);
99
99
  }, [onSelectRoom]);
100
- return (_jsxs("div", { className: cn('flex flex-col h-full', className), children: [_jsxs("div", { className: "flex-shrink-0 px-3 pt-3 pb-2 space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h2", { className: "text-lg font-semibold text-[rgb(var(--fg-default))]", children: t('Messages') }), _jsx("button", { onClick: onNewConversation, className: "w-8 h-8 rounded-lg flex items-center justify-center hover:bg-[rgb(var(--bg-hover))] text-[rgb(var(--fg-muted))] transition-colors", title: t('New conversation'), children: _jsx(Plus, { className: "w-5 h-5" }) })] }), _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-[rgb(var(--fg-muted))]" }), _jsx("input", { type: "text", value: searchText, onChange: e => setSearchText(e.target.value), placeholder: t('Search conversations...'), className: "w-full h-8 pl-8 pr-8 rounded-lg bg-[rgb(var(--bg-subtle))] text-sm text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))] border border-[rgb(var(--bd-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-primary))]" }), searchText && (_jsx("button", { onClick: () => setSearchText(''), className: "absolute right-2 top-1/2 -translate-y-1/2 text-[rgb(var(--fg-muted))]", children: _jsx(X, { className: "w-3.5 h-3.5" }) }))] }), _jsx("div", { className: "flex gap-1", children: tabs.map(tab => (_jsx("button", { onClick: () => setFilter(tab.key), className: cn('flex-1 py-1 px-2 rounded-md text-xs font-medium transition-colors', filter === tab.key
100
+ return (_jsxs("div", { className: cn('flex flex-col h-full', className), children: [_jsxs("div", { className: "flex-shrink-0 px-3 pt-3 pb-2 space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("h2", { className: "text-lg font-semibold text-[rgb(var(--fg-default))]", children: t('Messages') }), _jsx("button", { onClick: onNewConversation, className: "w-8 h-8 rounded-lg flex items-center justify-center hover:bg-[rgb(var(--bg-hover))] text-[rgb(var(--fg-muted))] transition-colors", title: t('New conversation'), children: _jsx(Plus, { className: "w-5 h-5" }) })] }), _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-[rgb(var(--fg-muted))]" }), _jsx("input", { type: "text", value: searchText, onChange: e => setSearchText(e.target.value), placeholder: t('Search conversations...'), className: "w-full h-8 pl-8 pr-8 rounded-lg bg-[rgb(var(--bg-subtle))] text-sm text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))] border border-[rgb(var(--bd-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-focus))]" }), searchText && (_jsx("button", { onClick: () => setSearchText(''), className: "absolute right-2 top-1/2 -translate-y-1/2 text-[rgb(var(--fg-muted))]", children: _jsx(X, { className: "w-3.5 h-3.5" }) }))] }), _jsx("div", { className: "flex gap-1", children: tabs.map(tab => (_jsx("button", { onClick: () => setFilter(tab.key), className: cn('flex-1 py-1 px-2 rounded-md text-xs font-medium transition-colors', filter === tab.key
101
101
  ? 'bg-[rgb(var(--color-primary))] text-white'
102
102
  : 'text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))]'), children: tab.label }, tab.key))) })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-1.5 py-1", children: state.loadingConversations ? (_jsx("div", { className: "space-y-2 px-2", children: [1, 2, 3, 4, 5].map(i => (_jsxs("div", { className: "flex items-center gap-3 py-2.5 animate-pulse", children: [_jsx("div", { className: "w-10 h-10 rounded-full bg-[rgb(var(--bg-subtle))]" }), _jsxs("div", { className: "flex-1 space-y-1.5", children: [_jsx("div", { className: "h-3.5 w-24 rounded bg-[rgb(var(--bg-subtle))]" }), _jsx("div", { className: "h-3 w-40 rounded bg-[rgb(var(--bg-subtle))]" })] })] }, i))) })) : filteredConversations.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center justify-center py-12 text-[rgb(var(--fg-muted))]", children: [_jsx(MessageSquare, { className: "w-10 h-10 mb-2 opacity-40" }), _jsx("p", { className: "text-sm", children: searchText ? t('No conversations found') : t('No conversations yet') }), !searchText && (_jsx("button", { onClick: onNewConversation, className: "mt-2 text-xs text-[rgb(var(--color-primary))] hover:underline", children: t('Start a conversation') }))] })) : (filteredConversations.map(room => (_jsx(ConversationListItem, { room: room, isActive: activeRoomId === room.RoomID, unreadCount: state.unreadCounts[room.RoomID] || 0, isOnline: room.Type === 'DM' ? actions.isUserOnline(room.RoomID) : undefined, currentUserId: currentUserId, onClick: () => handleSelectRoom(room) }, room.RoomID)))) })] }));
103
103
  }
@@ -102,7 +102,7 @@ export function CreateConversationModal({ open, onClose, onCreated, currentUserI
102
102
  : selectedUsers.length > 0 && name.trim();
103
103
  return (_jsx(Modal, { open: open, onOpenChange: onClose, children: _jsxs(ModalContent, { size: "md", hideCloseButton: true, disableOutsideClick: true, className: "p-0 flex flex-col overflow-hidden max-h-[85vh]", children: [_jsx(ModalHeader, { className: "px-5 py-4 border-b border-[rgb(var(--bd-default))]", children: _jsx(ModalTitle, { children: t('New Conversation') }) }), _jsxs("div", { className: "flex-1 overflow-y-auto p-5 space-y-4", children: [_jsx("div", { className: "grid grid-cols-3 gap-2", children: typeOptions.map(opt => (_jsxs("button", { onClick: () => { setType(opt.key); setSelectedUsers([]); }, className: cn('flex flex-col items-center gap-1 p-3 rounded-lg border transition-colors', type === opt.key
104
104
  ? 'border-[rgb(var(--color-primary))] bg-[rgb(var(--color-primary)/0.05)]'
105
- : 'border-[rgb(var(--bd-default))] hover:bg-[rgb(var(--bg-hover))]'), children: [_jsx(opt.icon, { className: cn('w-5 h-5', type === opt.key ? 'text-[rgb(var(--color-primary))]' : 'text-[rgb(var(--fg-muted))]') }), _jsx("span", { className: "text-xs font-medium", children: opt.label })] }, opt.key))) }), type !== 'DM' && (_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-xs font-medium text-[rgb(var(--fg-muted))]", children: t('Name') }), _jsx("input", { value: name, onChange: e => setName(e.target.value), placeholder: type === 'Group' ? t('Group name') : t('Channel name'), className: "w-full h-9 px-3 rounded-lg bg-[rgb(var(--bg-subtle))] text-sm text-[rgb(var(--fg-default))] border border-[rgb(var(--bd-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-primary))]" }), _jsx("input", { value: description, onChange: e => setDescription(e.target.value), placeholder: t('Description (optional)'), className: "w-full h-9 px-3 rounded-lg bg-[rgb(var(--bg-subtle))] text-sm text-[rgb(var(--fg-default))] border border-[rgb(var(--bd-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-primary))]" }), type === 'Channel' && (_jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: isPublic, onChange: e => setIsPublic(e.target.checked), className: "rounded" }), _jsx("span", { className: "text-sm text-[rgb(var(--fg-default))]", children: t('Public channel') })] }))] })), selectedUsers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5", children: selectedUsers.map(user => (_jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-1 rounded-full bg-[rgb(var(--color-primary)/0.1)] text-xs text-[rgb(var(--color-primary))]", children: [user.UserName, _jsx("button", { onClick: () => toggleUser(user), className: "hover:opacity-70", children: _jsx(X, { className: "w-3 h-3" }) })] }, user.UserID))) })), _jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-xs font-medium text-[rgb(var(--fg-muted))]", children: type === 'DM' ? t('Select person') : t('Add members') }), _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-[rgb(var(--fg-muted))]" }), _jsx("input", { value: searchText, onChange: e => setSearchText(e.target.value), placeholder: t('Search by name or email...'), autoComplete: "off", "data-1p-ignore": true, "data-lpignore": "true", className: "w-full h-9 pl-8 pr-3 rounded-lg bg-[rgb(var(--bg-subtle))] text-sm text-[rgb(var(--fg-default))] border border-[rgb(var(--bd-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-primary))]" })] })] }), _jsx("div", { className: "max-h-48 overflow-y-auto rounded-lg border border-[rgb(var(--bd-default))]", children: filteredContacts.length === 0 ? (_jsx("div", { className: "p-4 text-center text-sm text-[rgb(var(--fg-muted))]", children: t('No contacts found') })) : (filteredContacts.map(contact => {
105
+ : 'border-[rgb(var(--bd-default))] hover:bg-[rgb(var(--bg-hover))]'), children: [_jsx(opt.icon, { className: cn('w-5 h-5', type === opt.key ? 'text-[rgb(var(--color-primary))]' : 'text-[rgb(var(--fg-muted))]') }), _jsx("span", { className: "text-xs font-medium", children: opt.label })] }, opt.key))) }), type !== 'DM' && (_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-xs font-medium text-[rgb(var(--fg-muted))]", children: t('Name') }), _jsx("input", { value: name, onChange: e => setName(e.target.value), placeholder: type === 'Group' ? t('Group name') : t('Channel name'), className: "w-full h-9 px-3 rounded-lg bg-[rgb(var(--bg-subtle))] text-sm text-[rgb(var(--fg-default))] border border-[rgb(var(--bd-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-focus))]" }), _jsx("input", { value: description, onChange: e => setDescription(e.target.value), placeholder: t('Description (optional)'), className: "w-full h-9 px-3 rounded-lg bg-[rgb(var(--bg-subtle))] text-sm text-[rgb(var(--fg-default))] border border-[rgb(var(--bd-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-focus))]" }), type === 'Channel' && (_jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: isPublic, onChange: e => setIsPublic(e.target.checked), className: "rounded" }), _jsx("span", { className: "text-sm text-[rgb(var(--fg-default))]", children: t('Public channel') })] }))] })), selectedUsers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5", children: selectedUsers.map(user => (_jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-1 rounded-full bg-[rgb(var(--color-primary)/0.1)] text-xs text-[rgb(var(--color-primary))]", children: [user.UserName, _jsx("button", { onClick: () => toggleUser(user), className: "hover:opacity-70", children: _jsx(X, { className: "w-3 h-3" }) })] }, user.UserID))) })), _jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-xs font-medium text-[rgb(var(--fg-muted))]", children: type === 'DM' ? t('Select person') : t('Add members') }), _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-[rgb(var(--fg-muted))]" }), _jsx("input", { value: searchText, onChange: e => setSearchText(e.target.value), placeholder: t('Search by name or email...'), autoComplete: "off", "data-1p-ignore": true, "data-lpignore": "true", className: "w-full h-9 pl-8 pr-3 rounded-lg bg-[rgb(var(--bg-subtle))] text-sm text-[rgb(var(--fg-default))] border border-[rgb(var(--bd-default))] focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-focus))]" })] })] }), _jsx("div", { className: "max-h-48 overflow-y-auto rounded-lg border border-[rgb(var(--bd-default))]", children: filteredContacts.length === 0 ? (_jsx("div", { className: "p-4 text-center text-sm text-[rgb(var(--fg-muted))]", children: t('No contacts found') })) : (filteredContacts.map(contact => {
106
106
  const isSelected = selectedUsers.some(u => u.UserID === contact.UserID);
107
107
  return (_jsxs("button", { onClick: () => toggleUser(contact), className: cn('w-full flex items-center gap-3 px-3 py-2 hover:bg-[rgb(var(--bg-hover))] transition-colors', isSelected && 'bg-[rgb(var(--color-primary)/0.05)]'), children: [_jsx("div", { className: cn('w-8 h-8 rounded-full flex items-center justify-center text-white text-xs font-medium flex-shrink-0', getAvatarColor(contact.UserID)), children: getInitials(contact.UserName) }), _jsxs("div", { className: "flex-1 min-w-0 text-left", children: [_jsx("p", { className: "text-sm font-medium text-[rgb(var(--fg-default))] truncate", children: contact.UserName }), contact.Designation && (_jsx("p", { className: "text-xs text-[rgb(var(--fg-muted))] truncate", children: contact.Designation }))] }), isSelected && (_jsx(Check, { className: "w-4 h-4 text-[rgb(var(--color-primary))] flex-shrink-0" }))] }, contact.UserID));
108
108
  })) })] }), _jsxs("div", { className: "flex justify-end gap-2 px-5 py-3 border-t border-[rgb(var(--bd-default))]", children: [_jsx("button", { onClick: onClose, className: "px-4 h-9 rounded-lg text-sm font-medium text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))] transition-colors", children: t('Cancel') }), _jsx("button", { onClick: handleCreate, disabled: !canCreate || creating, className: "px-4 h-9 rounded-lg text-sm font-medium bg-[rgb(var(--color-primary))] text-white hover:opacity-90 disabled:opacity-50 transition-colors", children: creating ? t('Creating...') : type === 'DM' ? t('Start Chat') : t('Create') })] })] }) }));
@@ -143,7 +143,7 @@ export function MessageInput({ onSend, onUploadFile, onTyping, replyTo, onCancel
143
143
  return prev.filter((_, i) => i !== idx);
144
144
  });
145
145
  }, []);
146
- return (_jsxs("div", { className: "flex-shrink-0 border-t border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))]", children: [replyTo && (_jsxs("div", { className: "flex items-center gap-2 px-4 py-2 bg-[rgb(var(--bg-subtle))] border-b border-[rgb(var(--bd-default))]", children: [_jsx(Reply, { className: "w-4 h-4 text-[rgb(var(--color-primary))] flex-shrink-0" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: "text-xs font-medium text-[rgb(var(--color-primary))]", children: t('Replying to message') }), _jsx("p", { className: "text-xs text-[rgb(var(--fg-muted))] truncate", children: replyTo.Content })] }), _jsx("button", { onClick: onCancelReply, className: "flex-shrink-0 text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))]", children: _jsx(X, { className: "w-4 h-4" }) })] })), pendingFiles.length > 0 && (_jsx("div", { className: "flex gap-2 px-4 py-2 overflow-x-auto", children: pendingFiles.map((f, i) => (_jsxs("div", { className: "relative flex-shrink-0", children: [f.preview ? (_jsx("img", { src: f.preview, alt: f.file.name, className: "w-16 h-16 rounded-lg object-cover border border-[rgb(var(--bd-default))]" })) : (_jsxs("div", { className: "w-16 h-16 rounded-lg border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] flex flex-col items-center justify-center", children: [_jsx(FileIcon, { className: "w-5 h-5 text-[rgb(var(--fg-muted))]" }), _jsx("span", { className: "text-[0.5rem] text-[rgb(var(--fg-muted))] mt-0.5 truncate max-w-[3.5rem]", children: f.file.name.split('.').pop()?.toUpperCase() })] })), _jsx("button", { onClick: () => removeFile(i), className: "absolute -top-1.5 -right-1.5 w-5 h-5 rounded-full bg-red-500 text-white flex items-center justify-center", children: _jsx(X, { className: "w-3 h-3" }) })] }, i))) })), _jsxs("div", { className: "flex items-end gap-2 px-3 py-2", children: [_jsx("button", { onClick: () => fileInputRef.current?.click(), disabled: disabled || uploading, className: "flex-shrink-0 w-9 h-9 rounded-lg flex items-center justify-center text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))] transition-colors disabled:opacity-50", children: _jsx(Paperclip, { className: "w-5 h-5" }) }), _jsx("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", onChange: handleFileSelect, accept: "image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt,.csv,.zip,.rar" }), _jsx("textarea", { ref: textareaRef, value: text, onChange: e => { setText(e.target.value); handleTyping(); }, onKeyDown: handleKeyDown, disabled: disabled || uploading || isListening, placeholder: isListening ? t('Listening...') : (placeholder || t('Type a message...')), rows: 1, className: "flex-1 min-h-[2.25rem] max-h-[7.5rem] px-3 py-2 rounded-xl bg-[rgb(var(--bg-subtle))] text-sm text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))] border border-[rgb(var(--bd-default))] resize-none focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-primary))] disabled:opacity-50" }), speechSupported && (_jsx("button", { onClick: handleVoiceInput, disabled: disabled || uploading, className: cn('flex-shrink-0 w-9 h-9 rounded-lg flex items-center justify-center transition-colors', isListening
146
+ return (_jsxs("div", { className: "flex-shrink-0 border-t border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))]", children: [replyTo && (_jsxs("div", { className: "flex items-center gap-2 px-4 py-2 bg-[rgb(var(--bg-subtle))] border-b border-[rgb(var(--bd-default))]", children: [_jsx(Reply, { className: "w-4 h-4 text-[rgb(var(--color-primary))] flex-shrink-0" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: "text-xs font-medium text-[rgb(var(--color-primary))]", children: t('Replying to message') }), _jsx("p", { className: "text-xs text-[rgb(var(--fg-muted))] truncate", children: replyTo.Content })] }), _jsx("button", { onClick: onCancelReply, className: "flex-shrink-0 text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))]", children: _jsx(X, { className: "w-4 h-4" }) })] })), pendingFiles.length > 0 && (_jsx("div", { className: "flex gap-2 px-4 py-2 overflow-x-auto", children: pendingFiles.map((f, i) => (_jsxs("div", { className: "relative flex-shrink-0", children: [f.preview ? (_jsx("img", { src: f.preview, alt: f.file.name, className: "w-16 h-16 rounded-lg object-cover border border-[rgb(var(--bd-default))]" })) : (_jsxs("div", { className: "w-16 h-16 rounded-lg border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))] flex flex-col items-center justify-center", children: [_jsx(FileIcon, { className: "w-5 h-5 text-[rgb(var(--fg-muted))]" }), _jsx("span", { className: "text-[0.5rem] text-[rgb(var(--fg-muted))] mt-0.5 truncate max-w-[3.5rem]", children: f.file.name.split('.').pop()?.toUpperCase() })] })), _jsx("button", { onClick: () => removeFile(i), className: "absolute -top-1.5 -right-1.5 w-5 h-5 rounded-full bg-red-500 text-white flex items-center justify-center", children: _jsx(X, { className: "w-3 h-3" }) })] }, i))) })), _jsxs("div", { className: "flex items-end gap-2 px-3 py-2", children: [_jsx("button", { onClick: () => fileInputRef.current?.click(), disabled: disabled || uploading, className: "flex-shrink-0 w-9 h-9 rounded-lg flex items-center justify-center text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))] transition-colors disabled:opacity-50", children: _jsx(Paperclip, { className: "w-5 h-5" }) }), _jsx("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", onChange: handleFileSelect, accept: "image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt,.csv,.zip,.rar" }), _jsx("textarea", { ref: textareaRef, value: text, onChange: e => { setText(e.target.value); handleTyping(); }, onKeyDown: handleKeyDown, disabled: disabled || uploading || isListening, placeholder: isListening ? t('Listening...') : (placeholder || t('Type a message...')), rows: 1, className: "flex-1 min-h-[2.25rem] max-h-[7.5rem] px-3 py-2 rounded-xl bg-[rgb(var(--bg-subtle))] text-sm text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))] border border-[rgb(var(--bd-default))] resize-none focus:outline-none focus:ring-1 focus:ring-[rgb(var(--color-focus))] disabled:opacity-50" }), speechSupported && (_jsx("button", { onClick: handleVoiceInput, disabled: disabled || uploading, className: cn('flex-shrink-0 w-9 h-9 rounded-lg flex items-center justify-center transition-colors', isListening
147
147
  ? 'text-red-500 bg-red-500/10 animate-pulse'
148
148
  : 'text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))]', 'disabled:opacity-50'), children: isListening ? _jsx(MicOff, { className: "w-5 h-5" }) : _jsx(Mic, { className: "w-5 h-5" }) })), _jsx("button", { onClick: handleSubmit, disabled: disabled || uploading || isListening || (!text.trim() && pendingFiles.length === 0), className: cn('flex-shrink-0 w-9 h-9 rounded-lg flex items-center justify-center transition-colors', text.trim() || pendingFiles.length > 0
149
149
  ? 'bg-[rgb(var(--color-primary))] text-white hover:opacity-90'
@@ -526,7 +526,7 @@ export function ImageModal({ isOpen: controlledIsOpen, onClose: controlledOnClos
526
526
  ? 'h-[95vh] max-w-[92vw]'
527
527
  : 'w-auto max-w-[95vw] max-h-[95vh]'}`, style: isZoomMode && computedModalWidth ? { width: `${computedModalWidth}px` } : undefined, hideCloseButton: true, children: [cleanMode ? (_jsx(DialogTitle, { className: "sr-only", children: title || 'Preview' })) : (_jsx(DialogHeader, { className: "px-4 md:px-6 py-2.5 border-b border-[rgb(var(--bd-default))] flex-shrink-0 bg-[rgb(var(--bg-surface))]", children: _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(DialogTitle, { className: "flex-shrink-0 mr-auto", children: title }), isZoomMode && (_jsxs("div", { className: "flex items-center gap-1 flex-shrink-0", children: [_jsx("button", { className: zoomBtn, onClick: zoomOut, disabled: zoomScale <= MIN_SCALE, title: t('Zoom Out'), children: _jsx(Minus, { className: "h-3.5 w-3.5" }) }), _jsxs("div", { className: "relative", ref: zoomPresetsRef, children: [_jsxs("button", { className: `${zoomBtnActive} min-w-[3.5rem] gap-1`, onClick: () => setShowZoomPresets(!showZoomPresets), title: t('Zoom Level'), children: [physicalPercent, "%"] }), showZoomPresets && (_jsx("div", { className: "absolute top-full left-1/2 -translate-x-1/2 mt-1 bg-[rgb(var(--bg-surface))] border border-[rgb(var(--bd-default))] rounded-md shadow-lg z-50 py-1 min-w-[5rem]", children: PHYSICAL_PRESETS.map((preset) => (_jsxs("button", { className: `w-full text-left px-3 py-1.5 text-xs hover:bg-[rgb(var(--bg-subtle))] transition-colors ${physicalPercent === preset
528
528
  ? 'text-[rgb(var(--color-primary))] font-medium'
529
- : 'text-[rgb(var(--fg-default))]'}`, onClick: () => { setZoomLevel(preset / 100); setShowZoomPresets(false); }, children: [preset, "%"] }, preset))) }))] }), _jsx("button", { className: zoomBtn, onClick: zoomIn, disabled: zoomScale >= MAX_SCALE, title: t('Zoom In'), children: _jsx(Plus, { className: "h-3.5 w-3.5" }) }), _jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), _jsxs("button", { className: zoomBtn, onClick: fitToPage, title: t('Fit to Page'), children: [_jsx(Maximize, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "ml-1 hidden sm:inline", children: t('Fit Page') })] }), _jsxs("button", { className: zoomBtn, onClick: toggleFullScreen, title: t('Full Screen'), children: [_jsx(Maximize2, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "ml-1 hidden sm:inline", children: t('Full Screen') })] }), mmScale && (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), _jsxs("span", { className: "flex items-center h-7 text-[0.65rem] text-[rgb(var(--fg-muted))] select-none whitespace-nowrap", children: ["1mm = ", mmScale, "px"] })] }))] })), extraHeaderButtons && (_jsxs(_Fragment, { children: [isZoomMode && _jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), _jsx("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: extraHeaderButtons })] })), _jsxs("button", { onClick: handleClose, className: "flex-shrink-0 rounded-sm opacity-70 ring-offset-[rgb(var(--bg-surface))] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-primary))] focus:ring-offset-2", children: [_jsx(X, { className: "h-4 w-4 text-[rgb(var(--color-icon))]" }), _jsx("span", { className: "sr-only", children: "Close" })] })] }) })), !cleanMode && details && details.length > 0 && (_jsx("div", { className: "px-6 py-2 bg-[rgb(var(--bg-subtle))] border-b border-[rgb(var(--bd-default))] flex-shrink-0", children: _jsx("div", { className: "flex flex-wrap items-center justify-center gap-x-5 gap-y-1 text-xs text-[rgb(var(--fg-default))]", children: details.map((detail, index) => (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs("span", { className: "font-medium text-[rgb(var(--fg-muted))]", children: [detail.label, ":"] }), _jsx("span", { className: "font-normal", children: detail.value })] }, index))) }) })), isPdfMode && pdfUrl ? (_jsx("div", { className: "flex-1 bg-[rgb(var(--bg-subtle))] overflow-hidden p-0", style: { minHeight: 0 }, children: _jsx("embed", { src: pdfUrl, type: "application/pdf", className: "w-full h-full", style: { border: 'none' } }) })) : isZoomMode ? (
529
+ : 'text-[rgb(var(--fg-default))]'}`, onClick: () => { setZoomLevel(preset / 100); setShowZoomPresets(false); }, children: [preset, "%"] }, preset))) }))] }), _jsx("button", { className: zoomBtn, onClick: zoomIn, disabled: zoomScale >= MAX_SCALE, title: t('Zoom In'), children: _jsx(Plus, { className: "h-3.5 w-3.5" }) }), _jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), _jsxs("button", { className: zoomBtn, onClick: fitToPage, title: t('Fit to Page'), children: [_jsx(Maximize, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "ml-1 hidden sm:inline", children: t('Fit Page') })] }), _jsxs("button", { className: zoomBtn, onClick: toggleFullScreen, title: t('Full Screen'), children: [_jsx(Maximize2, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "ml-1 hidden sm:inline", children: t('Full Screen') })] }), mmScale && (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), _jsxs("span", { className: "flex items-center h-7 text-[0.65rem] text-[rgb(var(--fg-muted))] select-none whitespace-nowrap", children: ["1mm = ", mmScale, "px"] })] }))] })), extraHeaderButtons && (_jsxs(_Fragment, { children: [isZoomMode && _jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), _jsx("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: extraHeaderButtons })] })), _jsxs("button", { onClick: handleClose, className: "flex-shrink-0 rounded-sm opacity-70 ring-offset-[rgb(var(--bg-surface))] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-focus))] focus:ring-offset-2", children: [_jsx(X, { className: "h-4 w-4 text-[rgb(var(--color-icon))]" }), _jsx("span", { className: "sr-only", children: "Close" })] })] }) })), !cleanMode && details && details.length > 0 && (_jsx("div", { className: "px-6 py-2 bg-[rgb(var(--bg-subtle))] border-b border-[rgb(var(--bd-default))] flex-shrink-0", children: _jsx("div", { className: "flex flex-wrap items-center justify-center gap-x-5 gap-y-1 text-xs text-[rgb(var(--fg-default))]", children: details.map((detail, index) => (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs("span", { className: "font-medium text-[rgb(var(--fg-muted))]", children: [detail.label, ":"] }), _jsx("span", { className: "font-normal", children: detail.value })] }, index))) }) })), isPdfMode && pdfUrl ? (_jsx("div", { className: "flex-1 bg-[rgb(var(--bg-subtle))] overflow-hidden p-0", style: { minHeight: 0 }, children: _jsx("embed", { src: pdfUrl, type: "application/pdf", className: "w-full h-full", style: { border: 'none' } }) })) : isZoomMode ? (
530
530
  // Zoomable SVG Mode - uses native overflow scroll + CSS scale for zoom
531
531
  _jsx("div", { ref: scrollContainerRef, className: "flex-1 bg-[rgb(var(--bg-subtle))] overflow-auto relative", style: { minHeight: 0 }, children: _jsx("div", { style: {
532
532
  width: zoomScale <= 1 ? '100%' : `${zoomScale * 100}%`,
@@ -269,7 +269,7 @@ const ModalContent = React.forwardRef(({ className, children, hideCloseButton, d
269
269
  if (disableOutsideClick || (hasOpenChild && hasOpenChild.current > 0)) {
270
270
  e.preventDefault();
271
271
  }
272
- }, onEscapeKeyDown: handleEscapeKeyDown, ...props, children: [children, !hideCloseButton && (_jsxs(DialogPrimitive.Close, { className: "absolute right-2 top-2 sm:right-4 sm:top-4 rounded-sm opacity-70 ring-offset-[rgb(var(--bg-surface))] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-primary))] focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-[rgb(var(--bg-hover))] data-[state=open]:text-[rgb(var(--fg-muted))]", children: [_jsx(X, { className: "h-4 w-4 sm:h-5 sm:w-5 text-[rgb(var(--color-icon))]" }), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }));
272
+ }, onEscapeKeyDown: handleEscapeKeyDown, ...props, children: [children, !hideCloseButton && (_jsxs(DialogPrimitive.Close, { className: "absolute right-2 top-2 sm:right-4 sm:top-4 rounded-sm opacity-70 ring-offset-[rgb(var(--bg-surface))] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-focus))] focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-[rgb(var(--bg-hover))] data-[state=open]:text-[rgb(var(--fg-muted))]", children: [_jsx(X, { className: "h-4 w-4 sm:h-5 sm:w-5 text-[rgb(var(--color-icon))]" }), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }));
273
273
  });
274
274
  ModalContent.displayName = DialogPrimitive.Content.displayName;
275
275
  /**
@@ -139,7 +139,7 @@ const Button = React.forwardRef(({ className, variant = 'primary', size = 'md',
139
139
  if (iconOnly) {
140
140
  // For icon-only buttons, use ghost variant by default if not specified
141
141
  const iconOnlyVariant = variant === 'primary' ? 'ghost' : variant;
142
- return (_jsx("button", { ref: ref, type: "button", title: tooltip, disabled: isDisabled, className: cn('inline-flex items-center justify-center', 'rounded-full border-0', 'transition-colors duration-150 ease-in-out', 'focus:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--color-primary))] focus-visible:ring-offset-2', 'disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none', iconOnlyVariant === 'ghost' && [
142
+ return (_jsx("button", { ref: ref, type: "button", title: tooltip, disabled: isDisabled, className: cn('inline-flex items-center justify-center', 'rounded-full border-0', 'transition-colors duration-150 ease-in-out', 'focus:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--color-focus))] focus-visible:ring-offset-2', 'disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none', iconOnlyVariant === 'ghost' && [
143
143
  'text-[rgb(var(--fg-muted))]',
144
144
  'hover:bg-[rgb(var(--bg-hover))]',
145
145
  'active:bg-[rgb(var(--bg-subtle))]'
@@ -40,5 +40,5 @@ export function FormToggle({ isExpanded, onToggle, title, createTitle = 'Create
40
40
  else {
41
41
  onToggle(false);
42
42
  }
43
- }, className: "rounded-sm opacity-70 ring-offset-[rgb(var(--bg-surface))] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-primary))] focus:ring-offset-2", title: "Close form", children: [_jsx(X, { className: "h-5 w-5 text-[rgb(var(--color-icon))]" }), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }), isExpanded && (_jsx("div", { className: cn("px-6 pb-4 pt-2 space-y-4 animate-in slide-in-from-top duration-200", contentClassName), children: children }))] }));
43
+ }, className: "rounded-sm opacity-70 ring-offset-[rgb(var(--bg-surface))] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-focus))] focus:ring-offset-2", title: "Close form", children: [_jsx(X, { className: "h-5 w-5 text-[rgb(var(--color-icon))]" }), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }), isExpanded && (_jsx("div", { className: cn("px-6 pb-4 pt-2 space-y-4 animate-in slide-in-from-top duration-200", contentClassName), children: children }))] }));
44
44
  }
@@ -48,7 +48,7 @@ const Input = React.forwardRef(({ className, type = "text", label, error, helper
48
48
  };
49
49
  // Compact mode - just return the input without wrapper
50
50
  if (compact) {
51
- return (_jsx("input", { id: inputId, name: inputName, type: type, className: cn("flex h-10 w-full border px-3 py-2 text-xs", "bg-[rgb(var(--bg-surface))] text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-subtle))]", "focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-primary))]/10", "disabled:cursor-not-allowed disabled:opacity-50", "transition-all duration-200", type === "number" && "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
51
+ return (_jsx("input", { id: inputId, name: inputName, type: type, className: cn("flex h-10 w-full border px-3 py-2 text-xs", "bg-[rgb(var(--bg-surface))] text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-subtle))]", "focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-focus))]/10", "disabled:cursor-not-allowed disabled:opacity-50", "transition-all duration-200", type === "number" && "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
52
52
  // Joined group styling
53
53
  position === 'first' && "rounded-l border-r-0", position === 'middle' && "border-r-0", position === 'last' && "rounded-r", position === 'only' && "rounded", !position && "rounded",
54
54
  // Edited field highlighting
@@ -58,10 +58,10 @@ const Input = React.forwardRef(({ className, type = "text", label, error, helper
58
58
  ? "border-[rgb(var(--color-danger))] focus:border-[rgb(var(--color-danger))]"
59
59
  : isEdited
60
60
  ? "border-[rgb(var(--color-warning))] focus:border-[rgb(var(--color-warning))] focus:ring-[rgb(var(--color-warning))]/20 focus:z-10"
61
- : "border-[rgb(var(--bd-default))] focus:border-[rgb(var(--color-primary))] focus:z-10", className), ref: ref, onChange: handleChange, onKeyDown: handleKeyDown, onFocus: handleFocus, min: type === 'number' ? 0 : undefined, ...props }));
61
+ : "border-[rgb(var(--bd-default))] focus:border-[rgb(var(--color-focus))] focus:z-10", className), ref: ref, onChange: handleChange, onKeyDown: handleKeyDown, onFocus: handleFocus, min: type === 'number' ? 0 : undefined, ...props }));
62
62
  }
63
63
  // Standard mode with wrapper
64
- return (_jsxs("div", { className: "w-full", children: [label && (_jsx("label", { htmlFor: inputId, className: "block text-xs font-medium text-[rgb(var(--fg-default))] mb-1.5", suppressHydrationWarning: true, children: label })), _jsxs("div", { className: "relative", children: [LeftIcon && (_jsx("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2", children: _jsx(LeftIcon, { className: "h-4 w-4 text-[rgb(var(--fg-muted))]" }) })), _jsx("input", { id: inputId, name: inputName, type: type, className: cn("flex h-10 w-full rounded-md border px-3 py-2 text-xs", "bg-[rgb(var(--bg-surface))] text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-subtle))]", "focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-primary))]/10", "disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[rgb(var(--bg-subtle))]", "transition-all duration-200", type === "number" && "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none", LeftIcon && "pl-10", RightIcon && "pr-10",
64
+ return (_jsxs("div", { className: "w-full", children: [label && (_jsx("label", { htmlFor: inputId, className: "block text-xs font-medium text-[rgb(var(--fg-default))] mb-1.5", suppressHydrationWarning: true, children: label })), _jsxs("div", { className: "relative", children: [LeftIcon && (_jsx("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2", children: _jsx(LeftIcon, { className: "h-4 w-4 text-[rgb(var(--fg-muted))]" }) })), _jsx("input", { id: inputId, name: inputName, type: type, className: cn("flex h-10 w-full rounded-md border px-3 py-2 text-xs", "bg-[rgb(var(--bg-surface))] text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-subtle))]", "focus:outline-none focus:ring-2 focus:ring-[rgb(var(--color-focus))]/10", "disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[rgb(var(--bg-subtle))]", "transition-all duration-200", type === "number" && "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none", LeftIcon && "pl-10", RightIcon && "pr-10",
65
65
  // Edited field highlighting
66
66
  isEdited && !props.disabled && "bg-[rgb(var(--color-warning-subtle))] border-[rgb(var(--color-warning))]",
67
67
  // Border color
@@ -69,7 +69,7 @@ const Input = React.forwardRef(({ className, type = "text", label, error, helper
69
69
  ? "border-[rgb(var(--color-danger))] focus:border-[rgb(var(--color-danger))]"
70
70
  : isEdited
71
71
  ? "border-[rgb(var(--color-warning))] focus:border-[rgb(var(--color-warning))] focus:ring-[rgb(var(--color-warning))]/20"
72
- : "border-[rgb(var(--bd-default))] focus:border-[rgb(var(--color-primary))]", className), ref: ref, suppressHydrationWarning: label ? true : false, onChange: handleChange, onKeyDown: handleKeyDown, onFocus: handleFocus, min: type === 'number' ? 0 : undefined, ...props }), RightIcon && (_jsx("div", { className: cn("absolute right-3 top-1/2 transform -translate-y-1/2", onRightIconClick && !props.disabled && "cursor-pointer", props.disabled && "opacity-50 cursor-not-allowed"), onClick: props.disabled ? undefined : onRightIconClick, children: _jsx(RightIcon, { className: "h-4 w-4 text-[rgb(var(--fg-muted))]" }) }))] }), error && typeof error === 'string' && (_jsx("p", { className: "mt-1 text-sm text-[rgb(var(--color-danger))]", children: error })), helper && !error && (_jsx("p", { className: "mt-1 text-sm text-[rgb(var(--fg-muted))]", children: helper }))] }));
72
+ : "border-[rgb(var(--bd-default))] focus:border-[rgb(var(--color-focus))]", className), ref: ref, suppressHydrationWarning: label ? true : false, onChange: handleChange, onKeyDown: handleKeyDown, onFocus: handleFocus, min: type === 'number' ? 0 : undefined, ...props }), RightIcon && (_jsx("div", { className: cn("absolute right-3 top-1/2 transform -translate-y-1/2", onRightIconClick && !props.disabled && "cursor-pointer", props.disabled && "opacity-50 cursor-not-allowed"), onClick: props.disabled ? undefined : onRightIconClick, children: _jsx(RightIcon, { className: "h-4 w-4 text-[rgb(var(--fg-muted))]" }) }))] }), error && typeof error === 'string' && (_jsx("p", { className: "mt-1 text-sm text-[rgb(var(--color-danger))]", children: error })), helper && !error && (_jsx("p", { className: "mt-1 text-sm text-[rgb(var(--fg-muted))]", children: helper }))] }));
73
73
  });
74
74
  Input.displayName = "Input";
75
75
  export { Input };
@@ -10,9 +10,9 @@ import { Dropdown } from '../../forms/dropdown/index.js';
10
10
  const TabsRoot = TabsPrimitive.Root;
11
11
  const TabsList = React.forwardRef(({ className, ...props }, ref) => (_jsx(TabsPrimitive.List, { ref: ref, className: cn('inline-flex h-10 items-center justify-center rounded-md bg-[rgb(var(--bg-subtle))] p-1 text-[rgb(var(--fg-muted))]', className), ...props })));
12
12
  TabsList.displayName = TabsPrimitive.List.displayName;
13
- const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (_jsx(TabsPrimitive.Trigger, { ref: ref, className: cn('inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-[rgb(var(--bg-surface))] transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--color-primary))] focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-[rgb(var(--bg-surface))] data-[state=active]:text-[rgb(var(--fg-default))] data-[state=active]:shadow-sm', className), suppressHydrationWarning: true, ...props })));
13
+ const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (_jsx(TabsPrimitive.Trigger, { ref: ref, className: cn('inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-[rgb(var(--bg-surface))] transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--color-focus))] focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-[rgb(var(--bg-surface))] data-[state=active]:text-[rgb(var(--fg-default))] data-[state=active]:shadow-sm', className), suppressHydrationWarning: true, ...props })));
14
14
  TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
15
- const TabsContent = React.forwardRef(({ className, ...props }, ref) => (_jsx(TabsPrimitive.Content, { ref: ref, className: cn('mt-2 ring-offset-[rgb(var(--bg-surface))] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--color-primary))] focus-visible:ring-offset-2', className), suppressHydrationWarning: true, ...props })));
15
+ const TabsContent = React.forwardRef(({ className, ...props }, ref) => (_jsx(TabsPrimitive.Content, { ref: ref, className: cn('mt-2 ring-offset-[rgb(var(--bg-surface))] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--color-focus))] focus-visible:ring-offset-2', className), suppressHydrationWarning: true, ...props })));
16
16
  TabsContent.displayName = TabsPrimitive.Content.displayName;
17
17
  export function Tabs({ tabs, activeTab, onTabChange, fullWidth = false, className = '', variant = 'pill', size = 'md', dropdownValues, onDropdownChange }) {
18
18
  const containerClasses = cn('inline-flex items-center max-w-full overflow-x-auto scrollbar-hide [-webkit-overflow-scrolling:touch]', variant === 'pill' && 'bg-[rgb(var(--bg-subtle))] rounded-full border border-[rgb(var(--bd-default))] p-px gap-0.5', variant === 'rounded' && 'rounded-lg border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))] p-0.5', fullWidth && 'w-full', className);
@@ -22,6 +22,9 @@
22
22
 
23
23
  /* Primary Color System (Main brand/accent) - Default #003366 */
24
24
  --color-primary: 0 51 102; /* Primary brand color #003366 */
25
+ /* What a focused field or button is outlined in. The brand colour unless the app says
26
+ otherwise: an app that keeps its brand colour for primary actions sets a neutral here. */
27
+ --color-focus: var(--color-primary);
25
28
  --color-primary-hover: 0 40 82; /* Primary hover state - darker #003366 */
26
29
  --color-primary-subtle: 250 251 252; /* Very light primary backgrounds (0.02 opacity equivalent) */
27
30
  --color-primary-muted: 102 153 204; /* Muted primary */