@burdenoff/microfe-proserviceworld 2026.525.1 → 2026.625.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/proserviceworld/pages/AdminReportsPage.js +368 -335
  2. package/dist/proserviceworld/pages/AdminReportsPage.js.map +1 -1
  3. package/dist/proserviceworld/pages/AdminUsersPage.js +262 -242
  4. package/dist/proserviceworld/pages/AdminUsersPage.js.map +1 -1
  5. package/dist/proserviceworld/pages/AnalyticsPage.js +346 -318
  6. package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
  7. package/dist/proserviceworld/pages/BookingsPage.js +202 -185
  8. package/dist/proserviceworld/pages/BookingsPage.js.map +1 -1
  9. package/dist/proserviceworld/pages/DashboardPage.js +400 -363
  10. package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
  11. package/dist/proserviceworld/pages/DocumentsPage.js +389 -324
  12. package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
  13. package/dist/proserviceworld/pages/MessagesPage.js +77 -82
  14. package/dist/proserviceworld/pages/MessagesPage.js.map +1 -1
  15. package/dist/proserviceworld/pages/PaymentsPage.js +373 -346
  16. package/dist/proserviceworld/pages/PaymentsPage.js.map +1 -1
  17. package/dist/proserviceworld/pages/ProjectsPage.js +432 -385
  18. package/dist/proserviceworld/pages/ProjectsPage.js.map +1 -1
  19. package/dist/proserviceworld/pages/ProviderDetailPage.js +396 -352
  20. package/dist/proserviceworld/pages/ProviderDetailPage.js.map +1 -1
  21. package/dist/proserviceworld/pages/ProvidersPage.js +245 -244
  22. package/dist/proserviceworld/pages/ProvidersPage.js.map +1 -1
  23. package/dist/proserviceworld/pages/ReviewsPage.js +31 -31
  24. package/dist/proserviceworld/pages/ReviewsPage.js.map +1 -1
  25. package/dist/proserviceworld/pages/ServiceDetailsPage.js +349 -316
  26. package/dist/proserviceworld/pages/ServiceDetailsPage.js.map +1 -1
  27. package/dist/proserviceworld/pages/ServicesPage.js +163 -160
  28. package/dist/proserviceworld/pages/ServicesPage.js.map +1 -1
  29. package/dist/proserviceworld/pages/VerificationPage.js +265 -256
  30. package/dist/proserviceworld/pages/VerificationPage.js.map +1 -1
  31. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/DocumentsPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n FolderOpen,\n FileText,\n File,\n Image,\n Upload,\n Plus,\n Grid3x3,\n List,\n Star,\n Download,\n Share2,\n MoreHorizontal,\n ArrowUpDown,\n ChevronRight,\n FolderPlus,\n Users,\n Clock,\n HardDrive,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\n\ntype ViewMode = 'grid' | 'list';\ntype SortBy = 'name' | 'date' | 'size';\ntype FileFilter = 'all' | 'pdf' | 'docx' | 'txt' | 'image' | 'starred';\n\nconst fileTypeIcons: Record<string, typeof FileText> = {\n pdf: FileText,\n docx: File,\n doc: File,\n txt: FileText,\n image: Image,\n video: File,\n audio: File,\n other: File,\n};\n\nconst fileTypeColors: Record<string, string> = {\n pdf: 'text-red-500',\n docx: 'text-blue-500',\n doc: 'text-blue-500',\n txt: 'text-gray-500',\n image: 'text-green-500',\n video: 'text-purple-500',\n audio: 'text-orange-500',\n other: 'text-gray-400',\n};\n\nconst folderColors: Record<string, string> = {\n blue: 'text-blue-500',\n green: 'text-green-500',\n purple: 'text-purple-500',\n yellow: 'text-yellow-500',\n red: 'text-red-500',\n};\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport function DocumentsPage() {\n const { documents, folders } = useProServiceWorldStore();\n const [viewMode, setViewMode] = useState<ViewMode>('grid');\n const [searchQuery, setSearchQuery] = useState('');\n const [fileFilter, setFileFilter] = useState<FileFilter>('all');\n const [sortBy, setSortBy] = useState<SortBy>('date');\n const [sortAsc, setSortAsc] = useState(false);\n const [selectedFolderId, setSelectedFolderId] = useState<string | null>(null);\n const [showUploadModal, setShowUploadModal] = useState(false);\n const [showCreateFolderModal, setShowCreateFolderModal] = useState(false);\n\n const filteredDocs = useMemo(() => {\n let result = [...documents];\n\n // Folder filter\n if (selectedFolderId) {\n result = result.filter((d) => d.folderId === selectedFolderId);\n }\n\n // Type filter\n if (fileFilter === 'starred') {\n result = result.filter((d) => d.isStarred);\n } else if (fileFilter !== 'all') {\n result = result.filter((d) => d.type === fileFilter);\n }\n\n // Search\n if (searchQuery.trim()) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (d) => d.name.toLowerCase().includes(q) || d.tags.some((t) => t.toLowerCase().includes(q))\n );\n }\n\n // Sort\n result.sort((a, b) => {\n const cmp =\n sortBy === 'name'\n ? a.name.localeCompare(b.name)\n : sortBy === 'date'\n ? new Date(b.modifiedAt).getTime() - new Date(a.modifiedAt).getTime()\n : b.size - a.size;\n return sortAsc ? -cmp : cmp;\n });\n\n return result;\n }, [documents, selectedFolderId, fileFilter, searchQuery, sortBy, sortAsc]);\n\n const totalSize = documents.reduce((s, d) => s + d.size, 0);\n const starredCount = documents.filter((d) => d.isStarred).length;\n const currentFolder = selectedFolderId ? folders.find((f) => f.id === selectedFolderId) : null;\n\n const handleSort = (field: SortBy) => {\n if (sortBy === field) setSortAsc(!sortAsc);\n else {\n setSortBy(field);\n setSortAsc(false);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Documents</h1>\n <p className=\"text-sm text-muted-foreground\">\n Manage files, folders, and shared documents.\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => setShowCreateFolderModal(true)}>\n <FolderPlus className=\"mr-2 h-4 w-4\" /> New Folder\n </Button>\n <Button size=\"sm\" onClick={() => setShowUploadModal(true)}>\n <Upload className=\"mr-2 h-4 w-4\" /> Upload\n </Button>\n </div>\n </div>\n\n {/* Stats */}\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-blue-100 p-2 dark:bg-blue-950\">\n <FileText className=\"h-5 w-5 text-blue-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{documents.length}</p>\n <p className=\"text-xs text-muted-foreground\">Total Files</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-purple-100 p-2 dark:bg-purple-950\">\n <FolderOpen className=\"h-5 w-5 text-purple-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{folders.length}</p>\n <p className=\"text-xs text-muted-foreground\">Folders</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-yellow-100 p-2 dark:bg-yellow-950\">\n <Star className=\"h-5 w-5 text-yellow-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{starredCount}</p>\n <p className=\"text-xs text-muted-foreground\">Starred</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-green-100 p-2 dark:bg-green-950\">\n <HardDrive className=\"h-5 w-5 text-green-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{formatFileSize(totalSize)}</p>\n <p className=\"text-xs text-muted-foreground\">Total Size</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n {/* Breadcrumb */}\n <div className=\"flex items-center gap-2 text-sm\">\n <button\n onClick={() => setSelectedFolderId(null)}\n className={`font-medium ${!selectedFolderId ? 'text-primary' : 'text-muted-foreground hover:text-foreground'}`}\n >\n All Files\n </button>\n {currentFolder && (\n <>\n <ChevronRight className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"font-medium text-primary\">{currentFolder.name}</span>\n </>\n )}\n </div>\n\n {/* Search, Filters, View Toggle */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n placeholder=\"Search documents...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex flex-wrap gap-1\">\n {(['all', 'pdf', 'docx', 'txt', 'starred'] as FileFilter[]).map((filter) => (\n <button\n key={filter}\n onClick={() => setFileFilter(filter)}\n className={`rounded px-2 py-1 text-xs font-medium transition-colors ${\n fileFilter === filter\n ? 'bg-primary text-primary-foreground'\n : 'bg-muted text-muted-foreground hover:bg-muted/80'\n }`}\n >\n {filter === 'all' ? 'All' : filter === 'starred' ? 'Starred' : filter.toUpperCase()}\n </button>\n ))}\n </div>\n <div className=\"flex rounded border\">\n <button\n onClick={() => setViewMode('grid')}\n className={`p-1.5 ${viewMode === 'grid' ? 'bg-primary text-primary-foreground' : 'text-muted-foreground'}`}\n >\n <Grid3x3 className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setViewMode('list')}\n className={`p-1.5 ${viewMode === 'list' ? 'bg-primary text-primary-foreground' : 'text-muted-foreground'}`}\n >\n <List className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n </div>\n\n {/* Sort */}\n <div className=\"flex gap-2\">\n {[\n { field: 'name' as SortBy, label: 'Name' },\n { field: 'date' as SortBy, label: 'Date' },\n { field: 'size' as SortBy, label: 'Size' },\n ].map(({ field, label }) => (\n <button\n key={field}\n onClick={() => handleSort(field)}\n className={`flex items-center gap-1 rounded border px-3 py-1 text-xs ${\n sortBy === field\n ? 'border-primary bg-primary/5 text-primary'\n : 'text-muted-foreground hover:bg-muted/50'\n }`}\n >\n <ArrowUpDown className=\"h-3 w-3\" />\n {label}\n </button>\n ))}\n </div>\n\n {/* Folders section (only on root) */}\n {!selectedFolderId && (\n <div>\n <h3 className=\"mb-3 text-sm font-medium text-muted-foreground\">Folders</h3>\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n {folders.map((folder) => (\n <button\n key={folder.id}\n onClick={() => setSelectedFolderId(folder.id)}\n className=\"flex items-center gap-3 rounded-lg border p-3 text-left transition-colors hover:bg-muted/50\"\n >\n <FolderOpen\n className={`h-8 w-8 ${folderColors[folder.color] ?? 'text-gray-500'}`}\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate font-medium text-sm\">{folder.name}</p>\n <p className=\"text-xs text-muted-foreground\">\n {folder.documentsCount} files\n {folder.isPublic && ' - Public'}\n </p>\n </div>\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* Files */}\n <div>\n <h3 className=\"mb-3 text-sm font-medium text-muted-foreground\">\n Files {filteredDocs.length > 0 && `(${filteredDocs.length})`}\n </h3>\n\n {filteredDocs.length === 0 ? (\n <Card>\n <CardContent className=\"py-12 text-center text-muted-foreground\">\n No files found. Try adjusting your filters.\n </CardContent>\n </Card>\n ) : viewMode === 'grid' ? (\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\">\n {filteredDocs.map((doc) => {\n const TypeIcon = fileTypeIcons[doc.type] ?? File;\n return (\n <Card key={doc.id} className=\"hover:bg-muted/30 transition-colors\">\n <CardContent className=\"pt-4\">\n <div className=\"flex items-start justify-between\">\n <TypeIcon\n className={`h-10 w-10 ${fileTypeColors[doc.type] ?? 'text-gray-400'}`}\n />\n <div className=\"flex items-center gap-1\">\n {doc.isStarred && (\n <Star className=\"h-4 w-4 fill-yellow-400 text-yellow-400\" />\n )}\n {doc.sharedWith > 0 && <Share2 className=\"h-4 w-4 text-muted-foreground\" />}\n </div>\n </div>\n <h4 className=\"mt-3 truncate font-medium text-sm\">{doc.name}</h4>\n <div className=\"mt-1 flex items-center gap-2 text-xs text-muted-foreground\">\n <span>{formatFileSize(doc.size)}</span>\n <span>v{doc.version}</span>\n </div>\n <div className=\"mt-2 flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" /> {doc.modifiedAt}\n </div>\n <div className=\"mt-3 flex gap-1\">\n <Button variant=\"outline\" size=\"sm\" className=\"flex-1 text-xs\">\n <Download className=\"mr-1 h-3 w-3\" /> Download\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <MoreHorizontal className=\"h-3 w-3\" />\n </Button>\n </div>\n </CardContent>\n </Card>\n );\n })}\n </div>\n ) : (\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-muted-foreground\">\n <th className=\"p-3\">Name</th>\n <th className=\"p-3\">Type</th>\n <th className=\"p-3\">Size</th>\n <th className=\"p-3\">Modified</th>\n <th className=\"p-3\">Uploaded By</th>\n <th className=\"p-3 text-right\">Actions</th>\n </tr>\n </thead>\n <tbody>\n {filteredDocs.map((doc) => {\n const TypeIcon = fileTypeIcons[doc.type] ?? File;\n return (\n <tr key={doc.id} className=\"border-b hover:bg-muted/50\">\n <td className=\"p-3\">\n <div className=\"flex items-center gap-2\">\n <TypeIcon\n className={`h-5 w-5 ${fileTypeColors[doc.type] ?? 'text-gray-400'}`}\n />\n <span className=\"font-medium\">{doc.name}</span>\n {doc.isStarred && (\n <Star className=\"h-3 w-3 fill-yellow-400 text-yellow-400\" />\n )}\n {doc.sharedWith > 0 && (\n <span className=\"flex items-center gap-0.5 text-xs text-muted-foreground\">\n <Users className=\"h-3 w-3\" /> {doc.sharedWith}\n </span>\n )}\n </div>\n </td>\n <td className=\"p-3 uppercase text-xs\">{doc.type}</td>\n <td className=\"p-3\">{formatFileSize(doc.size)}</td>\n <td className=\"p-3 text-muted-foreground\">{doc.modifiedAt}</td>\n <td className=\"p-3 text-muted-foreground\">{doc.uploadedBy}</td>\n <td className=\"p-3\">\n <div className=\"flex justify-end gap-1\">\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"h-3 w-3\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <Share2 className=\"h-3 w-3\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n\n {/* Upload Modal */}\n {showUploadModal && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\">\n <Card className=\"mx-4 w-full max-w-md\">\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle>Upload Files</CardTitle>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setShowUploadModal(false)}>\n Close\n </Button>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"flex flex-col items-center justify-center rounded-lg border-2 border-dashed p-8\">\n <Upload className=\"h-10 w-10 text-muted-foreground\" />\n <p className=\"mt-2 text-sm font-medium\">Drag & drop files here</p>\n <p className=\"text-xs text-muted-foreground\">or click to browse</p>\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">Destination Folder</label>\n <select className=\"w-full rounded border bg-background px-3 py-2 text-sm\">\n <option value=\"\">Root</option>\n {folders.map((f) => (\n <option key={f.id} value={f.id}>\n {f.name}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n className=\"flex-1\"\n onClick={() => setShowUploadModal(false)}\n >\n Cancel\n </Button>\n <Button className=\"flex-1\">Upload</Button>\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n\n {/* Create Folder Modal */}\n {showCreateFolderModal && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\">\n <Card className=\"mx-4 w-full max-w-md\">\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle>Create Folder</CardTitle>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setShowCreateFolderModal(false)}>\n Close\n </Button>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">Folder Name</label>\n <Input placeholder=\"Enter folder name...\" />\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n className=\"flex-1\"\n onClick={() => setShowCreateFolderModal(false)}\n >\n Cancel\n </Button>\n <Button className=\"flex-1\">Create</Button>\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DocumentsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/DocumentsPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n GlassCard,\n AuroraBackground,\n GradientText,\n CTAOverflowMenu,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n FolderOpen,\n FileText,\n File,\n Image,\n Upload,\n Grid3x3,\n List,\n Star,\n Download,\n Share2,\n MoreHorizontal,\n ArrowUpDown,\n ChevronRight,\n FolderPlus,\n Users,\n Clock,\n HardDrive,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\n\ntype ViewMode = 'grid' | 'list';\ntype SortBy = 'name' | 'date' | 'size';\ntype FileFilter = 'all' | 'pdf' | 'docx' | 'txt' | 'image' | 'starred';\n\nconst fileTypeIcons: Record<string, typeof FileText> = {\n pdf: FileText,\n docx: File,\n doc: File,\n txt: FileText,\n image: Image,\n video: File,\n audio: File,\n other: File,\n};\n\nconst fileTypeColors: Record<string, string> = {\n pdf: 'text-status-error-text',\n docx: 'text-accent-blue',\n doc: 'text-accent-blue',\n txt: 'text-text-secondary',\n image: 'text-status-success-text',\n video: 'text-accent-purple',\n audio: 'text-status-warning-text',\n other: 'text-text-secondary',\n};\n\nconst folderColors: Record<string, string> = {\n blue: 'text-accent-blue',\n green: 'text-status-success-text',\n purple: 'text-accent-purple',\n yellow: 'text-status-warning-text',\n red: 'text-status-error-text',\n};\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport function DocumentsPage() {\n const { documents, folders } = useProServiceWorldStore();\n const [viewMode, setViewMode] = useState<ViewMode>('grid');\n const [searchQuery, setSearchQuery] = useState('');\n const [fileFilter, setFileFilter] = useState<FileFilter>('all');\n const [sortBy, setSortBy] = useState<SortBy>('date');\n const [sortAsc, setSortAsc] = useState(false);\n const [selectedFolderId, setSelectedFolderId] = useState<string | null>(null);\n const [showUploadModal, setShowUploadModal] = useState(false);\n const [showCreateFolderModal, setShowCreateFolderModal] = useState(false);\n\n const filteredDocs = useMemo(() => {\n let result = [...documents];\n\n // Folder filter\n if (selectedFolderId) {\n result = result.filter((d) => d.folderId === selectedFolderId);\n }\n\n // Type filter\n if (fileFilter === 'starred') {\n result = result.filter((d) => d.isStarred);\n } else if (fileFilter !== 'all') {\n result = result.filter((d) => d.type === fileFilter);\n }\n\n // Search\n if (searchQuery.trim()) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (d) => d.name.toLowerCase().includes(q) || d.tags.some((t) => t.toLowerCase().includes(q))\n );\n }\n\n // Sort\n result.sort((a, b) => {\n const cmp =\n sortBy === 'name'\n ? a.name.localeCompare(b.name)\n : sortBy === 'date'\n ? new Date(b.modifiedAt).getTime() - new Date(a.modifiedAt).getTime()\n : b.size - a.size;\n return sortAsc ? -cmp : cmp;\n });\n\n return result;\n }, [documents, selectedFolderId, fileFilter, searchQuery, sortBy, sortAsc]);\n\n const totalSize = documents.reduce((s, d) => s + d.size, 0);\n const starredCount = documents.filter((d) => d.isStarred).length;\n const currentFolder = selectedFolderId ? folders.find((f) => f.id === selectedFolderId) : null;\n\n const handleSort = (field: SortBy) => {\n if (sortBy === field) setSortAsc(!sortAsc);\n else {\n setSortBy(field);\n setSortAsc(false);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 bg-bg-canvas min-h-screen\">\n {/* Hero header — the ONE aurora backdrop for this page. */}\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>Documents</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Manage files, folders, and shared documents.\n </p>\n </div>\n <CTAOverflowMenu\n primary={{\n label: 'Upload',\n onSelect: () => setShowUploadModal(true),\n icon: <Upload className=\"h-4 w-4\" />,\n }}\n actions={[\n {\n label: 'New Folder',\n onSelect: () => setShowCreateFolderModal(true),\n icon: <FolderPlus className=\"h-4 w-4\" />,\n },\n ]}\n />\n </div>\n </div>\n\n {/* Stats */}\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-accent-blue-subtle p-2\">\n <FileText className=\"h-5 w-5 text-accent-blue\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">{documents.length}</p>\n <p className=\"text-xs text-text-secondary\">Total Files</p>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-accent-purple-subtle p-2\">\n <FolderOpen className=\"h-5 w-5 text-accent-purple\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">{folders.length}</p>\n <p className=\"text-xs text-text-secondary\">Folders</p>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-warning-bg-subtle p-2\">\n <Star className=\"h-5 w-5 text-status-warning-text\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">{starredCount}</p>\n <p className=\"text-xs text-text-secondary\">Starred</p>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-success-bg-subtle p-2\">\n <HardDrive className=\"h-5 w-5 text-status-success-text\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">{formatFileSize(totalSize)}</p>\n <p className=\"text-xs text-text-secondary\">Total Size</p>\n </div>\n </div>\n </CardContent>\n </GlassCard>\n </div>\n\n {/* Breadcrumb */}\n <div className=\"flex items-center gap-2 text-sm\">\n <button\n onClick={() => setSelectedFolderId(null)}\n className={`font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus rounded ${!selectedFolderId ? 'text-accent-blue' : 'text-text-secondary hover:text-text-primary'}`}\n >\n All Files\n </button>\n {currentFolder && (\n <>\n <ChevronRight className=\"h-4 w-4 text-text-secondary\" />\n <span className=\"font-medium text-accent-blue\">{currentFolder.name}</span>\n </>\n )}\n </div>\n\n {/* Search, Filters, View Toggle */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search documents...\"\n aria-label=\"Search documents\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <div className=\"flex flex-wrap gap-1\">\n {(['all', 'pdf', 'docx', 'txt', 'starred'] as FileFilter[]).map((filter) => (\n <button\n key={filter}\n onClick={() => setFileFilter(filter)}\n aria-pressed={fileFilter === filter}\n className={`rounded px-2 py-1 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${\n fileFilter === filter\n ? 'bg-accent-blue text-action-primary-text'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n }`}\n >\n {filter === 'all' ? 'All' : filter === 'starred' ? 'Starred' : filter.toUpperCase()}\n </button>\n ))}\n </div>\n <div className=\"flex rounded border border-border-seam\">\n <button\n onClick={() => setViewMode('grid')}\n aria-label=\"Grid view\"\n aria-pressed={viewMode === 'grid'}\n className={`p-1.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${viewMode === 'grid' ? 'bg-accent-blue text-action-primary-text' : 'text-text-secondary'}`}\n >\n <Grid3x3 className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setViewMode('list')}\n aria-label=\"List view\"\n aria-pressed={viewMode === 'list'}\n className={`p-1.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${viewMode === 'list' ? 'bg-accent-blue text-action-primary-text' : 'text-text-secondary'}`}\n >\n <List className=\"h-4 w-4\" />\n </button>\n </div>\n </div>\n </div>\n\n {/* Sort */}\n <div className=\"flex gap-2\">\n {[\n { field: 'name' as SortBy, label: 'Name' },\n { field: 'date' as SortBy, label: 'Date' },\n { field: 'size' as SortBy, label: 'Size' },\n ].map(({ field, label }) => (\n <button\n key={field}\n onClick={() => handleSort(field)}\n aria-pressed={sortBy === field}\n className={`flex items-center gap-1 rounded border px-3 py-1 text-xs focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${\n sortBy === field\n ? 'border-accent-blue bg-accent-blue-subtle text-accent-blue'\n : 'border-border-seam text-text-secondary hover:text-text-primary'\n }`}\n >\n <ArrowUpDown className=\"h-3 w-3\" />\n {label}\n </button>\n ))}\n </div>\n\n {/* Folders section (only on root) */}\n {!selectedFolderId && (\n <div>\n <h3 className=\"mb-3 text-sm font-medium text-text-secondary\">Folders</h3>\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n {folders.map((folder) => (\n <button\n key={folder.id}\n onClick={() => setSelectedFolderId(folder.id)}\n className=\"flex items-center gap-3 rounded-lg border border-border-seam p-3 text-left transition-shadow hover:shadow-pop focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus\"\n >\n <FolderOpen\n className={`h-8 w-8 ${folderColors[folder.color] ?? 'text-text-secondary'}`}\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate font-medium text-sm\">{folder.name}</p>\n <p className=\"text-xs text-text-secondary\">\n <span className=\"tabular-nums\">{folder.documentsCount}</span> files\n {folder.isPublic && ' - Public'}\n </p>\n </div>\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* Files */}\n <div>\n <h3 className=\"mb-3 text-sm font-medium text-text-secondary\">\n Files {filteredDocs.length > 0 && `(${filteredDocs.length})`}\n </h3>\n\n {filteredDocs.length === 0 ? (\n <Card className=\"border-border-seam\">\n <CardContent className=\"py-6\">\n <IllustratedEmptyState\n illustration={\n searchQuery || fileFilter !== 'all' ? 'empty-search' : 'empty-files'\n }\n title=\"No files found\"\n description=\"Try adjusting your filters or upload a new document.\"\n action={\n <Button size=\"sm\" onClick={() => setShowUploadModal(true)}>\n <Upload className=\"mr-2 h-4 w-4\" /> Upload\n </Button>\n }\n />\n </CardContent>\n </Card>\n ) : viewMode === 'grid' ? (\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\">\n {filteredDocs.map((doc) => {\n const TypeIcon = fileTypeIcons[doc.type] ?? File;\n return (\n <GlassCard\n key={doc.id}\n treatment=\"plain\"\n className=\"border-border-seam transition-shadow hover:shadow-pop\"\n >\n <CardContent className=\"pt-4\">\n <div className=\"flex items-start justify-between\">\n <TypeIcon\n className={`h-10 w-10 ${fileTypeColors[doc.type] ?? 'text-text-secondary'}`}\n />\n <div className=\"flex items-center gap-1\">\n {doc.isStarred && (\n <Star className=\"h-4 w-4 fill-status-warning-text text-status-warning-text\" />\n )}\n {doc.sharedWith > 0 && <Share2 className=\"h-4 w-4 text-text-secondary\" />}\n </div>\n </div>\n <h4 className=\"mt-3 truncate font-medium text-sm\">{doc.name}</h4>\n <div className=\"mt-1 flex items-center gap-2 text-xs text-text-secondary\">\n <span className=\"tabular-nums\">{formatFileSize(doc.size)}</span>\n <span className=\"tabular-nums\">v{doc.version}</span>\n </div>\n <div className=\"mt-2 flex items-center gap-1 text-xs text-text-secondary\">\n <Clock className=\"h-3 w-3\" /> {doc.modifiedAt}\n </div>\n <div className=\"mt-3 flex gap-1\">\n <Button variant=\"outline\" size=\"sm\" className=\"flex-1 text-xs\">\n <Download className=\"mr-1 h-3 w-3\" /> Download\n </Button>\n <Button variant=\"outline\" size=\"sm\" aria-label=\"More actions\">\n <MoreHorizontal className=\"h-3 w-3\" />\n </Button>\n </div>\n </CardContent>\n </GlassCard>\n );\n })}\n </div>\n ) : (\n <Card className=\"border-border-seam\">\n <CardContent className=\"pt-4\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam text-left text-text-secondary\">\n <th className=\"p-3\">Name</th>\n <th className=\"p-3\">Type</th>\n <th className=\"p-3\">Size</th>\n <th className=\"p-3\">Modified</th>\n <th className=\"p-3\">Uploaded By</th>\n <th className=\"p-3 text-right\">Actions</th>\n </tr>\n </thead>\n <tbody>\n {filteredDocs.map((doc) => {\n const TypeIcon = fileTypeIcons[doc.type] ?? File;\n return (\n <tr key={doc.id} className=\"border-b border-border-seam hover:bg-bg-sunken\">\n <td className=\"p-3\">\n <div className=\"flex items-center gap-2\">\n <TypeIcon\n className={`h-5 w-5 ${fileTypeColors[doc.type] ?? 'text-text-secondary'}`}\n />\n <span className=\"font-medium\">{doc.name}</span>\n {doc.isStarred && (\n <Star className=\"h-3 w-3 fill-status-warning-text text-status-warning-text\" />\n )}\n {doc.sharedWith > 0 && (\n <span className=\"flex items-center gap-0.5 text-xs text-text-secondary\">\n <Users className=\"h-3 w-3\" />{' '}\n <span className=\"tabular-nums\">{doc.sharedWith}</span>\n </span>\n )}\n </div>\n </td>\n <td className=\"p-3 uppercase text-xs\">{doc.type}</td>\n <td className=\"p-3 tabular-nums\">{formatFileSize(doc.size)}</td>\n <td className=\"p-3 text-text-secondary\">{doc.modifiedAt}</td>\n <td className=\"p-3 text-text-secondary\">{doc.uploadedBy}</td>\n <td className=\"p-3\">\n <div className=\"flex justify-end gap-1\">\n <Button variant=\"outline\" size=\"sm\" aria-label=\"Download\">\n <Download className=\"h-3 w-3\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\" aria-label=\"Share\">\n <Share2 className=\"h-3 w-3\" />\n </Button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n\n {/* Upload Modal */}\n {showUploadModal && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay\">\n <GlassCard treatment=\"glass\" className=\"mx-4 w-full max-w-md border-border-seam\">\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle>Upload Files</CardTitle>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setShowUploadModal(false)}>\n Close\n </Button>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"flex flex-col items-center justify-center rounded-lg border-2 border-dashed border-border-seam p-8\">\n <Upload className=\"h-10 w-10 text-text-secondary\" />\n <p className=\"mt-2 text-sm font-medium\">Drag & drop files here</p>\n <p className=\"text-xs text-text-secondary\">or click to browse</p>\n </div>\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\" htmlFor=\"upload-folder\">\n Destination Folder\n </label>\n <select\n id=\"upload-folder\"\n className=\"w-full rounded border border-border-seam bg-bg-surface px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus\"\n >\n <option value=\"\">Root</option>\n {folders.map((f) => (\n <option key={f.id} value={f.id}>\n {f.name}\n </option>\n ))}\n </select>\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n className=\"flex-1\"\n onClick={() => setShowUploadModal(false)}\n >\n Cancel\n </Button>\n <Button className=\"flex-1\">Upload</Button>\n </div>\n </CardContent>\n </GlassCard>\n </div>\n )}\n\n {/* Create Folder Modal */}\n {showCreateFolderModal && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay\">\n <GlassCard treatment=\"glass\" className=\"mx-4 w-full max-w-md border-border-seam\">\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle>Create Folder</CardTitle>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setShowCreateFolderModal(false)}>\n Close\n </Button>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\" htmlFor=\"folder-name\">\n Folder Name\n </label>\n <Input id=\"folder-name\" placeholder=\"Enter folder name...\" />\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n className=\"flex-1\"\n onClick={() => setShowCreateFolderModal(false)}\n >\n Cancel\n </Button>\n <Button className=\"flex-1\">Create</Button>\n </div>\n </CardContent>\n </GlassCard>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -4,72 +4,76 @@ import { useMemo as n, useState as r } from "react";
4
4
  import { Check as i, CheckCheck as a, Circle as o, MessageSquare as s, MoreHorizontal as c, Paperclip as l, Phone as u, Search as d, Send as f, Smile as p, Video as m } from "lucide-react";
5
5
  import { useI18n as h } from "@burdenoff/fe-libs/shared/providers/shell";
6
6
  import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
7
- import { Badge as y, Button as b, Input as x } from "@burdenoff/fe-libs/ui";
7
+ import { AuroraBackground as y, Badge as b, Button as x, GradientText as S, IllustratedEmptyState as C, Input as w } from "@burdenoff/fe-libs/ui";
8
8
  //#region src/proserviceworld/pages/MessagesPage.tsx
9
- function S() {
10
- let { t: S } = h(), C = (e, n, r) => t(S, e, n, r), { conversations: w } = e(), [T, E] = r(""), [D, O] = r(w[0]?.id ?? ""), [k, A] = r(""), j = n(() => {
11
- if (!T.trim()) return w;
12
- let e = T.toLowerCase();
13
- return w.filter((t) => t.participantName.toLowerCase().includes(e) || t.lastMessage.toLowerCase().includes(e));
14
- }, [w, T]), M = w.find((e) => e.id === D), N = w.reduce((e, t) => e + t.unreadCount, 0), P = N > 0 ? C("proserviceworld.messages.subtitle.unread", "{{count}} unread messages", { count: N }) : C("proserviceworld.messages.subtitle.caughtUp", "All caught up"), F = (e) => {
9
+ function T() {
10
+ let { t: T } = h(), E = (e, n, r) => t(T, e, n, r), { conversations: D } = e(), [O, k] = r(""), [A, j] = r(D[0]?.id ?? ""), [M, N] = r(""), P = n(() => {
11
+ if (!O.trim()) return D;
12
+ let e = O.toLowerCase();
13
+ return D.filter((t) => t.participantName.toLowerCase().includes(e) || t.lastMessage.toLowerCase().includes(e));
14
+ }, [D, O]), F = D.find((e) => e.id === A), I = D.reduce((e, t) => e + t.unreadCount, 0), L = I > 0 ? E("proserviceworld.messages.subtitle.unread", "{{count}} unread messages", { count: I }) : E("proserviceworld.messages.subtitle.caughtUp", "All caught up"), R = (e) => {
15
15
  let t = new Date(e), n = Math.floor(((/* @__PURE__ */ new Date()).getTime() - t.getTime()) / (1e3 * 60 * 60 * 24));
16
16
  return n === 0 ? t.toLocaleTimeString([], {
17
17
  hour: "2-digit",
18
18
  minute: "2-digit"
19
- }) : n === 1 ? C("proserviceworld.messages.time.yesterday", "Yesterday") : n < 7 ? t.toLocaleDateString([], { weekday: "short" }) : t.toLocaleDateString([], {
19
+ }) : n === 1 ? E("proserviceworld.messages.time.yesterday", "Yesterday") : n < 7 ? t.toLocaleDateString([], { weekday: "short" }) : t.toLocaleDateString([], {
20
20
  month: "short",
21
21
  day: "numeric"
22
22
  });
23
23
  };
24
24
  return /* @__PURE__ */ v("div", {
25
- className: "p-6",
25
+ className: "p-6 bg-bg-canvas min-h-screen",
26
26
  children: [/* @__PURE__ */ v("div", {
27
- className: "mb-6 flex items-center justify-between",
28
- children: [/* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("h1", {
29
- className: "text-2xl font-semibold",
30
- children: C("proserviceworld.messages.title", "Messages")
31
- }), /* @__PURE__ */ _("p", {
32
- className: "text-sm text-muted-foreground",
33
- children: P
34
- })] }), /* @__PURE__ */ v(b, {
35
- size: "sm",
36
- children: [/* @__PURE__ */ _(s, { className: "mr-2 h-4 w-4" }), C("proserviceworld.messages.actions.newMessage", "New Message")]
37
- })]
27
+ className: "relative overflow-hidden rounded-card -mx-2 px-2 pt-1 mb-6 flex items-center justify-between gap-4",
28
+ children: [
29
+ /* @__PURE__ */ _(y, { intensity: "subtle" }),
30
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("h1", {
31
+ className: "text-2xl font-semibold tracking-tight",
32
+ children: /* @__PURE__ */ _(S, { children: E("proserviceworld.messages.title", "Messages") })
33
+ }), /* @__PURE__ */ _("p", {
34
+ className: "text-sm text-text-secondary",
35
+ children: L
36
+ })] }),
37
+ /* @__PURE__ */ v(x, {
38
+ size: "sm",
39
+ children: [/* @__PURE__ */ _(s, { className: "mr-2 h-4 w-4" }), E("proserviceworld.messages.actions.newMessage", "New Message")]
40
+ })
41
+ ]
38
42
  }), /* @__PURE__ */ v("div", {
39
- className: "grid gap-0 overflow-hidden rounded-lg border lg:grid-cols-3",
43
+ className: "grid gap-0 overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-pop lg:grid-cols-3",
40
44
  style: {
41
45
  height: "calc(100vh - 220px)",
42
46
  minHeight: "500px"
43
47
  },
44
48
  children: [/* @__PURE__ */ v("div", {
45
- className: "flex flex-col border-r lg:col-span-1",
49
+ className: "flex flex-col border-r border-border-seam lg:col-span-1",
46
50
  children: [/* @__PURE__ */ _("div", {
47
- className: "border-b p-3",
51
+ className: "border-b border-border-seam p-3",
48
52
  children: /* @__PURE__ */ v("div", {
49
53
  className: "relative",
50
- children: [/* @__PURE__ */ _(d, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), /* @__PURE__ */ _(x, {
51
- placeholder: C("proserviceworld.messages.search.placeholder", "Search conversations..."),
52
- value: T,
53
- onChange: (e) => E(e.target.value),
54
+ children: [/* @__PURE__ */ _(d, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ _(w, {
55
+ placeholder: E("proserviceworld.messages.search.placeholder", "Search conversations..."),
56
+ value: O,
57
+ onChange: (e) => k(e.target.value),
54
58
  className: "pl-10"
55
59
  })]
56
60
  })
57
61
  }), /* @__PURE__ */ _("div", {
58
62
  className: "flex-1 overflow-y-auto",
59
- children: j.length === 0 ? /* @__PURE__ */ _("div", {
60
- className: "p-6 text-center text-sm text-muted-foreground",
61
- children: C("proserviceworld.messages.empty.list", "No conversations found.")
62
- }) : j.map((e) => /* @__PURE__ */ _("button", {
63
- onClick: () => O(e.id),
64
- className: `w-full border-b p-3 text-left transition-colors ${D === e.id ? "bg-primary/5" : "hover:bg-muted/50"}`,
63
+ children: P.length === 0 ? /* @__PURE__ */ _("div", {
64
+ className: "p-6 text-center text-sm text-text-secondary",
65
+ children: E("proserviceworld.messages.empty.list", "No conversations found.")
66
+ }) : P.map((e) => /* @__PURE__ */ _("button", {
67
+ onClick: () => j(e.id),
68
+ className: `w-full border-b border-border-seam p-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-border-focus ${A === e.id ? "bg-accent-soft" : "hover:bg-bg-sunken/50"}`,
65
69
  children: /* @__PURE__ */ v("div", {
66
70
  className: "flex items-start gap-3",
67
71
  children: [/* @__PURE__ */ v("div", {
68
72
  className: "relative shrink-0",
69
73
  children: [/* @__PURE__ */ _("div", {
70
- className: "flex h-10 w-10 items-center justify-center rounded-full bg-primary/10 font-semibold text-primary",
74
+ className: "flex h-10 w-10 items-center justify-center rounded-full bg-accent-soft font-semibold text-text-primary",
71
75
  children: e.participantName.charAt(0)
72
- }), e.online && /* @__PURE__ */ _(o, { className: "absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-green-500 text-green-500 stroke-background" })]
76
+ }), e.online && /* @__PURE__ */ _(o, { className: "absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-status-success-text text-status-success-text stroke-bg-surface motion-safe:animate-vc-glow-pulse" })]
73
77
  }), /* @__PURE__ */ v("div", {
74
78
  className: "min-w-0 flex-1",
75
79
  children: [
@@ -79,20 +83,20 @@ function S() {
79
83
  className: `truncate text-sm ${e.unreadCount > 0 ? "font-bold" : "font-medium"}`,
80
84
  children: e.participantName
81
85
  }), /* @__PURE__ */ _("span", {
82
- className: "shrink-0 text-xs text-muted-foreground",
83
- children: F(e.lastMessageTime)
86
+ className: "shrink-0 text-xs text-text-secondary",
87
+ children: R(e.lastMessageTime)
84
88
  })]
85
89
  }),
86
90
  /* @__PURE__ */ _("p", {
87
- className: "text-xs text-muted-foreground",
91
+ className: "text-xs text-text-secondary",
88
92
  children: e.participantRole
89
93
  }),
90
94
  /* @__PURE__ */ v("div", {
91
95
  className: "mt-1 flex items-center justify-between",
92
96
  children: [/* @__PURE__ */ _("p", {
93
- className: `truncate text-xs ${e.unreadCount > 0 ? "font-medium text-foreground" : "text-muted-foreground"}`,
97
+ className: `truncate text-xs ${e.unreadCount > 0 ? "font-medium text-text-primary" : "text-text-secondary"}`,
94
98
  children: e.lastMessage
95
- }), e.unreadCount > 0 && /* @__PURE__ */ _(y, {
99
+ }), e.unreadCount > 0 && /* @__PURE__ */ _(b, {
96
100
  className: "ml-2 h-5 w-5 shrink-0 rounded-full p-0 text-xs flex items-center justify-center",
97
101
  children: e.unreadCount
98
102
  })]
@@ -104,43 +108,43 @@ function S() {
104
108
  })]
105
109
  }), /* @__PURE__ */ _("div", {
106
110
  className: "flex flex-col lg:col-span-2",
107
- children: M ? /* @__PURE__ */ v(g, { children: [
111
+ children: F ? /* @__PURE__ */ v(g, { children: [
108
112
  /* @__PURE__ */ v("div", {
109
- className: "flex items-center justify-between border-b p-3",
113
+ className: "flex items-center justify-between border-b border-border-seam p-3",
110
114
  children: [/* @__PURE__ */ v("div", {
111
115
  className: "flex items-center gap-3",
112
116
  children: [/* @__PURE__ */ v("div", {
113
117
  className: "relative",
114
118
  children: [/* @__PURE__ */ _("div", {
115
- className: "flex h-10 w-10 items-center justify-center rounded-full bg-primary/10 font-semibold text-primary",
116
- children: M.participantName.charAt(0)
117
- }), M.online && /* @__PURE__ */ _(o, { className: "absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-green-500 text-green-500 stroke-background" })]
119
+ className: "flex h-10 w-10 items-center justify-center rounded-full bg-accent-soft font-semibold text-text-primary",
120
+ children: F.participantName.charAt(0)
121
+ }), F.online && /* @__PURE__ */ _(o, { className: "absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-status-success-text text-status-success-text stroke-bg-surface motion-safe:animate-vc-glow-pulse" })]
118
122
  }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("h3", {
119
123
  className: "font-medium",
120
- children: M.participantName
124
+ children: F.participantName
121
125
  }), /* @__PURE__ */ v("p", {
122
- className: "text-xs text-muted-foreground",
126
+ className: "text-xs text-text-secondary",
123
127
  children: [
124
- M.online ? C("proserviceworld.messages.presence.online", "Online") : C("proserviceworld.messages.presence.offline", "Offline"),
128
+ F.online ? E("proserviceworld.messages.presence.online", "Online") : E("proserviceworld.messages.presence.offline", "Offline"),
125
129
  " ",
126
130
  "- ",
127
- M.participantRole
131
+ F.participantRole
128
132
  ]
129
133
  })] })]
130
134
  }), /* @__PURE__ */ v("div", {
131
135
  className: "flex gap-1",
132
136
  children: [
133
- /* @__PURE__ */ _(b, {
137
+ /* @__PURE__ */ _(x, {
134
138
  variant: "outline",
135
139
  size: "sm",
136
140
  children: /* @__PURE__ */ _(u, { className: "h-4 w-4" })
137
141
  }),
138
- /* @__PURE__ */ _(b, {
142
+ /* @__PURE__ */ _(x, {
139
143
  variant: "outline",
140
144
  size: "sm",
141
145
  children: /* @__PURE__ */ _(m, { className: "h-4 w-4" })
142
146
  }),
143
- /* @__PURE__ */ _(b, {
147
+ /* @__PURE__ */ _(x, {
144
148
  variant: "outline",
145
149
  size: "sm",
146
150
  children: /* @__PURE__ */ _(c, { className: "h-4 w-4" })
@@ -150,73 +154,64 @@ function S() {
150
154
  }),
151
155
  /* @__PURE__ */ _("div", {
152
156
  className: "flex-1 overflow-y-auto p-4 space-y-4",
153
- children: M.messages.map((e) => /* @__PURE__ */ _("div", {
157
+ children: F.messages.map((e) => /* @__PURE__ */ _("div", {
154
158
  className: `flex ${e.isOwn ? "justify-end" : "justify-start"}`,
155
159
  children: /* @__PURE__ */ v("div", {
156
160
  className: `flex max-w-[75%] items-end gap-2 ${e.isOwn ? "flex-row-reverse" : ""}`,
157
161
  children: [!e.isOwn && /* @__PURE__ */ _("div", {
158
- className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary/10 text-xs font-semibold text-primary",
162
+ className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-accent-soft text-xs font-semibold text-text-primary",
159
163
  children: e.senderName.charAt(0)
160
164
  }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("div", {
161
- className: `rounded-2xl px-4 py-2 ${e.isOwn ? "bg-primary text-primary-foreground rounded-br-md" : "bg-muted rounded-bl-md"}`,
165
+ className: `rounded-2xl px-4 py-2 ${e.isOwn ? "bg-action-primary-bg text-action-primary-text rounded-br-md" : "bg-bg-sunken rounded-bl-md"}`,
162
166
  children: /* @__PURE__ */ _("p", {
163
167
  className: "text-sm",
164
168
  children: e.content
165
169
  })
166
170
  }), /* @__PURE__ */ v("div", {
167
- className: `mt-1 flex items-center gap-1 text-xs text-muted-foreground ${e.isOwn ? "justify-end" : ""}`,
168
- children: [/* @__PURE__ */ _("span", { children: F(e.timestamp) }), e.isOwn && (e.read ? /* @__PURE__ */ _(a, { className: "h-3 w-3 text-blue-500" }) : /* @__PURE__ */ _(i, { className: "h-3 w-3" }))]
171
+ className: `mt-1 flex items-center gap-1 text-xs text-text-secondary ${e.isOwn ? "justify-end" : ""}`,
172
+ children: [/* @__PURE__ */ _("span", { children: R(e.timestamp) }), e.isOwn && (e.read ? /* @__PURE__ */ _(a, { className: "h-3 w-3 text-accent-blue" }) : /* @__PURE__ */ _(i, { className: "h-3 w-3" }))]
169
173
  })] })]
170
174
  })
171
175
  }, e.id))
172
176
  }),
173
177
  /* @__PURE__ */ _("div", {
174
- className: "border-t p-3",
178
+ className: "border-t border-border-seam p-3",
175
179
  children: /* @__PURE__ */ v("div", {
176
180
  className: "flex items-center gap-2",
177
181
  children: [
178
- /* @__PURE__ */ _(b, {
182
+ /* @__PURE__ */ _(x, {
179
183
  variant: "outline",
180
184
  size: "sm",
181
185
  children: /* @__PURE__ */ _(l, { className: "h-4 w-4" })
182
186
  }),
183
- /* @__PURE__ */ _(x, {
184
- placeholder: C("proserviceworld.messages.input.placeholder", "Type a message..."),
185
- value: k,
186
- onChange: (e) => A(e.target.value),
187
+ /* @__PURE__ */ _(w, {
188
+ placeholder: E("proserviceworld.messages.input.placeholder", "Type a message..."),
189
+ value: M,
190
+ onChange: (e) => N(e.target.value),
187
191
  onKeyDown: (e) => {
188
- e.key === "Enter" && k.trim() && A("");
192
+ e.key === "Enter" && M.trim() && N("");
189
193
  },
190
194
  className: "flex-1"
191
195
  }),
192
- /* @__PURE__ */ _(b, {
196
+ /* @__PURE__ */ _(x, {
193
197
  variant: "outline",
194
198
  size: "sm",
195
199
  children: /* @__PURE__ */ _(p, { className: "h-4 w-4" })
196
200
  }),
197
- /* @__PURE__ */ _(b, {
201
+ /* @__PURE__ */ _(x, {
198
202
  size: "sm",
199
- disabled: !k.trim(),
203
+ disabled: !M.trim(),
200
204
  children: /* @__PURE__ */ _(f, { className: "h-4 w-4" })
201
205
  })
202
206
  ]
203
207
  })
204
208
  })
205
209
  ] }) : /* @__PURE__ */ _("div", {
206
- className: "flex flex-1 items-center justify-center text-muted-foreground",
207
- children: /* @__PURE__ */ v("div", {
208
- className: "text-center",
209
- children: [
210
- /* @__PURE__ */ _(s, { className: "mx-auto h-12 w-12 text-muted-foreground/50" }),
211
- /* @__PURE__ */ _("p", {
212
- className: "mt-2 font-medium",
213
- children: C("proserviceworld.messages.emptyConversation.title", "Select a conversation")
214
- }),
215
- /* @__PURE__ */ _("p", {
216
- className: "text-sm",
217
- children: C("proserviceworld.messages.emptyConversation.description", "Choose a conversation to start messaging.")
218
- })
219
- ]
210
+ className: "flex flex-1 items-center justify-center",
211
+ children: /* @__PURE__ */ _(C, {
212
+ illustration: "empty-notifications",
213
+ title: E("proserviceworld.messages.emptyConversation.title", "Select a conversation"),
214
+ description: E("proserviceworld.messages.emptyConversation.description", "Choose a conversation to start messaging.")
220
215
  })
221
216
  })
222
217
  })]
@@ -224,6 +219,6 @@ function S() {
224
219
  });
225
220
  }
226
221
  //#endregion
227
- export { S as MessagesPage };
222
+ export { T as MessagesPage };
228
223
 
229
224
  //# sourceMappingURL=MessagesPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessagesPage.js","names":[],"sources":["../../../src/proserviceworld/pages/MessagesPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { Badge, Button, Card, CardContent, Input } from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Send,\n Circle,\n CheckCheck,\n Check,\n MessageSquare,\n Phone,\n Video,\n MoreHorizontal,\n Paperclip,\n Smile,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport { tWithFallback } from '../utils/i18n';\n\nexport function MessagesPage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string, params?: Record<string, string | number>): string =>\n tWithFallback(t, key, fallback, params);\n const { conversations } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedConversationId, setSelectedConversationId] = useState<string>(\n conversations[0]?.id ?? ''\n );\n const [messageInput, setMessageInput] = useState('');\n\n const filteredConversations = useMemo(() => {\n if (!searchQuery.trim()) return conversations;\n const q = searchQuery.toLowerCase();\n return conversations.filter(\n (c) => c.participantName.toLowerCase().includes(q) || c.lastMessage.toLowerCase().includes(q)\n );\n }, [conversations, searchQuery]);\n\n const selectedConversation = conversations.find((c) => c.id === selectedConversationId);\n const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);\n const unreadSummary =\n totalUnread > 0\n ? tr('proserviceworld.messages.subtitle.unread', '{{count}} unread messages', {\n count: totalUnread,\n })\n : tr('proserviceworld.messages.subtitle.caughtUp', 'All caught up');\n\n const formatTime = (timestamp: string) => {\n const date = new Date(timestamp);\n const now = new Date();\n const diffDays = Math.floor((now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24));\n if (diffDays === 0) {\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n }\n if (diffDays === 1) return tr('proserviceworld.messages.time.yesterday', 'Yesterday');\n if (diffDays < 7) return date.toLocaleDateString([], { weekday: 'short' });\n return date.toLocaleDateString([], { month: 'short', day: 'numeric' });\n };\n\n return (\n <div className=\"p-6\">\n <div className=\"mb-6 flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n {tr('proserviceworld.messages.title', 'Messages')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">{unreadSummary}</p>\n </div>\n <Button size=\"sm\">\n <MessageSquare className=\"mr-2 h-4 w-4\" />\n {tr('proserviceworld.messages.actions.newMessage', 'New Message')}\n </Button>\n </div>\n\n <div\n className=\"grid gap-0 overflow-hidden rounded-lg border lg:grid-cols-3\"\n style={{ height: 'calc(100vh - 220px)', minHeight: '500px' }}\n >\n {/* Conversation sidebar */}\n <div className=\"flex flex-col border-r lg:col-span-1\">\n {/* Search */}\n <div className=\"border-b p-3\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n placeholder={tr(\n 'proserviceworld.messages.search.placeholder',\n 'Search conversations...'\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n </div>\n\n {/* Conversation list */}\n <div className=\"flex-1 overflow-y-auto\">\n {filteredConversations.length === 0 ? (\n <div className=\"p-6 text-center text-sm text-muted-foreground\">\n {tr('proserviceworld.messages.empty.list', 'No conversations found.')}\n </div>\n ) : (\n filteredConversations.map((conversation) => (\n <button\n key={conversation.id}\n onClick={() => setSelectedConversationId(conversation.id)}\n className={`w-full border-b p-3 text-left transition-colors ${\n selectedConversationId === conversation.id\n ? 'bg-primary/5'\n : 'hover:bg-muted/50'\n }`}\n >\n <div className=\"flex items-start gap-3\">\n {/* Avatar */}\n <div className=\"relative shrink-0\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-full bg-primary/10 font-semibold text-primary\">\n {conversation.participantName.charAt(0)}\n </div>\n {conversation.online && (\n <Circle className=\"absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-green-500 text-green-500 stroke-background\" />\n )}\n </div>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between\">\n <h3\n className={`truncate text-sm ${conversation.unreadCount > 0 ? 'font-bold' : 'font-medium'}`}\n >\n {conversation.participantName}\n </h3>\n <span className=\"shrink-0 text-xs text-muted-foreground\">\n {formatTime(conversation.lastMessageTime)}\n </span>\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {conversation.participantRole}\n </p>\n <div className=\"mt-1 flex items-center justify-between\">\n <p\n className={`truncate text-xs ${conversation.unreadCount > 0 ? 'font-medium text-foreground' : 'text-muted-foreground'}`}\n >\n {conversation.lastMessage}\n </p>\n {conversation.unreadCount > 0 && (\n <Badge className=\"ml-2 h-5 w-5 shrink-0 rounded-full p-0 text-xs flex items-center justify-center\">\n {conversation.unreadCount}\n </Badge>\n )}\n </div>\n </div>\n </div>\n </button>\n ))\n )}\n </div>\n </div>\n\n {/* Chat area */}\n <div className=\"flex flex-col lg:col-span-2\">\n {selectedConversation ? (\n <>\n {/* Chat header */}\n <div className=\"flex items-center justify-between border-b p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"relative\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-full bg-primary/10 font-semibold text-primary\">\n {selectedConversation.participantName.charAt(0)}\n </div>\n {selectedConversation.online && (\n <Circle className=\"absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-green-500 text-green-500 stroke-background\" />\n )}\n </div>\n <div>\n <h3 className=\"font-medium\">{selectedConversation.participantName}</h3>\n <p className=\"text-xs text-muted-foreground\">\n {selectedConversation.online\n ? tr('proserviceworld.messages.presence.online', 'Online')\n : tr('proserviceworld.messages.presence.offline', 'Offline')}{' '}\n - {selectedConversation.participantRole}\n </p>\n </div>\n </div>\n <div className=\"flex gap-1\">\n <Button variant=\"outline\" size=\"sm\">\n <Phone className=\"h-4 w-4\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <Video className=\"h-4 w-4\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n\n {/* Messages area */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {selectedConversation.messages.map((message) => (\n <div\n key={message.id}\n className={`flex ${message.isOwn ? 'justify-end' : 'justify-start'}`}\n >\n <div\n className={`flex max-w-[75%] items-end gap-2 ${message.isOwn ? 'flex-row-reverse' : ''}`}\n >\n {!message.isOwn && (\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary/10 text-xs font-semibold text-primary\">\n {message.senderName.charAt(0)}\n </div>\n )}\n <div>\n <div\n className={`rounded-2xl px-4 py-2 ${\n message.isOwn\n ? 'bg-primary text-primary-foreground rounded-br-md'\n : 'bg-muted rounded-bl-md'\n }`}\n >\n <p className=\"text-sm\">{message.content}</p>\n </div>\n <div\n className={`mt-1 flex items-center gap-1 text-xs text-muted-foreground ${message.isOwn ? 'justify-end' : ''}`}\n >\n <span>{formatTime(message.timestamp)}</span>\n {message.isOwn &&\n (message.read ? (\n <CheckCheck className=\"h-3 w-3 text-blue-500\" />\n ) : (\n <Check className=\"h-3 w-3\" />\n ))}\n </div>\n </div>\n </div>\n </div>\n ))}\n </div>\n\n {/* Message input */}\n <div className=\"border-t p-3\">\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Paperclip className=\"h-4 w-4\" />\n </Button>\n <Input\n placeholder={tr(\n 'proserviceworld.messages.input.placeholder',\n 'Type a message...'\n )}\n value={messageInput}\n onChange={(e) => setMessageInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && messageInput.trim()) {\n setMessageInput('');\n }\n }}\n className=\"flex-1\"\n />\n <Button variant=\"outline\" size=\"sm\">\n <Smile className=\"h-4 w-4\" />\n </Button>\n <Button size=\"sm\" disabled={!messageInput.trim()}>\n <Send className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </>\n ) : (\n <div className=\"flex flex-1 items-center justify-center text-muted-foreground\">\n <div className=\"text-center\">\n <MessageSquare className=\"mx-auto h-12 w-12 text-muted-foreground/50\" />\n <p className=\"mt-2 font-medium\">\n {tr('proserviceworld.messages.emptyConversation.title', 'Select a conversation')}\n </p>\n <p className=\"text-sm\">\n {tr(\n 'proserviceworld.messages.emptyConversation.description',\n 'Choose a conversation to start messaging.'\n )}\n </p>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MessagesPage.js","names":[],"sources":["../../../src/proserviceworld/pages/MessagesPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n Badge,\n Button,\n Input,\n AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Send,\n Circle,\n CheckCheck,\n Check,\n MessageSquare,\n Phone,\n Video,\n MoreHorizontal,\n Paperclip,\n Smile,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport { tWithFallback } from '../utils/i18n';\n\nexport function MessagesPage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string, params?: Record<string, string | number>): string =>\n tWithFallback(t, key, fallback, params);\n const { conversations } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedConversationId, setSelectedConversationId] = useState<string>(\n conversations[0]?.id ?? ''\n );\n const [messageInput, setMessageInput] = useState('');\n\n const filteredConversations = useMemo(() => {\n if (!searchQuery.trim()) return conversations;\n const q = searchQuery.toLowerCase();\n return conversations.filter(\n (c) => c.participantName.toLowerCase().includes(q) || c.lastMessage.toLowerCase().includes(q)\n );\n }, [conversations, searchQuery]);\n\n const selectedConversation = conversations.find((c) => c.id === selectedConversationId);\n const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);\n const unreadSummary =\n totalUnread > 0\n ? tr('proserviceworld.messages.subtitle.unread', '{{count}} unread messages', {\n count: totalUnread,\n })\n : tr('proserviceworld.messages.subtitle.caughtUp', 'All caught up');\n\n const formatTime = (timestamp: string) => {\n const date = new Date(timestamp);\n const now = new Date();\n const diffDays = Math.floor((now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24));\n if (diffDays === 0) {\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n }\n if (diffDays === 1) return tr('proserviceworld.messages.time.yesterday', 'Yesterday');\n if (diffDays < 7) return date.toLocaleDateString([], { weekday: 'short' });\n return date.toLocaleDateString([], { month: 'short', day: 'numeric' });\n };\n\n return (\n <div className=\"p-6 bg-bg-canvas min-h-screen\">\n <div className=\"relative overflow-hidden rounded-card -mx-2 px-2 pt-1 mb-6 flex items-center justify-between gap-4\">\n <AuroraBackground intensity=\"subtle\" />\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <GradientText>{tr('proserviceworld.messages.title', 'Messages')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{unreadSummary}</p>\n </div>\n <Button size=\"sm\">\n <MessageSquare className=\"mr-2 h-4 w-4\" />\n {tr('proserviceworld.messages.actions.newMessage', 'New Message')}\n </Button>\n </div>\n\n <div\n className=\"grid gap-0 overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-pop lg:grid-cols-3\"\n style={{ height: 'calc(100vh - 220px)', minHeight: '500px' }}\n >\n {/* Conversation sidebar */}\n <div className=\"flex flex-col border-r border-border-seam lg:col-span-1\">\n {/* Search */}\n <div className=\"border-b border-border-seam p-3\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder={tr(\n 'proserviceworld.messages.search.placeholder',\n 'Search conversations...'\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n </div>\n\n {/* Conversation list */}\n <div className=\"flex-1 overflow-y-auto\">\n {filteredConversations.length === 0 ? (\n <div className=\"p-6 text-center text-sm text-text-secondary\">\n {tr('proserviceworld.messages.empty.list', 'No conversations found.')}\n </div>\n ) : (\n filteredConversations.map((conversation) => (\n <button\n key={conversation.id}\n onClick={() => setSelectedConversationId(conversation.id)}\n className={`w-full border-b border-border-seam p-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-border-focus ${\n selectedConversationId === conversation.id\n ? 'bg-accent-soft'\n : 'hover:bg-bg-sunken/50'\n }`}\n >\n <div className=\"flex items-start gap-3\">\n {/* Avatar */}\n <div className=\"relative shrink-0\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-full bg-accent-soft font-semibold text-text-primary\">\n {conversation.participantName.charAt(0)}\n </div>\n {conversation.online && (\n <Circle className=\"absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-status-success-text text-status-success-text stroke-bg-surface motion-safe:animate-vc-glow-pulse\" />\n )}\n </div>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between\">\n <h3\n className={`truncate text-sm ${conversation.unreadCount > 0 ? 'font-bold' : 'font-medium'}`}\n >\n {conversation.participantName}\n </h3>\n <span className=\"shrink-0 text-xs text-text-secondary\">\n {formatTime(conversation.lastMessageTime)}\n </span>\n </div>\n <p className=\"text-xs text-text-secondary\">\n {conversation.participantRole}\n </p>\n <div className=\"mt-1 flex items-center justify-between\">\n <p\n className={`truncate text-xs ${conversation.unreadCount > 0 ? 'font-medium text-text-primary' : 'text-text-secondary'}`}\n >\n {conversation.lastMessage}\n </p>\n {conversation.unreadCount > 0 && (\n <Badge className=\"ml-2 h-5 w-5 shrink-0 rounded-full p-0 text-xs flex items-center justify-center\">\n {conversation.unreadCount}\n </Badge>\n )}\n </div>\n </div>\n </div>\n </button>\n ))\n )}\n </div>\n </div>\n\n {/* Chat area */}\n <div className=\"flex flex-col lg:col-span-2\">\n {selectedConversation ? (\n <>\n {/* Chat header */}\n <div className=\"flex items-center justify-between border-b border-border-seam p-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"relative\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-full bg-accent-soft font-semibold text-text-primary\">\n {selectedConversation.participantName.charAt(0)}\n </div>\n {selectedConversation.online && (\n <Circle className=\"absolute -bottom-0.5 -right-0.5 h-3.5 w-3.5 fill-status-success-text text-status-success-text stroke-bg-surface motion-safe:animate-vc-glow-pulse\" />\n )}\n </div>\n <div>\n <h3 className=\"font-medium\">{selectedConversation.participantName}</h3>\n <p className=\"text-xs text-text-secondary\">\n {selectedConversation.online\n ? tr('proserviceworld.messages.presence.online', 'Online')\n : tr('proserviceworld.messages.presence.offline', 'Offline')}{' '}\n - {selectedConversation.participantRole}\n </p>\n </div>\n </div>\n <div className=\"flex gap-1\">\n <Button variant=\"outline\" size=\"sm\">\n <Phone className=\"h-4 w-4\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <Video className=\"h-4 w-4\" />\n </Button>\n <Button variant=\"outline\" size=\"sm\">\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n\n {/* Messages area */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {selectedConversation.messages.map((message) => (\n <div\n key={message.id}\n className={`flex ${message.isOwn ? 'justify-end' : 'justify-start'}`}\n >\n <div\n className={`flex max-w-[75%] items-end gap-2 ${message.isOwn ? 'flex-row-reverse' : ''}`}\n >\n {!message.isOwn && (\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-accent-soft text-xs font-semibold text-text-primary\">\n {message.senderName.charAt(0)}\n </div>\n )}\n <div>\n <div\n className={`rounded-2xl px-4 py-2 ${\n message.isOwn\n ? 'bg-action-primary-bg text-action-primary-text rounded-br-md'\n : 'bg-bg-sunken rounded-bl-md'\n }`}\n >\n <p className=\"text-sm\">{message.content}</p>\n </div>\n <div\n className={`mt-1 flex items-center gap-1 text-xs text-text-secondary ${message.isOwn ? 'justify-end' : ''}`}\n >\n <span>{formatTime(message.timestamp)}</span>\n {message.isOwn &&\n (message.read ? (\n <CheckCheck className=\"h-3 w-3 text-accent-blue\" />\n ) : (\n <Check className=\"h-3 w-3\" />\n ))}\n </div>\n </div>\n </div>\n </div>\n ))}\n </div>\n\n {/* Message input */}\n <div className=\"border-t border-border-seam p-3\">\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" size=\"sm\">\n <Paperclip className=\"h-4 w-4\" />\n </Button>\n <Input\n placeholder={tr(\n 'proserviceworld.messages.input.placeholder',\n 'Type a message...'\n )}\n value={messageInput}\n onChange={(e) => setMessageInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && messageInput.trim()) {\n setMessageInput('');\n }\n }}\n className=\"flex-1\"\n />\n <Button variant=\"outline\" size=\"sm\">\n <Smile className=\"h-4 w-4\" />\n </Button>\n <Button size=\"sm\" disabled={!messageInput.trim()}>\n <Send className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </>\n ) : (\n <div className=\"flex flex-1 items-center justify-center\">\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title={tr('proserviceworld.messages.emptyConversation.title', 'Select a conversation')}\n description={tr(\n 'proserviceworld.messages.emptyConversation.description',\n 'Choose a conversation to start messaging.'\n )}\n />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}