indas-ui 0.1.9 → 0.1.11
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.
- package/dist/cjs/components/chat/multimodal-input.js +2 -2
- package/dist/cjs/components/dashboard/FilterBar.js +5 -3
- package/dist/cjs/components/datagrid/DataGrid.js +3 -3
- package/dist/cjs/components/datagrid/rows/FilterRow.js +1 -1
- package/dist/cjs/components/draft/DraftModal.js +1 -1
- package/dist/cjs/components/forms/date-picker/DateTimePicker.js +1 -1
- package/dist/cjs/components/forms/dropdown/Dropdown.js +1 -1
- package/dist/cjs/components/forms/file-attachment/FileAttachment.js +1 -1
- package/dist/cjs/components/forms/remark-input/RemarkInput.js +3 -3
- package/dist/cjs/components/layout/mobile-menu-sheet.js +1 -1
- package/dist/cjs/components/layout/top-header.js +1 -1
- package/dist/cjs/components/messaging/conversation-list.js +1 -1
- package/dist/cjs/components/messaging/create-conversation-modal.js +1 -1
- package/dist/cjs/components/messaging/message-input.js +1 -1
- package/dist/cjs/components/modals/ImageModal.js +1 -1
- package/dist/cjs/components/modals/Modal.js +1 -1
- package/dist/cjs/components/ui/buttons/button.js +1 -1
- package/dist/cjs/components/ui/form-toggle.js +1 -1
- package/dist/cjs/components/ui/forms/input.js +4 -4
- package/dist/cjs/components/ui/navigation/tabs.js +2 -2
- package/dist/cjs/styles/tokens.css +3 -0
- package/dist/components/chat/multimodal-input.d.ts +11 -1
- package/dist/components/chat/multimodal-input.js +2 -2
- package/dist/components/dashboard/FilterBar.js +5 -3
- package/dist/components/datagrid/DataGrid.js +3 -3
- package/dist/components/datagrid/rows/FilterRow.js +1 -1
- package/dist/components/draft/DraftModal.js +1 -1
- package/dist/components/forms/date-picker/DateTimePicker.js +1 -1
- package/dist/components/forms/dropdown/Dropdown.d.ts +1 -1
- package/dist/components/forms/dropdown/Dropdown.js +1 -1
- package/dist/components/forms/file-attachment/FileAttachment.js +1 -1
- package/dist/components/forms/remark-input/RemarkInput.js +3 -3
- package/dist/components/layout/mobile-menu-sheet.js +1 -1
- package/dist/components/layout/top-header.js +1 -1
- package/dist/components/messaging/conversation-list.js +1 -1
- package/dist/components/messaging/create-conversation-modal.js +1 -1
- package/dist/components/messaging/message-input.js +1 -1
- package/dist/components/modals/ImageModal.js +1 -1
- package/dist/components/modals/Modal.js +1 -1
- package/dist/components/ui/buttons/button.js +1 -1
- package/dist/components/ui/form-toggle.js +1 -1
- package/dist/components/ui/forms/input.js +4 -4
- package/dist/components/ui/navigation/tabs.js +2 -2
- package/dist/styles/tokens.css +3 -0
- package/package.json +1 -1
|
@@ -14,7 +14,7 @@ const utils_1 = require("../../lib/utils.js");
|
|
|
14
14
|
const LanguageContext_1 = require("../../contexts/LanguageContext.js");
|
|
15
15
|
/** What the paperclip offers when the host does not say: images, PDFs and documents. */
|
|
16
16
|
exports.DEFAULT_CHAT_ACCEPT = 'image/*,application/pdf,.doc,.docx,.txt';
|
|
17
|
-
function MultimodalInput({ onSubmit, onStop, isLoading = false, placeholder = 'Send a message...', allowFileUpload = true, accept = exports.DEFAULT_CHAT_ACCEPT, multiple = true, attachLabel = 'Attach file', compact = false, disabled = false, disabledReason }) {
|
|
17
|
+
function MultimodalInput({ onSubmit, onStop, isLoading = false, placeholder = 'Send a message...', allowFileUpload = true, accept = exports.DEFAULT_CHAT_ACCEPT, multiple = true, attachLabel = 'Attach file', attachIcon, compact = false, disabled = false, disabledReason }) {
|
|
18
18
|
// Optional: the composer is exported for host apps that have no LanguageProvider, and falls
|
|
19
19
|
// back to the English source text rather than throwing.
|
|
20
20
|
const { t } = (0, LanguageContext_1.useOptionalLanguage)();
|
|
@@ -114,7 +114,7 @@ function MultimodalInput({ onSubmit, onStop, isLoading = false, placeholder = 'S
|
|
|
114
114
|
const removeFile = (index) => {
|
|
115
115
|
setFiles(prev => prev.filter((_, i) => i !== index));
|
|
116
116
|
};
|
|
117
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.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: (0, jsx_runtime_1.jsxs)("div", { className: "max-w-3xl mx-auto", children: [disabled && disabledReason && ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "10" }), (0, jsx_runtime_1.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "12" }), (0, jsx_runtime_1.jsx)("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })] }), (0, jsx_runtime_1.jsx)("span", { children: disabledReason })] })), files.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-wrap gap-2 mb-3", children: files.map((file, index) => ((0, jsx_runtime_1.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/') ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Image, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })) : /\.(xlsx|xls|csv)$/i.test(file.name) ? ((0, jsx_runtime_1.jsx)(lucide_react_1.FileSpreadsheet, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.FileIcon, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })), (0, jsx_runtime_1.jsx)("span", { className: "text-[rgb(var(--fg-default))] truncate max-w-[150px]", children: file.name }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-3 h-3" }) })] }, index))) })), (0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.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-
|
|
117
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.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: (0, jsx_runtime_1.jsxs)("div", { className: "max-w-3xl mx-auto", children: [disabled && disabledReason && ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)("circle", { cx: "12", cy: "12", r: "10" }), (0, jsx_runtime_1.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "12" }), (0, jsx_runtime_1.jsx)("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })] }), (0, jsx_runtime_1.jsx)("span", { children: disabledReason })] })), files.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-wrap gap-2 mb-3", children: files.map((file, index) => ((0, jsx_runtime_1.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/') ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Image, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })) : /\.(xlsx|xls|csv)$/i.test(file.name) ? ((0, jsx_runtime_1.jsx)(lucide_react_1.FileSpreadsheet, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.FileIcon, { className: "w-4 h-4 text-[rgb(var(--fg-muted))]" })), (0, jsx_runtime_1.jsx)("span", { className: "text-[rgb(var(--fg-default))] truncate max-w-[150px]", children: file.name }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-3 h-3" }) })] }, index))) })), (0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.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 && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", multiple: multiple, accept: accept, onChange: handleFileSelect, className: "hidden" }), (0, jsx_runtime_1.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 ?? (0, jsx_runtime_1.jsx)(lucide_react_1.Paperclip, { className: "w-4 h-4" }) })] })), (0, jsx_runtime_1.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')
|
|
118
118
|
: isListening ? t('Listening...')
|
|
119
119
|
: placeholder, disabled: isListening || disabled, autoFocus: !disabled, rows: 1, className: (0, utils_1.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 && ((0, jsx_runtime_1.jsx)("button", { onClick: handleVoiceInput, className: (0, utils_1.cn)('shrink-0 !min-h-0 w-9 h-9 rounded-lg flex items-center justify-center transition-colors', isListening
|
|
120
120
|
? 'text-red-500 bg-red-500/10 animate-pulse'
|
|
@@ -273,7 +273,7 @@ function Stepper({ value, min, max, onChange }) {
|
|
|
273
273
|
onChange(clamped);
|
|
274
274
|
};
|
|
275
275
|
const buttonClasses = (0, utils_1.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');
|
|
276
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => onChange(value - 1), disabled: value <= min, className: buttonClasses, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Minus, { className: "w-3.5 h-3.5" }) }), (0, jsx_runtime_1.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: (0, utils_1.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-
|
|
276
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => onChange(value - 1), disabled: value <= min, className: buttonClasses, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Minus, { className: "w-3.5 h-3.5" }) }), (0, jsx_runtime_1.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: (0, utils_1.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))]') }), (0, jsx_runtime_1.jsx)("button", { onClick: () => onChange(value + 1), disabled: value >= max, className: buttonClasses, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { className: "w-3.5 h-3.5" }) })] }));
|
|
277
277
|
}
|
|
278
278
|
function OverflowMenu({ showInsights, insightsActive, onInsightsClick, reports, onReportSelect, onShare, onExport }) {
|
|
279
279
|
const { t } = (0, LanguageContext_1.useLanguage)();
|
|
@@ -417,7 +417,9 @@ function FilterBar({ title, contextLabel, description, secondaryToggle, timeFilt
|
|
|
417
417
|
} }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 text-center", children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-sm font-semibold text-[rgb(var(--fg-default))]", children: title }), contextLabel && ((0, jsx_runtime_1.jsx)("span", { className: "text-xs text-[rgb(var(--fg-muted))]", children: contextLabel })), description && (0, jsx_runtime_1.jsx)("p", { className: "mt-0.5 text-xs text-[rgb(var(--fg-muted))]", children: description })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [!hideFilterButton && ((0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsxs)("button", { ref: buttonRef, onClick: () => setPopoverOpen(!popoverOpen), className: (0, utils_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.ListFilter, { className: "w-4 h-4" }), hasActiveFilters && !popoverOpen && ((0, jsx_runtime_1.jsx)("span", { className: "absolute -top-1 -right-1 w-2 h-2 bg-[rgb(var(--color-primary))] rounded-full" }))] }), popoverOpen && ((0, jsx_runtime_1.jsxs)("div", { ref: popoverRef, className: (0, utils_1.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: [(0, jsx_runtime_1.jsxs)("div", { className: "px-3 py-2 border-b border-[rgb(var(--bd-default))] flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xs font-semibold text-[rgb(var(--fg-default))]", children: "Filters" }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-3 h-3 text-[rgb(var(--fg-muted))]" }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-3 space-y-3", children: [filters.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "grid gap-3", style: { gridTemplateColumns: `repeat(${filters.length}, minmax(140px, 1fr))` }, children: filters.map((filter) => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-[10px] font-semibold text-[rgb(var(--fg-muted))] uppercase tracking-wider mb-1 block", children: filter.label }), (0, jsx_runtime_1.jsx)(dropdown_1.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 && ((0, jsx_runtime_1.jsx)(date_picker_1.DatePicker, { mode: "range", value: dateRangeValue, onChange: handleDateRangeChange, inline: true }))] })] }))] })), forecast && onForecastChange && ((0, jsx_runtime_1.jsx)(ForecastControl, { forecast: forecast, onForecastChange: onForecastChange, timeFilter: timeFilter, onTimeFilterChange: onTimeFilterChange })), showApplyButton && ((0, jsx_runtime_1.jsx)("button", { onClick: onApply, className: (0, utils_1.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) && ((0, jsx_runtime_1.jsx)(OverflowMenu, { reports: reports, onReportSelect: onReportSelect, onShare: onShare, onExport: onExport }))] })] }) }) }));
|
|
418
418
|
}
|
|
419
419
|
// Default layout: Title centered, controls on right
|
|
420
|
-
return ((0, jsx_runtime_1.jsxs)("header", { className: (0, utils_1.cn)('bg-[rgb(var(--bg-surface))] border-b border-[rgb(var(--bd-default))]', 'px-4 py-3 lg:px-6', className), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex-auto min-w-0 flex items-center gap-2.5", children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-base sm:text-xl font-bold text-[rgb(var(--fg-default))] leading-tight truncate", children: title }), contextLabel && (
|
|
420
|
+
return ((0, jsx_runtime_1.jsxs)("header", { className: (0, utils_1.cn)('bg-[rgb(var(--bg-surface))] border-b border-[rgb(var(--bd-default))]', 'px-4 py-3 lg:px-6', className), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex-auto min-w-0 flex items-center gap-2.5", children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-base sm:text-xl font-bold text-[rgb(var(--fg-default))] leading-tight truncate", children: title }), contextLabel && (
|
|
421
|
+
/* Beside the title at every width: on a phone it sat on a line of its own under the title. */
|
|
422
|
+
(0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.CalendarDays, { className: "w-3.5 h-3.5" }), contextLabel] }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "ml-auto flex flex-wrap items-center justify-end gap-x-3 gap-y-2", children: [secondaryToggle && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { ref: toggleRef, className: "hidden sm:block", children: (0, jsx_runtime_1.jsx)(tabs_1.Tabs, { tabs: secondaryToggle.options.map(opt => ({ id: opt.value, label: opt.label })), activeTab: secondaryToggle.value, onTabChange: secondaryToggle.onChange, size: "sm" }) }), (0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.cn)('hidden h-4 w-px bg-[rgb(var(--bd-default))] self-center', !tabsWrapped && 'sm:block') })] })), !hideTimeFilter && ((0, jsx_runtime_1.jsx)("div", { ref: timeTabsRef, className: "hidden sm:block", children: (0, jsx_runtime_1.jsx)(tabs_1.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: {
|
|
421
423
|
Day: timeFilterSelection?.days || [],
|
|
422
424
|
Week: timeFilterSelection?.weeks || [],
|
|
423
425
|
Month: timeFilterSelection?.months || [],
|
|
@@ -436,7 +438,7 @@ function FilterBar({ title, contextLabel, description, secondaryToggle, timeFilt
|
|
|
436
438
|
onTimeFilterSelectionChange?.(newSelection);
|
|
437
439
|
} }) })), (0, jsx_runtime_1.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 && ((0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsxs)("button", { ref: buttonRef, onClick: () => setPopoverOpen(!popoverOpen), className: (0, utils_1.cn)('w-7 h-7 rounded-md flex items-center justify-center transition-colors relative', popoverOpen
|
|
438
440
|
? 'bg-[rgb(var(--color-primary))] text-white shadow-sm'
|
|
439
|
-
: 'text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] hover:bg-[rgb(var(--bg-subtle))]'), title: "Filters", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ListFilter, { className: "w-4 h-4" }), hasActiveFilters && !popoverOpen && ((0, jsx_runtime_1.jsx)("span", { className: "absolute -top-1 -right-1 w-2 h-2 bg-[rgb(var(--color-primary))] rounded-full" }))] }), popoverOpen && ((0, jsx_runtime_1.jsxs)("div", { ref: popoverRef, className: (0, utils_1.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: [(0, jsx_runtime_1.jsxs)("div", { className: "px-3 py-2 border-b border-[rgb(var(--bd-default))] flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xs font-semibold text-[rgb(var(--fg-default))]", children: "Filters" }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-3 h-3 text-[rgb(var(--fg-muted))]" }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-3 space-y-3", children: [filters.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "grid gap-3", style: { gridTemplateColumns: `repeat(${Math.min(filters.length, 3)}, minmax(140px, 1fr))` }, children: filters.map((filter) => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-[10px] font-semibold text-[rgb(var(--fg-muted))] uppercase tracking-wider mb-1 block", children: filter.label }), (0, jsx_runtime_1.jsx)(dropdown_1.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 && ((0, jsx_runtime_1.jsx)(date_picker_1.DatePicker, { mode: "range", value: dateRangeValue, onChange: handleDateRangeChange, inline: true }))] })] }))] })), forecast && onForecastChange && ((0, jsx_runtime_1.jsx)(ForecastControl, { forecast: forecast, onForecastChange: onForecastChange, timeFilter: timeFilter, onTimeFilterChange: onTimeFilterChange, bare: true })), (showInsights || reports.length > 0 || onShare || onExport) && ((0, jsx_runtime_1.jsx)(OverflowMenu, { showInsights: showInsights, insightsActive: insightsActive, onInsightsClick: onInsightsClick, reports: reports, onReportSelect: onReportSelect, onShare: onShare, onExport: onExport }))] }), showApplyButton && ((0, jsx_runtime_1.jsx)("button", { onClick: onApply, className: (0, utils_1.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" }))] })] }),
|
|
441
|
+
: 'text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] hover:bg-[rgb(var(--bg-subtle))]'), title: "Filters", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ListFilter, { className: "w-4 h-4" }), hasActiveFilters && !popoverOpen && ((0, jsx_runtime_1.jsx)("span", { className: "absolute -top-1 -right-1 w-2 h-2 bg-[rgb(var(--color-primary))] rounded-full" }))] }), popoverOpen && ((0, jsx_runtime_1.jsxs)("div", { ref: popoverRef, className: (0, utils_1.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: [(0, jsx_runtime_1.jsxs)("div", { className: "px-3 py-2 border-b border-[rgb(var(--bd-default))] flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xs font-semibold text-[rgb(var(--fg-default))]", children: "Filters" }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-3 h-3 text-[rgb(var(--fg-muted))]" }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-3 space-y-3", children: [filters.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "grid gap-3", style: { gridTemplateColumns: `repeat(${Math.min(filters.length, 3)}, minmax(140px, 1fr))` }, children: filters.map((filter) => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "text-[10px] font-semibold text-[rgb(var(--fg-muted))] uppercase tracking-wider mb-1 block", children: filter.label }), (0, jsx_runtime_1.jsx)(dropdown_1.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 && ((0, jsx_runtime_1.jsx)(date_picker_1.DatePicker, { mode: "range", value: dateRangeValue, onChange: handleDateRangeChange, inline: true }))] })] }))] })), forecast && onForecastChange && ((0, jsx_runtime_1.jsx)(ForecastControl, { forecast: forecast, onForecastChange: onForecastChange, timeFilter: timeFilter, onTimeFilterChange: onTimeFilterChange, bare: true })), (showInsights || reports.length > 0 || onShare || onExport) && ((0, jsx_runtime_1.jsx)(OverflowMenu, { showInsights: showInsights, insightsActive: insightsActive, onInsightsClick: onInsightsClick, reports: reports, onReportSelect: onReportSelect, onShare: onShare, onExport: onExport }))] }), showApplyButton && ((0, jsx_runtime_1.jsx)("button", { onClick: onApply, className: (0, utils_1.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) && ((0, jsx_runtime_1.jsxs)("div", { className: "sm:hidden mt-2 flex flex-col items-start gap-2", children: [secondaryToggle && ((0, jsx_runtime_1.jsx)(tabs_1.Tabs, { tabs: secondaryToggle.options.map(opt => ({ id: opt.value, label: opt.label })), activeTab: secondaryToggle.value, onTabChange: secondaryToggle.onChange, size: "sm" })), !hideTimeFilter && ((0, jsx_runtime_1.jsx)(tabs_1.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: {
|
|
440
442
|
Day: timeFilterSelection?.days || [],
|
|
441
443
|
Week: timeFilterSelection?.weeks || [],
|
|
442
444
|
Month: timeFilterSelection?.months || [],
|
|
@@ -1352,7 +1352,7 @@ enableFilterRow = false, initialColumnFilters, }) {
|
|
|
1352
1352
|
}
|
|
1353
1353
|
}, 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'
|
|
1354
1354
|
? 'bg-primary text-white shadow-sm'
|
|
1355
|
-
: '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: [(0, jsx_runtime_1.jsx)("span", { className: "hidden sm:inline", children: "Selected " }), "(", safeSelectedCount, ")"] })] }, "view-toggle")), preDateActions, enableSearch && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "min-w-0 flex-1", children: effectiveSearchType === 'advanced' ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ui_3.TooltipProvider, { delayDuration: 100, children: (0, jsx_runtime_1.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-
|
|
1355
|
+
: '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: [(0, jsx_runtime_1.jsx)("span", { className: "hidden sm:inline", children: "Selected " }), "(", safeSelectedCount, ")"] })] }, "view-toggle")), preDateActions, enableSearch && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "min-w-0 flex-1", children: effectiveSearchType === 'advanced' ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ui_3.TooltipProvider, { delayDuration: 100, children: (0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 flex-1 min-w-0", children: [speechSupported && ((0, jsx_runtime_1.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 ? (0, jsx_runtime_1.jsx)(lucide_react_1.MicOff, { className: "h-3.5 w-3.5" }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Mic, { className: "h-3.5 w-3.5" }) })), (0, jsx_runtime_1.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))]" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 flex-shrink-0 ml-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))]" }), enableDateFilter && ((0, jsx_runtime_1.jsx)(DatePicker_1.DatePicker, { mode: "range", value: { from: dateFrom || undefined, to: dateTo || undefined }, onChange: (range) => {
|
|
1356
1356
|
if (range && typeof range === 'object' && 'from' in range) {
|
|
1357
1357
|
onDateFromChange?.(range.from || null);
|
|
1358
1358
|
onDateToChange?.(range.to || null);
|
|
@@ -1378,7 +1378,7 @@ enableFilterRow = false, initialColumnFilters, }) {
|
|
|
1378
1378
|
}, "aria-label": "Auto-size all columns to fit content", children: "Auto-size" })] })] }) }), enableColumnFreezing && frozenColumns.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "px-2 py-1", children: (0, jsx_runtime_1.jsx)("div", { className: "bg-[rgb(var(--color-primary-subtle))] rounded-md p-1 space-y-0.5", children: frozenColumns.map((column) => ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center space-x-2 flex-1", children: [(0, jsx_runtime_1.jsx)("input", { type: "checkbox", checked: column.getIsVisible(), onChange: (e) => {
|
|
1379
1379
|
e.stopPropagation();
|
|
1380
1380
|
column.toggleVisibility(e.target.checked);
|
|
1381
|
-
}, className: "w-3 h-3 rounded border-[rgb(var(--bd-default))] text-[rgb(var(--color-primary))] focus:ring-[rgb(var(--color-
|
|
1381
|
+
}, className: "w-3 h-3 rounded border-[rgb(var(--bd-default))] text-[rgb(var(--color-primary))] focus:ring-[rgb(var(--color-focus))] cursor-pointer" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-[rgb(var(--fg-default))] capitalize truncate", children: column.id })] }), (0, jsx_runtime_1.jsx)(ui_1.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) => {
|
|
1382
1382
|
e.stopPropagation();
|
|
1383
1383
|
const newFrozenColumns = new Set(frozenColumnsState);
|
|
1384
1384
|
newFrozenColumns.delete(column.id);
|
|
@@ -1388,7 +1388,7 @@ enableFilterRow = false, initialColumnFilters, }) {
|
|
|
1388
1388
|
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between px-2 py-1.5 hover:bg-[rgb(var(--bg-subtle))] rounded group cursor-pointer", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center space-x-2 flex-1", children: [(0, jsx_runtime_1.jsx)("input", { type: "checkbox", checked: column.getIsVisible(), onChange: (e) => {
|
|
1389
1389
|
e.stopPropagation();
|
|
1390
1390
|
column.toggleVisibility(e.target.checked);
|
|
1391
|
-
}, className: "w-3 h-3 rounded border-[rgb(var(--bd-default))] text-[rgb(var(--color-primary))] focus:ring-[rgb(var(--color-
|
|
1391
|
+
}, className: "w-3 h-3 rounded border-[rgb(var(--bd-default))] text-[rgb(var(--color-primary))] focus:ring-[rgb(var(--color-focus))] cursor-pointer" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-[rgb(var(--fg-default))] capitalize truncate", children: column.id })] }), enableColumnFreezing && !isSelectColumn && ((0, jsx_runtime_1.jsx)(ui_1.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) => {
|
|
1392
1392
|
e.stopPropagation();
|
|
1393
1393
|
const newFrozenColumns = new Set(frozenColumnsState);
|
|
1394
1394
|
newFrozenColumns.add(column.id);
|
|
@@ -136,7 +136,7 @@ function FilterCell({ header, isFrozen, isPinnedRight, leftPosition, rightPositi
|
|
|
136
136
|
})
|
|
137
137
|
}, className: (0, utils_1.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 ? (
|
|
138
138
|
// Empty cell for select/action columns
|
|
139
|
-
(0, jsx_runtime_1.jsx)("div", { className: "h-full" })) : ((0, jsx_runtime_1.jsxs)("div", { className: "relative flex items-center h-full", children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute left-1.5 top-1/2 -translate-y-1/2 pointer-events-none opacity-50", children: isDate ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Calendar, { className: "h-3 w-3 text-[rgb(var(--color-icon))]" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "h-3 w-3 text-[rgb(var(--color-icon))]" })) }), (0, jsx_runtime_1.jsx)("input", { ref: inputRef, type: isNumber ? 'number' : 'text', value: localValue, onChange: handleChange, placeholder: "", className: (0, utils_1.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-
|
|
139
|
+
(0, jsx_runtime_1.jsx)("div", { className: "h-full" })) : ((0, jsx_runtime_1.jsxs)("div", { className: "relative flex items-center h-full", children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute left-1.5 top-1/2 -translate-y-1/2 pointer-events-none opacity-50", children: isDate ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Calendar, { className: "h-3 w-3 text-[rgb(var(--color-icon))]" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "h-3 w-3 text-[rgb(var(--color-icon))]" })) }), (0, jsx_runtime_1.jsx)("input", { ref: inputRef, type: isNumber ? 'number' : 'text', value: localValue, onChange: handleChange, placeholder: "", className: (0, utils_1.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))]',
|
|
140
140
|
// Highlight active filter
|
|
141
141
|
localValue
|
|
142
142
|
? 'border-2 border-[rgb(var(--color-primary))] bg-[color-mix(in_srgb,rgb(var(--color-primary))_5%,rgb(var(--bg-surface)))]'
|
|
@@ -192,7 +192,7 @@ function DraftModal({ open, onClose, drafts, onLoad, onDelete, isLoading = false
|
|
|
192
192
|
// Early return after all hooks to comply with Rules of Hooks
|
|
193
193
|
if (!open)
|
|
194
194
|
return null;
|
|
195
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm", children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-[rgb(var(--bg-surface))] rounded-lg shadow-2xl w-full max-w-4xl max-h-[85vh] flex flex-col", children: [(0, jsx_runtime_1.jsxs)("div", { className: "px-6 py-3 border-b border-[rgb(var(--bd-default))] flex items-center gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 flex-shrink-0", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.FileText, { className: "w-5 h-5 text-[rgb(var(--color-primary))]" }), (0, jsx_runtime_1.jsx)("h2", { className: "text-base font-semibold text-[rgb(var(--fg-default))]", children: "Saved Drafts" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-xs text-[rgb(var(--fg-muted))]", children: ["(", drafts.length, ")"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "relative flex-1", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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-
|
|
195
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm", children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-[rgb(var(--bg-surface))] rounded-lg shadow-2xl w-full max-w-4xl max-h-[85vh] flex flex-col", children: [(0, jsx_runtime_1.jsxs)("div", { className: "px-6 py-3 border-b border-[rgb(var(--bd-default))] flex items-center gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 flex-shrink-0", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.FileText, { className: "w-5 h-5 text-[rgb(var(--color-primary))]" }), (0, jsx_runtime_1.jsx)("h2", { className: "text-base font-semibold text-[rgb(var(--fg-default))]", children: "Saved Drafts" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-xs text-[rgb(var(--fg-muted))]", children: ["(", drafts.length, ")"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "relative flex-1", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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 " })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex-shrink-0 w-36", children: (0, jsx_runtime_1.jsx)(dropdown_1.Dropdown, { options: SORT_OPTIONS, value: sortBy, onValueChange: (val) => setSortBy(val), size: "sm", autoWidth: true }) }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-5 h-5" }) })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 overflow-y-auto px-6 py-4", children: isLoading ? ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-16", children: (0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.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" }), (0, jsx_runtime_1.jsx)("p", { className: "text-[rgb(var(--fg-muted))]", children: "Loading drafts..." })] }) })) : filteredAndSortedDrafts.length === 0 ? ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.FileText, { className: "w-16 h-16 text-[rgb(var(--fg-muted))] mb-4 opacity-50" }), (0, jsx_runtime_1.jsx)("p", { className: "text-lg font-medium text-[rgb(var(--fg-default))] mb-1", children: searchQuery ? 'No matching drafts' : 'No drafts saved yet' }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-[rgb(var(--fg-muted))]", children: searchQuery ? 'Try a different search term' : 'Start by clicking "Save Draft" button' })] })) : ((0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: paginatedDrafts.map((draft) => {
|
|
196
196
|
const progress = calculateProgress(draft);
|
|
197
197
|
const preview = draft.previewData || {};
|
|
198
198
|
return ((0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)("div", { className: "flex items-start gap-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("h3", { className: "font-semibold text-[rgb(var(--fg-default))] truncate text-base", children: draft.draftName || 'Untitled Draft' }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mt-1 text-xs text-[rgb(var(--fg-muted))]", children: [(0, jsx_runtime_1.jsx)("span", { children: formatRelativeTime(draft.lastSaved) }), (0, jsx_runtime_1.jsxs)("span", { className: "hidden group-hover:inline", children: ["\u2022 ", formatFullDate(draft.lastSaved)] }), draft.isAutoSave && ((0, jsx_runtime_1.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" }))] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity", children: [(0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.Download, { className: "w-4 h-4" }), "Load"] }), (0, jsx_runtime_1.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 ? ((0, jsx_runtime_1.jsx)("div", { className: "w-4 h-4 rounded-full border-2 border-red-200 border-t-red-600 animate-spin" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Trash2, { className: "w-4 h-4" })) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 gap-x-6 gap-y-1 mt-2 text-sm", children: [preview.jobName && ((0, jsx_runtime_1.jsx)("div", { className: "text-[rgb(var(--fg-muted))] truncate", children: preview.jobName }, "job")), preview.clientName && ((0, jsx_runtime_1.jsx)("div", { className: "text-[rgb(var(--fg-muted))] truncate", children: preview.clientName }, "client")), preview.category && ((0, jsx_runtime_1.jsx)("div", { className: "text-[rgb(var(--fg-muted))] truncate", children: preview.category }, "category")), preview.totalCost !== undefined && preview.totalCost > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "font-medium text-[rgb(var(--color-primary))]", children: [currencySymbol, preview.totalCost.toLocaleString('en-IN')] }, "cost"))] }), progress > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "mt-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between text-xs text-[rgb(var(--fg-muted))] mb-1", children: [(0, jsx_runtime_1.jsx)("span", { children: "Progress" }), (0, jsx_runtime_1.jsxs)("span", { className: "font-medium", children: [progress, "%"] })] }), (0, jsx_runtime_1.jsx)("div", { className: "h-1.5 bg-[rgb(var(--bg-muted))] rounded-full overflow-hidden", children: (0, jsx_runtime_1.jsx)("div", { className: "h-full bg-[rgb(var(--color-primary))] transition-all duration-500 rounded-full", style: { width: `${progress}%` } }) })] }))] }) }) }, draft.draftId));
|
|
@@ -165,7 +165,7 @@ function DateTimePicker({ value, onChange, placeholder = 'Select date & time...'
|
|
|
165
165
|
e.preventDefault();
|
|
166
166
|
onChange(value === 0 ? max : value - 1);
|
|
167
167
|
}
|
|
168
|
-
}, 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-
|
|
168
|
+
}, 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 }), (0, jsx_runtime_1.jsx)("span", { className: "text-[10px] text-[rgb(var(--fg-muted))] mt-0.5", children: label })] }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeft, { className: "h-4 w-4 -rotate-90" }) })] }));
|
|
169
169
|
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.cn)('relative w-full', className), children: [label && ((0, jsx_runtime_1.jsx)("label", { className: "block text-sm font-medium text-[rgb(var(--fg-default))] mb-2", children: label })), (0, jsx_runtime_1.jsxs)(Popover.Root, { open: isOpen, onOpenChange: setIsOpen, children: [(0, jsx_runtime_1.jsx)(Popover.Trigger, { asChild: true, children: (0, jsx_runtime_1.jsx)("div", { className: "relative", children: (0, jsx_runtime_1.jsx)(ui_2.Input, { value: inputValue, onChange: (e) => setInputValue(e.target.value), placeholder: placeholder, disabled: disabled, error: error, className: (0, utils_1.cn)('pl-2 pr-9 text-xs w-full', error && 'border-red-300'), onFocus: () => !disabled && setIsOpen(true), rightIcon: lucide_react_1.Calendar, onRightIconClick: () => !disabled && setIsOpen(!isOpen), readOnly: true }) }) }), (0, jsx_runtime_1.jsx)(Popover.Portal, { container: typeof document !== 'undefined' ? document.body : undefined, children: (0, jsx_runtime_1.jsxs)(Popover.Content, { className: (0, utils_1.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: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Calendar, { className: "h-4 w-4 text-[rgb(var(--color-primary))]" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-semibold text-[rgb(var(--fg-default))]", children: "Select Date & Time" })] }), (0, jsx_runtime_1.jsx)(ui_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-3 w-3" }) })] }), (0, jsx_runtime_1.jsx)(CalendarView_1.CalendarView, { currentMonth: selectedDate || new Date(), selectedDate: selectedDate, onDateClick: handleDateClick, onMonthChange: handleMonthChange, minDate: minDate, maxDate: maxDate, showNavigation: true }), (0, jsx_runtime_1.jsxs)("div", { className: "border-t border-[rgb(var(--bd-default))] pt-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-3", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Clock, { className: "h-4 w-4 text-[rgb(var(--color-primary))]" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-semibold text-[rgb(var(--fg-default))]", children: "Time" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center gap-2", children: [renderTimeInput(hours, setHours, timeFormat === '12h' ? 12 : 23, 'Hours'), (0, jsx_runtime_1.jsx)("span", { className: "text-2xl font-bold text-[rgb(var(--fg-muted))] mb-5", children: ":" }), renderTimeInput(minutes, setMinutes, 59, 'Mins'), timeFormat === '12h' && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "w-px h-16 bg-[rgb(var(--bd-default))] mx-2" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-1", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setPeriod('AM'), className: (0, utils_1.cn)('px-3 py-1.5 text-sm font-semibold rounded-lg transition-all duration-200', period === 'AM'
|
|
170
170
|
? 'bg-[rgb(var(--color-primary))] text-white shadow-md'
|
|
171
171
|
: 'bg-[rgb(var(--bg-subtle))] text-[rgb(var(--fg-default))] hover:bg-[rgb(var(--bg-hover))]'), children: "AM" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setPeriod('PM'), className: (0, utils_1.cn)('px-3 py-1.5 text-sm font-semibold rounded-lg transition-all duration-200', period === 'PM'
|
|
@@ -153,7 +153,7 @@ exports.dropdownSharedStyles = {
|
|
|
153
153
|
// Trigger (button) styles
|
|
154
154
|
trigger: {
|
|
155
155
|
base: "flex items-center justify-between rounded-md border bg-bg-surface cursor-pointer transition-all duration-200",
|
|
156
|
-
focus: "focus-within:outline-none focus-within:border-[rgb(var(--color-
|
|
156
|
+
focus: "focus-within:outline-none focus-within:border-[rgb(var(--color-focus))]",
|
|
157
157
|
error: "border-[rgb(var(--color-error))] focus-within:border-[rgb(var(--color-error))]",
|
|
158
158
|
normal: "border-[rgb(var(--bd-default))] hover:border-[rgb(var(--bd-hover))]",
|
|
159
159
|
disabled: "cursor-not-allowed opacity-50",
|
|
@@ -908,7 +908,7 @@ acceptedFileTypes = [], label = "File Attachment", className, disabled = false,
|
|
|
908
908
|
setSelectedEmail(null);
|
|
909
909
|
setEmailSearchQuery('');
|
|
910
910
|
}
|
|
911
|
-
}, children: (0, jsx_runtime_1.jsxs)(Modal_1.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: [(0, jsx_runtime_1.jsx)(Modal_1.ModalHeader, { className: "px-5 py-3 border-b border-[rgb(var(--bd-default))] flex-shrink-0 bg-[rgb(var(--bg-surface))]", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between w-full gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 flex-shrink-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-9 h-9 rounded-lg bg-[rgba(var(--color-primary),0.1)] flex items-center justify-center", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Mail, { className: "h-4.5 w-4.5 text-[rgb(var(--color-primary))]" }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(Modal_1.ModalTitle, { className: "text-sm", children: "Import from Email" }), emailState.emails.length > 0 && ((0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-[rgb(var(--fg-muted))] mt-0.5", children: [emailState.emails.length, " emails"] }))] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0 relative", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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-
|
|
911
|
+
}, children: (0, jsx_runtime_1.jsxs)(Modal_1.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: [(0, jsx_runtime_1.jsx)(Modal_1.ModalHeader, { className: "px-5 py-3 border-b border-[rgb(var(--bd-default))] flex-shrink-0 bg-[rgb(var(--bg-surface))]", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between w-full gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 flex-shrink-0", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-9 h-9 rounded-lg bg-[rgba(var(--color-primary),0.1)] flex items-center justify-center", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Mail, { className: "h-4.5 w-4.5 text-[rgb(var(--color-primary))]" }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(Modal_1.ModalTitle, { className: "text-sm", children: "Import from Email" }), emailState.emails.length > 0 && ((0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-[rgb(var(--fg-muted))] mt-0.5", children: [emailState.emails.length, " emails"] }))] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0 relative", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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 && ((0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }) }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 flex-shrink-0", children: [(0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.RefreshCw, { className: (0, utils_1.cn)("h-4 w-4", emailState.loading && "animate-spin") }) }), (0, jsx_runtime_1.jsx)("button", { onClick: () => {
|
|
912
912
|
setShowEmailImportModal(false);
|
|
913
913
|
setSelectedEmail(null);
|
|
914
914
|
setEmailSearchQuery('');
|
|
@@ -143,11 +143,11 @@ function RemarkTrail({ remarks, onAdd, canAdd = true, loading = false, onClose,
|
|
|
143
143
|
e.preventDefault();
|
|
144
144
|
commitEdit();
|
|
145
145
|
} if (e.key === 'Escape')
|
|
146
|
-
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-
|
|
146
|
+
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))]" }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: commitEdit, title: t('Save'), className: "p-1 rounded bg-[rgb(var(--color-primary))] text-white hover:opacity-90", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Check, { className: "h-3 w-3" }) }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-3 w-3" }) })] })) : (r.text && (0, jsx_runtime_1.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 && ((0, jsx_runtime_1.jsx)("div", { className: "mt-1 flex flex-wrap gap-1.5", children: r.files.map((f, i) => ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.FileText, { className: "h-3 w-3 shrink-0" }), (0, jsx_runtime_1.jsx)("span", { className: "truncate", children: f.name })] }, i))) }))] }, r.seq));
|
|
147
147
|
}) })) }), onAdd && ((0, jsx_runtime_1.jsxs)("div", { className: "border-t border-[rgb(var(--bd-subtle))] px-2 py-1.5 space-y-1.5", children: [pendingFiles.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-wrap gap-1.5", children: pendingFiles.map((f, i) => ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.FileText, { className: "h-3 w-3 shrink-0" }), (0, jsx_runtime_1.jsx)("span", { className: "truncate", children: f.name }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-2.5 w-2.5" }) })] }, i))) })), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5", children: [onUploadFiles && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", onChange: handlePickFiles }), (0, jsx_runtime_1.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 ? (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Paperclip, { className: "h-3.5 w-3.5" }) })] })), (0, jsx_runtime_1.jsx)("input", { value: text, onChange: (e) => setText(e.target.value), onKeyDown: (e) => { if (e.key === 'Enter' && !e.shiftKey) {
|
|
148
148
|
e.preventDefault();
|
|
149
149
|
handleAdd();
|
|
150
|
-
} }, 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-
|
|
150
|
+
} }, 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" }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.Send, { className: "h-3.5 w-3.5" }) })] })] }))] }));
|
|
151
151
|
}
|
|
152
152
|
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, }) {
|
|
153
153
|
const { t } = (0, LanguageContext_1.useLanguage)();
|
|
@@ -259,5 +259,5 @@ function RemarkInput({ value, onChange, module, documentId, documentName, docume
|
|
|
259
259
|
userResized.current = true;
|
|
260
260
|
}, placeholder: placeholder ?? t('Add remarks or notes...'), rows: rows, disabled: disabled, className: (0, utils_1.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
|
|
261
261
|
? 'border-[rgb(var(--color-error))] placeholder:text-[rgb(var(--fg-subtle))]'
|
|
262
|
-
: '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-
|
|
262
|
+
: '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 && ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.Info, { className: "h-3 w-3" }), count > 0 && (0, jsx_runtime_1.jsx)("span", { className: "absolute -top-1 -right-1 h-2 w-2 rounded-full bg-[rgb(var(--color-primary))]" })] }))] }), (0, jsx_runtime_1.jsx)(components_1.Modal, { open: trailOpen, onOpenChange: setTrailOpen, children: (0, jsx_runtime_1.jsxs)(components_1.ModalContent, { size: "md", hideCloseButton: true, className: "p-0 overflow-hidden max-h-[80vh]", children: [(0, jsx_runtime_1.jsx)(components_1.ModalTitle, { className: "sr-only", children: t('Remarks') }), (0, jsx_runtime_1.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" })] }) })] }));
|
|
263
263
|
}
|
|
@@ -179,7 +179,7 @@ function MobileMenuSheet({ open, onClose }) {
|
|
|
179
179
|
const getInitials = (name) => {
|
|
180
180
|
return name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2);
|
|
181
181
|
};
|
|
182
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.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 }), (0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.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: [(0, jsx_runtime_1.jsx)("div", { className: "flex justify-center pt-2.5 pb-1", children: (0, jsx_runtime_1.jsx)("div", { className: "w-9 h-1 rounded-full bg-[rgb(var(--bd-default))]" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 px-4 py-2.5 border-b border-[rgb(var(--bd-default))]", children: [(0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)("span", { className: "text-xs font-semibold text-[rgb(var(--fg-muted))]", children: getInitials(userName) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm font-semibold text-[rgb(var(--fg-default))] truncate leading-tight", children: userName }), userRole && ((0, jsx_runtime_1.jsx)("p", { className: "text-[0.65rem] text-[rgb(var(--fg-muted))] truncate", children: userRole }))] }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-4.5 w-4.5" }) })] }), (0, jsx_runtime_1.jsx)("div", { className: "px-4 py-2.5", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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-
|
|
182
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.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 }), (0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.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: [(0, jsx_runtime_1.jsx)("div", { className: "flex justify-center pt-2.5 pb-1", children: (0, jsx_runtime_1.jsx)("div", { className: "w-9 h-1 rounded-full bg-[rgb(var(--bd-default))]" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 px-4 py-2.5 border-b border-[rgb(var(--bd-default))]", children: [(0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)("span", { className: "text-xs font-semibold text-[rgb(var(--fg-muted))]", children: getInitials(userName) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm font-semibold text-[rgb(var(--fg-default))] truncate leading-tight", children: userName }), userRole && ((0, jsx_runtime_1.jsx)("p", { className: "text-[0.65rem] text-[rgb(var(--fg-muted))] truncate", children: userRole }))] }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-4.5 w-4.5" }) })] }), (0, jsx_runtime_1.jsx)("div", { className: "px-4 py-2.5", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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 && ((0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-3.5 w-3.5" }) }))] }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 overflow-y-auto px-2 pb-2", children: filteredGroups.length === 0 ? ((0, jsx_runtime_1.jsxs)("div", { className: "py-12 text-center", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "h-8 w-8 mx-auto mb-2 text-[rgb(var(--fg-muted))] opacity-30" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-[rgb(var(--fg-muted))]", children: t('No modules found') })] })) : (filteredGroups.map(group => {
|
|
183
183
|
const GroupIcon = getGroupIcon(group.groupName);
|
|
184
184
|
const isExpanded = expandedGroups.includes(group.groupName);
|
|
185
185
|
return ((0, jsx_runtime_1.jsxs)("div", { className: "mb-0.5", children: [(0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(GroupIcon, { className: "h-4 w-4 text-[rgb(var(--fg-muted))] flex-shrink-0" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs font-semibold text-[rgb(var(--fg-muted))] uppercase tracking-wide flex-1", children: t(group.groupName) }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { className: (0, utils_1.cn)('h-3.5 w-3.5 text-[rgb(var(--fg-muted))]/50 transition-transform duration-200', isExpanded && 'rotate-90') })] }), isExpanded && ((0, jsx_runtime_1.jsx)("div", { className: "ml-5 pl-3 border-l-2 border-[rgb(var(--bd-default))]/50 mb-1", children: group.modules.map(mod => {
|
|
@@ -221,7 +221,7 @@ function TopHeader({ className, sidebarCollapsed = true, onToggleSidebar, onTogg
|
|
|
221
221
|
})(), showNotificationDropdown && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "fixed inset-0 z-40", onClick: () => {
|
|
222
222
|
setShowNotificationDropdown(false);
|
|
223
223
|
setNotificationSearchQuery('');
|
|
224
|
-
} }), (0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.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: [(0, jsx_runtime_1.jsxs)("div", { className: "px-5 pt-5 pb-0 bg-[rgb(var(--bg-surface))]", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 mb-4", children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-bold text-[rgb(var(--fg-default))] flex-shrink-0", children: "Notifications" }), (0, jsx_runtime_1.jsxs)("div", { className: "relative flex-1", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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-
|
|
224
|
+
} }), (0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.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: [(0, jsx_runtime_1.jsxs)("div", { className: "px-5 pt-5 pb-0 bg-[rgb(var(--bg-surface))]", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 mb-4", children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-bold text-[rgb(var(--fg-default))] flex-shrink-0", children: "Notifications" }), (0, jsx_runtime_1.jsxs)("div", { className: "relative flex-1", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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" })] }), (0, jsx_runtime_1.jsx)("button", { onClick: (e) => {
|
|
225
225
|
e.stopPropagation();
|
|
226
226
|
setShowNotificationDropdown(false);
|
|
227
227
|
router.push('/settings?tab=notifications');
|
|
@@ -103,7 +103,7 @@ function ConversationList({ currentUserId, onSelectRoom, onNewConversation, acti
|
|
|
103
103
|
const handleSelectRoom = (0, react_1.useCallback)((room) => {
|
|
104
104
|
onSelectRoom(room);
|
|
105
105
|
}, [onSelectRoom]);
|
|
106
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.cn)('flex flex-col h-full', className), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex-shrink-0 px-3 pt-3 pb-2 space-y-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("h2", { className: "text-lg font-semibold text-[rgb(var(--fg-default))]", children: t('Messages') }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { className: "w-5 h-5" }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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-
|
|
106
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.cn)('flex flex-col h-full', className), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex-shrink-0 px-3 pt-3 pb-2 space-y-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("h2", { className: "text-lg font-semibold text-[rgb(var(--fg-default))]", children: t('Messages') }), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { className: "w-5 h-5" }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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 && ((0, jsx_runtime_1.jsx)("button", { onClick: () => setSearchText(''), className: "absolute right-2 top-1/2 -translate-y-1/2 text-[rgb(var(--fg-muted))]", children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-3.5 h-3.5" }) }))] }), (0, jsx_runtime_1.jsx)("div", { className: "flex gap-1", children: tabs.map(tab => ((0, jsx_runtime_1.jsx)("button", { onClick: () => setFilter(tab.key), className: (0, utils_1.cn)('flex-1 py-1 px-2 rounded-md text-xs font-medium transition-colors', filter === tab.key
|
|
107
107
|
? 'bg-[rgb(var(--color-primary))] text-white'
|
|
108
108
|
: 'text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))]'), children: tab.label }, tab.key))) })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 overflow-y-auto px-1.5 py-1", children: state.loadingConversations ? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-2 px-2", children: [1, 2, 3, 4, 5].map(i => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 py-2.5 animate-pulse", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-10 h-10 rounded-full bg-[rgb(var(--bg-subtle))]" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 space-y-1.5", children: [(0, jsx_runtime_1.jsx)("div", { className: "h-3.5 w-24 rounded bg-[rgb(var(--bg-subtle))]" }), (0, jsx_runtime_1.jsx)("div", { className: "h-3 w-40 rounded bg-[rgb(var(--bg-subtle))]" })] })] }, i))) })) : filteredConversations.length === 0 ? ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 text-[rgb(var(--fg-muted))]", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.MessageSquare, { className: "w-10 h-10 mb-2 opacity-40" }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm", children: searchText ? t('No conversations found') : t('No conversations yet') }), !searchText && ((0, jsx_runtime_1.jsx)("button", { onClick: onNewConversation, className: "mt-2 text-xs text-[rgb(var(--color-primary))] hover:underline", children: t('Start a conversation') }))] })) : (filteredConversations.map(room => ((0, jsx_runtime_1.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)))) })] }));
|
|
109
109
|
}
|
|
@@ -105,7 +105,7 @@ function CreateConversationModal({ open, onClose, onCreated, currentUserId }) {
|
|
|
105
105
|
: selectedUsers.length > 0 && name.trim();
|
|
106
106
|
return ((0, jsx_runtime_1.jsx)(ui_1.Modal, { open: open, onOpenChange: onClose, children: (0, jsx_runtime_1.jsxs)(ui_1.ModalContent, { size: "md", hideCloseButton: true, disableOutsideClick: true, className: "p-0 flex flex-col overflow-hidden max-h-[85vh]", children: [(0, jsx_runtime_1.jsx)(ui_1.ModalHeader, { className: "px-5 py-4 border-b border-[rgb(var(--bd-default))]", children: (0, jsx_runtime_1.jsx)(ui_1.ModalTitle, { children: t('New Conversation') }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 overflow-y-auto p-5 space-y-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-3 gap-2", children: typeOptions.map(opt => ((0, jsx_runtime_1.jsxs)("button", { onClick: () => { setType(opt.key); setSelectedUsers([]); }, className: (0, utils_1.cn)('flex flex-col items-center gap-1 p-3 rounded-lg border transition-colors', type === opt.key
|
|
107
107
|
? 'border-[rgb(var(--color-primary))] bg-[rgb(var(--color-primary)/0.05)]'
|
|
108
|
-
: 'border-[rgb(var(--bd-default))] hover:bg-[rgb(var(--bg-hover))]'), children: [(0, jsx_runtime_1.jsx)(opt.icon, { className: (0, utils_1.cn)('w-5 h-5', type === opt.key ? 'text-[rgb(var(--color-primary))]' : 'text-[rgb(var(--fg-muted))]') }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs font-medium", children: opt.label })] }, opt.key))) }), type !== 'DM' && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs font-medium text-[rgb(var(--fg-muted))]", children: t('Name') }), (0, jsx_runtime_1.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-
|
|
108
|
+
: 'border-[rgb(var(--bd-default))] hover:bg-[rgb(var(--bg-hover))]'), children: [(0, jsx_runtime_1.jsx)(opt.icon, { className: (0, utils_1.cn)('w-5 h-5', type === opt.key ? 'text-[rgb(var(--color-primary))]' : 'text-[rgb(var(--fg-muted))]') }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs font-medium", children: opt.label })] }, opt.key))) }), type !== 'DM' && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs font-medium text-[rgb(var(--fg-muted))]", children: t('Name') }), (0, jsx_runtime_1.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))]" }), (0, jsx_runtime_1.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' && ((0, jsx_runtime_1.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer", children: [(0, jsx_runtime_1.jsx)("input", { type: "checkbox", checked: isPublic, onChange: e => setIsPublic(e.target.checked), className: "rounded" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm text-[rgb(var(--fg-default))]", children: t('Public channel') })] }))] })), selectedUsers.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-wrap gap-1.5", children: selectedUsers.map(user => ((0, jsx_runtime_1.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, (0, jsx_runtime_1.jsx)("button", { onClick: () => toggleUser(user), className: "hover:opacity-70", children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-3 h-3" }) })] }, user.UserID))) })), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-xs font-medium text-[rgb(var(--fg-muted))]", children: type === 'DM' ? t('Select person') : t('Add members') }), (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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))]" })] })] }), (0, jsx_runtime_1.jsx)("div", { className: "max-h-48 overflow-y-auto rounded-lg border border-[rgb(var(--bd-default))]", children: filteredContacts.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "p-4 text-center text-sm text-[rgb(var(--fg-muted))]", children: t('No contacts found') })) : (filteredContacts.map(contact => {
|
|
109
109
|
const isSelected = selectedUsers.some(u => u.UserID === contact.UserID);
|
|
110
110
|
return ((0, jsx_runtime_1.jsxs)("button", { onClick: () => toggleUser(contact), className: (0, utils_1.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: [(0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.cn)('w-8 h-8 rounded-full flex items-center justify-center text-white text-xs font-medium flex-shrink-0', (0, conversation_list_1.getAvatarColor)(contact.UserID)), children: (0, conversation_list_1.getInitials)(contact.UserName) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0 text-left", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm font-medium text-[rgb(var(--fg-default))] truncate", children: contact.UserName }), contact.Designation && ((0, jsx_runtime_1.jsx)("p", { className: "text-xs text-[rgb(var(--fg-muted))] truncate", children: contact.Designation }))] }), isSelected && ((0, jsx_runtime_1.jsx)(lucide_react_1.Check, { className: "w-4 h-4 text-[rgb(var(--color-primary))] flex-shrink-0" }))] }, contact.UserID));
|
|
111
111
|
})) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-end gap-2 px-5 py-3 border-t border-[rgb(var(--bd-default))]", children: [(0, jsx_runtime_1.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') }), (0, jsx_runtime_1.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') })] })] }) }));
|
|
@@ -146,7 +146,7 @@ function MessageInput({ onSend, onUploadFile, onTyping, replyTo, onCancelReply,
|
|
|
146
146
|
return prev.filter((_, i) => i !== idx);
|
|
147
147
|
});
|
|
148
148
|
}, []);
|
|
149
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex-shrink-0 border-t border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))]", children: [replyTo && ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.Reply, { className: "w-4 h-4 text-[rgb(var(--color-primary))] flex-shrink-0" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xs font-medium text-[rgb(var(--color-primary))]", children: t('Replying to message') }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-[rgb(var(--fg-muted))] truncate", children: replyTo.Content })] }), (0, jsx_runtime_1.jsx)("button", { onClick: onCancelReply, className: "flex-shrink-0 text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))]", children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-4 h-4" }) })] })), pendingFiles.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "flex gap-2 px-4 py-2 overflow-x-auto", children: pendingFiles.map((f, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "relative flex-shrink-0", children: [f.preview ? ((0, jsx_runtime_1.jsx)("img", { src: f.preview, alt: f.file.name, className: "w-16 h-16 rounded-lg object-cover border border-[rgb(var(--bd-default))]" })) : ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.FileIcon, { className: "w-5 h-5 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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() })] })), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-3 h-3" }) })] }, i))) })), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-end gap-2 px-3 py-2", children: [(0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.Paperclip, { className: "w-5 h-5" }) }), (0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", onChange: handleFileSelect, accept: "image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt,.csv,.zip,.rar" }), (0, jsx_runtime_1.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-
|
|
149
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex-shrink-0 border-t border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))]", children: [replyTo && ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.Reply, { className: "w-4 h-4 text-[rgb(var(--color-primary))] flex-shrink-0" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-xs font-medium text-[rgb(var(--color-primary))]", children: t('Replying to message') }), (0, jsx_runtime_1.jsx)("p", { className: "text-xs text-[rgb(var(--fg-muted))] truncate", children: replyTo.Content })] }), (0, jsx_runtime_1.jsx)("button", { onClick: onCancelReply, className: "flex-shrink-0 text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))]", children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-4 h-4" }) })] })), pendingFiles.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "flex gap-2 px-4 py-2 overflow-x-auto", children: pendingFiles.map((f, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "relative flex-shrink-0", children: [f.preview ? ((0, jsx_runtime_1.jsx)("img", { src: f.preview, alt: f.file.name, className: "w-16 h-16 rounded-lg object-cover border border-[rgb(var(--bd-default))]" })) : ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.FileIcon, { className: "w-5 h-5 text-[rgb(var(--fg-muted))]" }), (0, jsx_runtime_1.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() })] })), (0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "w-3 h-3" }) })] }, i))) })), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-end gap-2 px-3 py-2", children: [(0, jsx_runtime_1.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: (0, jsx_runtime_1.jsx)(lucide_react_1.Paperclip, { className: "w-5 h-5" }) }), (0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", onChange: handleFileSelect, accept: "image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt,.csv,.zip,.rar" }), (0, jsx_runtime_1.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 && ((0, jsx_runtime_1.jsx)("button", { onClick: handleVoiceInput, disabled: disabled || uploading, className: (0, utils_1.cn)('flex-shrink-0 w-9 h-9 rounded-lg flex items-center justify-center transition-colors', isListening
|
|
150
150
|
? 'text-red-500 bg-red-500/10 animate-pulse'
|
|
151
151
|
: 'text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))]', 'disabled:opacity-50'), children: isListening ? (0, jsx_runtime_1.jsx)(lucide_react_1.MicOff, { className: "w-5 h-5" }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Mic, { className: "w-5 h-5" }) })), (0, jsx_runtime_1.jsx)("button", { onClick: handleSubmit, disabled: disabled || uploading || isListening || (!text.trim() && pendingFiles.length === 0), className: (0, utils_1.cn)('flex-shrink-0 w-9 h-9 rounded-lg flex items-center justify-center transition-colors', text.trim() || pendingFiles.length > 0
|
|
152
152
|
? 'bg-[rgb(var(--color-primary))] text-white hover:opacity-90'
|
|
@@ -562,7 +562,7 @@ function ImageModal({ isOpen: controlledIsOpen, onClose: controlledOnClose, titl
|
|
|
562
562
|
? 'h-[95vh] max-w-[92vw]'
|
|
563
563
|
: 'w-auto max-w-[95vw] max-h-[95vh]'}`, style: isZoomMode && computedModalWidth ? { width: `${computedModalWidth}px` } : undefined, hideCloseButton: true, children: [cleanMode ? ((0, jsx_runtime_1.jsx)(ui_1.DialogTitle, { className: "sr-only", children: title || 'Preview' })) : ((0, jsx_runtime_1.jsx)(ui_1.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: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [(0, jsx_runtime_1.jsx)(ui_1.DialogTitle, { className: "flex-shrink-0 mr-auto", children: title }), isZoomMode && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1 flex-shrink-0", children: [(0, jsx_runtime_1.jsx)("button", { className: zoomBtn, onClick: zoomOut, disabled: zoomScale <= MIN_SCALE, title: t('Zoom Out'), children: (0, jsx_runtime_1.jsx)(lucide_react_1.Minus, { className: "h-3.5 w-3.5" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "relative", ref: zoomPresetsRef, children: [(0, jsx_runtime_1.jsxs)("button", { className: `${zoomBtnActive} min-w-[3.5rem] gap-1`, onClick: () => setShowZoomPresets(!showZoomPresets), title: t('Zoom Level'), children: [physicalPercent, "%"] }), showZoomPresets && ((0, jsx_runtime_1.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) => ((0, jsx_runtime_1.jsxs)("button", { className: `w-full text-left px-3 py-1.5 text-xs hover:bg-[rgb(var(--bg-subtle))] transition-colors ${physicalPercent === preset
|
|
564
564
|
? 'text-[rgb(var(--color-primary))] font-medium'
|
|
565
|
-
: 'text-[rgb(var(--fg-default))]'}`, onClick: () => { setZoomLevel(preset / 100); setShowZoomPresets(false); }, children: [preset, "%"] }, preset))) }))] }), (0, jsx_runtime_1.jsx)("button", { className: zoomBtn, onClick: zoomIn, disabled: zoomScale >= MAX_SCALE, title: t('Zoom In'), children: (0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { className: "h-3.5 w-3.5" }) }), (0, jsx_runtime_1.jsx)("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), (0, jsx_runtime_1.jsxs)("button", { className: zoomBtn, onClick: fitToPage, title: t('Fit to Page'), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Maximize, { className: "h-3.5 w-3.5" }), (0, jsx_runtime_1.jsx)("span", { className: "ml-1 hidden sm:inline", children: t('Fit Page') })] }), (0, jsx_runtime_1.jsxs)("button", { className: zoomBtn, onClick: toggleFullScreen, title: t('Full Screen'), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Maximize2, { className: "h-3.5 w-3.5" }), (0, jsx_runtime_1.jsx)("span", { className: "ml-1 hidden sm:inline", children: t('Full Screen') })] }), mmScale && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), (0, jsx_runtime_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 && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isZoomMode && (0, jsx_runtime_1.jsx)("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: extraHeaderButtons })] })), (0, jsx_runtime_1.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-
|
|
565
|
+
: 'text-[rgb(var(--fg-default))]'}`, onClick: () => { setZoomLevel(preset / 100); setShowZoomPresets(false); }, children: [preset, "%"] }, preset))) }))] }), (0, jsx_runtime_1.jsx)("button", { className: zoomBtn, onClick: zoomIn, disabled: zoomScale >= MAX_SCALE, title: t('Zoom In'), children: (0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { className: "h-3.5 w-3.5" }) }), (0, jsx_runtime_1.jsx)("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), (0, jsx_runtime_1.jsxs)("button", { className: zoomBtn, onClick: fitToPage, title: t('Fit to Page'), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Maximize, { className: "h-3.5 w-3.5" }), (0, jsx_runtime_1.jsx)("span", { className: "ml-1 hidden sm:inline", children: t('Fit Page') })] }), (0, jsx_runtime_1.jsxs)("button", { className: zoomBtn, onClick: toggleFullScreen, title: t('Full Screen'), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Maximize2, { className: "h-3.5 w-3.5" }), (0, jsx_runtime_1.jsx)("span", { className: "ml-1 hidden sm:inline", children: t('Full Screen') })] }), mmScale && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), (0, jsx_runtime_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 && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isZoomMode && (0, jsx_runtime_1.jsx)("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))] mx-1" }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: extraHeaderButtons })] })), (0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-4 w-4 text-[rgb(var(--color-icon))]" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: "Close" })] })] }) })), !cleanMode && details && details.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "px-6 py-2 bg-[rgb(var(--bg-subtle))] border-b border-[rgb(var(--bd-default))] flex-shrink-0", children: (0, jsx_runtime_1.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) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5", children: [(0, jsx_runtime_1.jsxs)("span", { className: "font-medium text-[rgb(var(--fg-muted))]", children: [detail.label, ":"] }), (0, jsx_runtime_1.jsx)("span", { className: "font-normal", children: detail.value })] }, index))) }) })), isPdfMode && pdfUrl ? ((0, jsx_runtime_1.jsx)("div", { className: "flex-1 bg-[rgb(var(--bg-subtle))] overflow-hidden p-0", style: { minHeight: 0 }, children: (0, jsx_runtime_1.jsx)("embed", { src: pdfUrl, type: "application/pdf", className: "w-full h-full", style: { border: 'none' } }) })) : isZoomMode ? (
|
|
566
566
|
// Zoomable SVG Mode - uses native overflow scroll + CSS scale for zoom
|
|
567
567
|
(0, jsx_runtime_1.jsx)("div", { ref: scrollContainerRef, className: "flex-1 bg-[rgb(var(--bg-subtle))] overflow-auto relative", style: { minHeight: 0 }, children: (0, jsx_runtime_1.jsx)("div", { style: {
|
|
568
568
|
width: zoomScale <= 1 ? '100%' : `${zoomScale * 100}%`,
|
|
@@ -312,7 +312,7 @@ const ModalContent = React.forwardRef(({ className, children, hideCloseButton, d
|
|
|
312
312
|
if (disableOutsideClick || (hasOpenChild && hasOpenChild.current > 0)) {
|
|
313
313
|
e.preventDefault();
|
|
314
314
|
}
|
|
315
|
-
}, onEscapeKeyDown: handleEscapeKeyDown, ...props, children: [children, !hideCloseButton && ((0, jsx_runtime_1.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-
|
|
315
|
+
}, onEscapeKeyDown: handleEscapeKeyDown, ...props, children: [children, !hideCloseButton && ((0, jsx_runtime_1.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: [(0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-4 w-4 sm:h-5 sm:w-5 text-[rgb(var(--color-icon))]" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: "Close" })] }))] })] }));
|
|
316
316
|
});
|
|
317
317
|
exports.ModalContent = ModalContent;
|
|
318
318
|
ModalContent.displayName = DialogPrimitive.Content.displayName;
|
|
@@ -175,7 +175,7 @@ const Button = React.forwardRef(({ className, variant = 'primary', size = 'md',
|
|
|
175
175
|
if (iconOnly) {
|
|
176
176
|
// For icon-only buttons, use ghost variant by default if not specified
|
|
177
177
|
const iconOnlyVariant = variant === 'primary' ? 'ghost' : variant;
|
|
178
|
-
return ((0, jsx_runtime_1.jsx)("button", { ref: ref, type: "button", title: tooltip, disabled: isDisabled, className: (0, utils_1.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-
|
|
178
|
+
return ((0, jsx_runtime_1.jsx)("button", { ref: ref, type: "button", title: tooltip, disabled: isDisabled, className: (0, utils_1.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' && [
|
|
179
179
|
'text-[rgb(var(--fg-muted))]',
|
|
180
180
|
'hover:bg-[rgb(var(--bg-hover))]',
|
|
181
181
|
'active:bg-[rgb(var(--bg-subtle))]'
|
|
@@ -43,5 +43,5 @@ function FormToggle({ isExpanded, onToggle, title, createTitle = 'Create New Rec
|
|
|
43
43
|
else {
|
|
44
44
|
onToggle(false);
|
|
45
45
|
}
|
|
46
|
-
}, 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-
|
|
46
|
+
}, 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: [(0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-5 w-5 text-[rgb(var(--color-icon))]" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: "Close" })] }))] })] }), isExpanded && ((0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.cn)("px-6 pb-4 pt-2 space-y-4 animate-in slide-in-from-top duration-200", contentClassName), children: children }))] }));
|
|
47
47
|
}
|
|
@@ -84,7 +84,7 @@ const Input = React.forwardRef(({ className, type = "text", label, error, helper
|
|
|
84
84
|
};
|
|
85
85
|
// Compact mode - just return the input without wrapper
|
|
86
86
|
if (compact) {
|
|
87
|
-
return ((0, jsx_runtime_1.jsx)("input", { id: inputId, name: inputName, type: type, className: (0, utils_1.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-
|
|
87
|
+
return ((0, jsx_runtime_1.jsx)("input", { id: inputId, name: inputName, type: type, className: (0, utils_1.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",
|
|
88
88
|
// Joined group styling
|
|
89
89
|
position === 'first' && "rounded-l border-r-0", position === 'middle' && "border-r-0", position === 'last' && "rounded-r", position === 'only' && "rounded", !position && "rounded",
|
|
90
90
|
// Edited field highlighting
|
|
@@ -94,10 +94,10 @@ const Input = React.forwardRef(({ className, type = "text", label, error, helper
|
|
|
94
94
|
? "border-[rgb(var(--color-danger))] focus:border-[rgb(var(--color-danger))]"
|
|
95
95
|
: isEdited
|
|
96
96
|
? "border-[rgb(var(--color-warning))] focus:border-[rgb(var(--color-warning))] focus:ring-[rgb(var(--color-warning))]/20 focus:z-10"
|
|
97
|
-
: "border-[rgb(var(--bd-default))] focus:border-[rgb(var(--color-
|
|
97
|
+
: "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 }));
|
|
98
98
|
}
|
|
99
99
|
// Standard mode with wrapper
|
|
100
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-full", children: [label && ((0, jsx_runtime_1.jsx)("label", { htmlFor: inputId, className: "block text-xs font-medium text-[rgb(var(--fg-default))] mb-1.5", suppressHydrationWarning: true, children: label })), (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [LeftIcon && ((0, jsx_runtime_1.jsx)("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2", children: (0, jsx_runtime_1.jsx)(LeftIcon, { className: "h-4 w-4 text-[rgb(var(--fg-muted))]" }) })), (0, jsx_runtime_1.jsx)("input", { id: inputId, name: inputName, type: type, className: (0, utils_1.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-
|
|
100
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-full", children: [label && ((0, jsx_runtime_1.jsx)("label", { htmlFor: inputId, className: "block text-xs font-medium text-[rgb(var(--fg-default))] mb-1.5", suppressHydrationWarning: true, children: label })), (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [LeftIcon && ((0, jsx_runtime_1.jsx)("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2", children: (0, jsx_runtime_1.jsx)(LeftIcon, { className: "h-4 w-4 text-[rgb(var(--fg-muted))]" }) })), (0, jsx_runtime_1.jsx)("input", { id: inputId, name: inputName, type: type, className: (0, utils_1.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",
|
|
101
101
|
// Edited field highlighting
|
|
102
102
|
isEdited && !props.disabled && "bg-[rgb(var(--color-warning-subtle))] border-[rgb(var(--color-warning))]",
|
|
103
103
|
// Border color
|
|
@@ -105,7 +105,7 @@ const Input = React.forwardRef(({ className, type = "text", label, error, helper
|
|
|
105
105
|
? "border-[rgb(var(--color-danger))] focus:border-[rgb(var(--color-danger))]"
|
|
106
106
|
: isEdited
|
|
107
107
|
? "border-[rgb(var(--color-warning))] focus:border-[rgb(var(--color-warning))] focus:ring-[rgb(var(--color-warning))]/20"
|
|
108
|
-
: "border-[rgb(var(--bd-default))] focus:border-[rgb(var(--color-
|
|
108
|
+
: "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 && ((0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.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: (0, jsx_runtime_1.jsx)(RightIcon, { className: "h-4 w-4 text-[rgb(var(--fg-muted))]" }) }))] }), error && typeof error === 'string' && ((0, jsx_runtime_1.jsx)("p", { className: "mt-1 text-sm text-[rgb(var(--color-danger))]", children: error })), helper && !error && ((0, jsx_runtime_1.jsx)("p", { className: "mt-1 text-sm text-[rgb(var(--fg-muted))]", children: helper }))] }));
|
|
109
109
|
});
|
|
110
110
|
exports.Input = Input;
|
|
111
111
|
Input.displayName = "Input";
|