@burdenoff/microfe-proserviceworld 2026.625.1 → 2026.626.2

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 +102 -68
  2. package/dist/proserviceworld/pages/AdminReportsPage.js.map +1 -1
  3. package/dist/proserviceworld/pages/AdminUsersPage.js +37 -33
  4. package/dist/proserviceworld/pages/AdminUsersPage.js.map +1 -1
  5. package/dist/proserviceworld/pages/AnalyticsPage.js +66 -36
  6. package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
  7. package/dist/proserviceworld/pages/BookingsPage.js +52 -48
  8. package/dist/proserviceworld/pages/BookingsPage.js.map +1 -1
  9. package/dist/proserviceworld/pages/DashboardPage.js +275 -243
  10. package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
  11. package/dist/proserviceworld/pages/DocumentsPage.js +204 -200
  12. package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
  13. package/dist/proserviceworld/pages/MessagesPage.js +200 -186
  14. package/dist/proserviceworld/pages/MessagesPage.js.map +1 -1
  15. package/dist/proserviceworld/pages/PaymentsPage.js +70 -39
  16. package/dist/proserviceworld/pages/PaymentsPage.js.map +1 -1
  17. package/dist/proserviceworld/pages/ProjectsPage.js +510 -477
  18. package/dist/proserviceworld/pages/ProjectsPage.js.map +1 -1
  19. package/dist/proserviceworld/pages/ProviderDetailPage.js +71 -41
  20. package/dist/proserviceworld/pages/ProviderDetailPage.js.map +1 -1
  21. package/dist/proserviceworld/pages/ProvidersPage.js +62 -58
  22. package/dist/proserviceworld/pages/ProvidersPage.js.map +1 -1
  23. package/dist/proserviceworld/pages/ReviewsPage.js +80 -63
  24. package/dist/proserviceworld/pages/ReviewsPage.js.map +1 -1
  25. package/dist/proserviceworld/pages/ServiceDetailsPage.js +118 -83
  26. package/dist/proserviceworld/pages/ServiceDetailsPage.js.map +1 -1
  27. package/dist/proserviceworld/pages/ServicesPage.js +134 -130
  28. package/dist/proserviceworld/pages/ServicesPage.js.map +1 -1
  29. package/dist/proserviceworld/pages/VerificationPage.js +23 -19
  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 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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"}
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 PagePurpose,\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 <PagePurpose icon={<FolderOpen className=\"h-4 w-4\" />}>\n A shared home for the files behind your work — contracts, deliverables, briefs, and more.\n Organise documents into folders, star the ones you reach for often, search across\n everything, and share files securely with clients and collaborators.\n </PagePurpose>\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,221 +4,235 @@ 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 { AuroraBackground as y, Badge as b, Button as x, GradientText as S, IllustratedEmptyState as C, Input as w } 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, PagePurpose as T } from "@burdenoff/fe-libs/ui";
8
8
  //#region src/proserviceworld/pages/MessagesPage.tsx
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) => {
9
+ function E() {
10
+ let { t: E } = h(), D = (e, n, r) => t(E, e, n, r), { conversations: O } = e(), [k, A] = r(""), [j, M] = r(O[0]?.id ?? ""), [N, P] = r(""), F = n(() => {
11
+ if (!k.trim()) return O;
12
+ let e = k.toLowerCase();
13
+ return O.filter((t) => t.participantName.toLowerCase().includes(e) || t.lastMessage.toLowerCase().includes(e));
14
+ }, [O, k]), I = O.find((e) => e.id === j), L = O.reduce((e, t) => e + t.unreadCount, 0), R = L > 0 ? D("proserviceworld.messages.subtitle.unread", "{{count}} unread messages", { count: L }) : D("proserviceworld.messages.subtitle.caughtUp", "All caught up"), z = (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 ? E("proserviceworld.messages.time.yesterday", "Yesterday") : n < 7 ? t.toLocaleDateString([], { weekday: "short" }) : t.toLocaleDateString([], {
19
+ }) : n === 1 ? D("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
25
  className: "p-6 bg-bg-canvas min-h-screen",
26
- children: [/* @__PURE__ */ v("div", {
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
- ]
42
- }), /* @__PURE__ */ v("div", {
43
- className: "grid gap-0 overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-pop lg:grid-cols-3",
44
- style: {
45
- height: "calc(100vh - 220px)",
46
- minHeight: "500px"
47
- },
48
- children: [/* @__PURE__ */ v("div", {
49
- className: "flex flex-col border-r border-border-seam lg:col-span-1",
50
- children: [/* @__PURE__ */ _("div", {
51
- className: "border-b border-border-seam p-3",
52
- children: /* @__PURE__ */ v("div", {
53
- className: "relative",
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),
58
- className: "pl-10"
59
- })]
26
+ children: [
27
+ /* @__PURE__ */ v("div", {
28
+ className: "relative overflow-hidden rounded-card -mx-2 px-2 pt-1 mb-6 flex items-center justify-between gap-4",
29
+ children: [
30
+ /* @__PURE__ */ _(y, { intensity: "subtle" }),
31
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("h1", {
32
+ className: "text-2xl font-semibold tracking-tight",
33
+ children: /* @__PURE__ */ _(S, { children: D("proserviceworld.messages.title", "Messages") })
34
+ }), /* @__PURE__ */ _("p", {
35
+ className: "text-sm text-text-secondary",
36
+ children: R
37
+ })] }),
38
+ /* @__PURE__ */ v(x, {
39
+ size: "sm",
40
+ children: [/* @__PURE__ */ _(s, { className: "mr-2 h-4 w-4" }), D("proserviceworld.messages.actions.newMessage", "New Message")]
60
41
  })
61
- }), /* @__PURE__ */ _("div", {
62
- className: "flex-1 overflow-y-auto",
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"}`,
42
+ ]
43
+ }),
44
+ /* @__PURE__ */ _("div", {
45
+ className: "mb-6",
46
+ children: /* @__PURE__ */ _(T, {
47
+ icon: /* @__PURE__ */ _(s, { className: "h-4 w-4" }),
48
+ children: D("proserviceworld.messages.purpose", "Keep every client and provider conversation in one place. Discuss scope, share updates, and coordinate bookings in real time — pick a conversation on the left to read the full thread and reply.")
49
+ })
50
+ }),
51
+ /* @__PURE__ */ v("div", {
52
+ className: "grid gap-0 overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-pop lg:grid-cols-3",
53
+ style: {
54
+ height: "calc(100vh - 220px)",
55
+ minHeight: "500px"
56
+ },
57
+ children: [/* @__PURE__ */ v("div", {
58
+ className: "flex flex-col border-r border-border-seam lg:col-span-1",
59
+ children: [/* @__PURE__ */ _("div", {
60
+ className: "border-b border-border-seam p-3",
69
61
  children: /* @__PURE__ */ v("div", {
70
- className: "flex items-start gap-3",
62
+ className: "relative",
63
+ children: [/* @__PURE__ */ _(d, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ _(w, {
64
+ placeholder: D("proserviceworld.messages.search.placeholder", "Search conversations..."),
65
+ value: k,
66
+ onChange: (e) => A(e.target.value),
67
+ className: "pl-10"
68
+ })]
69
+ })
70
+ }), /* @__PURE__ */ _("div", {
71
+ className: "flex-1 overflow-y-auto",
72
+ children: F.length === 0 ? /* @__PURE__ */ _("div", {
73
+ className: "p-4",
74
+ children: /* @__PURE__ */ _(C, {
75
+ illustration: k ? "empty-search" : "empty-people",
76
+ title: D("proserviceworld.messages.empty.list", "No conversations found"),
77
+ description: k ? D("proserviceworld.messages.empty.listSearch", "No conversations match your search.") : D("proserviceworld.messages.empty.listDescription", "Conversations with clients and providers will appear here.")
78
+ })
79
+ }) : F.map((e) => /* @__PURE__ */ _("button", {
80
+ onClick: () => M(e.id),
81
+ 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 ${j === e.id ? "bg-accent-soft" : "hover:bg-bg-sunken/50"}`,
82
+ children: /* @__PURE__ */ v("div", {
83
+ className: "flex items-start gap-3",
84
+ children: [/* @__PURE__ */ v("div", {
85
+ className: "relative shrink-0",
86
+ children: [/* @__PURE__ */ _("div", {
87
+ className: "flex h-10 w-10 items-center justify-center rounded-full bg-accent-soft font-semibold text-text-primary",
88
+ children: e.participantName.charAt(0)
89
+ }), 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" })]
90
+ }), /* @__PURE__ */ v("div", {
91
+ className: "min-w-0 flex-1",
92
+ children: [
93
+ /* @__PURE__ */ v("div", {
94
+ className: "flex items-center justify-between",
95
+ children: [/* @__PURE__ */ _("h3", {
96
+ className: `truncate text-sm ${e.unreadCount > 0 ? "font-bold" : "font-medium"}`,
97
+ children: e.participantName
98
+ }), /* @__PURE__ */ _("span", {
99
+ className: "shrink-0 text-xs text-text-secondary",
100
+ children: z(e.lastMessageTime)
101
+ })]
102
+ }),
103
+ /* @__PURE__ */ _("p", {
104
+ className: "text-xs text-text-secondary",
105
+ children: e.participantRole
106
+ }),
107
+ /* @__PURE__ */ v("div", {
108
+ className: "mt-1 flex items-center justify-between",
109
+ children: [/* @__PURE__ */ _("p", {
110
+ className: `truncate text-xs ${e.unreadCount > 0 ? "font-medium text-text-primary" : "text-text-secondary"}`,
111
+ children: e.lastMessage
112
+ }), e.unreadCount > 0 && /* @__PURE__ */ _(b, {
113
+ className: "ml-2 h-5 w-5 shrink-0 rounded-full p-0 text-xs flex items-center justify-center",
114
+ children: e.unreadCount
115
+ })]
116
+ })
117
+ ]
118
+ })]
119
+ })
120
+ }, e.id))
121
+ })]
122
+ }), /* @__PURE__ */ _("div", {
123
+ className: "flex flex-col lg:col-span-2",
124
+ children: I ? /* @__PURE__ */ v(g, { children: [
125
+ /* @__PURE__ */ v("div", {
126
+ className: "flex items-center justify-between border-b border-border-seam p-3",
71
127
  children: [/* @__PURE__ */ v("div", {
72
- className: "relative shrink-0",
73
- children: [/* @__PURE__ */ _("div", {
74
- className: "flex h-10 w-10 items-center justify-center rounded-full bg-accent-soft font-semibold text-text-primary",
75
- children: e.participantName.charAt(0)
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" })]
128
+ className: "flex items-center gap-3",
129
+ children: [/* @__PURE__ */ v("div", {
130
+ className: "relative",
131
+ children: [/* @__PURE__ */ _("div", {
132
+ className: "flex h-10 w-10 items-center justify-center rounded-full bg-accent-soft font-semibold text-text-primary",
133
+ children: I.participantName.charAt(0)
134
+ }), I.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" })]
135
+ }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("h3", {
136
+ className: "font-medium",
137
+ children: I.participantName
138
+ }), /* @__PURE__ */ v("p", {
139
+ className: "text-xs text-text-secondary",
140
+ children: [
141
+ I.online ? D("proserviceworld.messages.presence.online", "Online") : D("proserviceworld.messages.presence.offline", "Offline"),
142
+ " ",
143
+ "- ",
144
+ I.participantRole
145
+ ]
146
+ })] })]
77
147
  }), /* @__PURE__ */ v("div", {
78
- className: "min-w-0 flex-1",
148
+ className: "flex gap-1",
79
149
  children: [
80
- /* @__PURE__ */ v("div", {
81
- className: "flex items-center justify-between",
82
- children: [/* @__PURE__ */ _("h3", {
83
- className: `truncate text-sm ${e.unreadCount > 0 ? "font-bold" : "font-medium"}`,
84
- children: e.participantName
85
- }), /* @__PURE__ */ _("span", {
86
- className: "shrink-0 text-xs text-text-secondary",
87
- children: R(e.lastMessageTime)
88
- })]
150
+ /* @__PURE__ */ _(x, {
151
+ variant: "outline",
152
+ size: "sm",
153
+ children: /* @__PURE__ */ _(u, { className: "h-4 w-4" })
89
154
  }),
90
- /* @__PURE__ */ _("p", {
91
- className: "text-xs text-text-secondary",
92
- children: e.participantRole
155
+ /* @__PURE__ */ _(x, {
156
+ variant: "outline",
157
+ size: "sm",
158
+ children: /* @__PURE__ */ _(m, { className: "h-4 w-4" })
93
159
  }),
94
- /* @__PURE__ */ v("div", {
95
- className: "mt-1 flex items-center justify-between",
96
- children: [/* @__PURE__ */ _("p", {
97
- className: `truncate text-xs ${e.unreadCount > 0 ? "font-medium text-text-primary" : "text-text-secondary"}`,
98
- children: e.lastMessage
99
- }), e.unreadCount > 0 && /* @__PURE__ */ _(b, {
100
- className: "ml-2 h-5 w-5 shrink-0 rounded-full p-0 text-xs flex items-center justify-center",
101
- children: e.unreadCount
102
- })]
160
+ /* @__PURE__ */ _(x, {
161
+ variant: "outline",
162
+ size: "sm",
163
+ children: /* @__PURE__ */ _(c, { className: "h-4 w-4" })
103
164
  })
104
165
  ]
105
166
  })]
106
- })
107
- }, e.id))
108
- })]
109
- }), /* @__PURE__ */ _("div", {
110
- className: "flex flex-col lg:col-span-2",
111
- children: F ? /* @__PURE__ */ v(g, { children: [
112
- /* @__PURE__ */ v("div", {
113
- className: "flex items-center justify-between border-b border-border-seam p-3",
114
- children: [/* @__PURE__ */ v("div", {
115
- className: "flex items-center gap-3",
116
- children: [/* @__PURE__ */ v("div", {
117
- className: "relative",
118
- children: [/* @__PURE__ */ _("div", {
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" })]
122
- }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("h3", {
123
- className: "font-medium",
124
- children: F.participantName
125
- }), /* @__PURE__ */ v("p", {
126
- className: "text-xs text-text-secondary",
127
- children: [
128
- F.online ? E("proserviceworld.messages.presence.online", "Online") : E("proserviceworld.messages.presence.offline", "Offline"),
129
- " ",
130
- "- ",
131
- F.participantRole
132
- ]
133
- })] })]
134
- }), /* @__PURE__ */ v("div", {
135
- className: "flex gap-1",
136
- children: [
137
- /* @__PURE__ */ _(x, {
138
- variant: "outline",
139
- size: "sm",
140
- children: /* @__PURE__ */ _(u, { className: "h-4 w-4" })
141
- }),
142
- /* @__PURE__ */ _(x, {
143
- variant: "outline",
144
- size: "sm",
145
- children: /* @__PURE__ */ _(m, { className: "h-4 w-4" })
146
- }),
147
- /* @__PURE__ */ _(x, {
148
- variant: "outline",
149
- size: "sm",
150
- children: /* @__PURE__ */ _(c, { className: "h-4 w-4" })
167
+ }),
168
+ /* @__PURE__ */ _("div", {
169
+ className: "flex-1 overflow-y-auto p-4 space-y-4",
170
+ children: I.messages.map((e) => /* @__PURE__ */ _("div", {
171
+ className: `flex ${e.isOwn ? "justify-end" : "justify-start"}`,
172
+ children: /* @__PURE__ */ v("div", {
173
+ className: `flex max-w-[75%] items-end gap-2 ${e.isOwn ? "flex-row-reverse" : ""}`,
174
+ children: [!e.isOwn && /* @__PURE__ */ _("div", {
175
+ className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-accent-soft text-xs font-semibold text-text-primary",
176
+ children: e.senderName.charAt(0)
177
+ }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("div", {
178
+ 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"}`,
179
+ children: /* @__PURE__ */ _("p", {
180
+ className: "text-sm",
181
+ children: e.content
182
+ })
183
+ }), /* @__PURE__ */ v("div", {
184
+ className: `mt-1 flex items-center gap-1 text-xs text-text-secondary ${e.isOwn ? "justify-end" : ""}`,
185
+ children: [/* @__PURE__ */ _("span", { children: z(e.timestamp) }), e.isOwn && (e.read ? /* @__PURE__ */ _(a, { className: "h-3 w-3 text-accent-blue" }) : /* @__PURE__ */ _(i, { className: "h-3 w-3" }))]
186
+ })] })]
151
187
  })
152
- ]
153
- })]
154
- }),
155
- /* @__PURE__ */ _("div", {
156
- className: "flex-1 overflow-y-auto p-4 space-y-4",
157
- children: F.messages.map((e) => /* @__PURE__ */ _("div", {
158
- className: `flex ${e.isOwn ? "justify-end" : "justify-start"}`,
188
+ }, e.id))
189
+ }),
190
+ /* @__PURE__ */ _("div", {
191
+ className: "border-t border-border-seam p-3",
159
192
  children: /* @__PURE__ */ v("div", {
160
- className: `flex max-w-[75%] items-end gap-2 ${e.isOwn ? "flex-row-reverse" : ""}`,
161
- children: [!e.isOwn && /* @__PURE__ */ _("div", {
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",
163
- children: e.senderName.charAt(0)
164
- }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("div", {
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"}`,
166
- children: /* @__PURE__ */ _("p", {
167
- className: "text-sm",
168
- children: e.content
193
+ className: "flex items-center gap-2",
194
+ children: [
195
+ /* @__PURE__ */ _(x, {
196
+ variant: "outline",
197
+ size: "sm",
198
+ children: /* @__PURE__ */ _(l, { className: "h-4 w-4" })
199
+ }),
200
+ /* @__PURE__ */ _(w, {
201
+ placeholder: D("proserviceworld.messages.input.placeholder", "Type a message..."),
202
+ value: N,
203
+ onChange: (e) => P(e.target.value),
204
+ onKeyDown: (e) => {
205
+ e.key === "Enter" && N.trim() && P("");
206
+ },
207
+ className: "flex-1"
208
+ }),
209
+ /* @__PURE__ */ _(x, {
210
+ variant: "outline",
211
+ size: "sm",
212
+ children: /* @__PURE__ */ _(p, { className: "h-4 w-4" })
213
+ }),
214
+ /* @__PURE__ */ _(x, {
215
+ size: "sm",
216
+ disabled: !N.trim(),
217
+ children: /* @__PURE__ */ _(f, { className: "h-4 w-4" })
169
218
  })
170
- }), /* @__PURE__ */ v("div", {
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" }))]
173
- })] })]
219
+ ]
174
220
  })
175
- }, e.id))
176
- }),
177
- /* @__PURE__ */ _("div", {
178
- className: "border-t border-border-seam p-3",
179
- children: /* @__PURE__ */ v("div", {
180
- className: "flex items-center gap-2",
181
- children: [
182
- /* @__PURE__ */ _(x, {
183
- variant: "outline",
184
- size: "sm",
185
- children: /* @__PURE__ */ _(l, { className: "h-4 w-4" })
186
- }),
187
- /* @__PURE__ */ _(w, {
188
- placeholder: E("proserviceworld.messages.input.placeholder", "Type a message..."),
189
- value: M,
190
- onChange: (e) => N(e.target.value),
191
- onKeyDown: (e) => {
192
- e.key === "Enter" && M.trim() && N("");
193
- },
194
- className: "flex-1"
195
- }),
196
- /* @__PURE__ */ _(x, {
197
- variant: "outline",
198
- size: "sm",
199
- children: /* @__PURE__ */ _(p, { className: "h-4 w-4" })
200
- }),
201
- /* @__PURE__ */ _(x, {
202
- size: "sm",
203
- disabled: !M.trim(),
204
- children: /* @__PURE__ */ _(f, { className: "h-4 w-4" })
205
- })
206
- ]
221
+ })
222
+ ] }) : /* @__PURE__ */ _("div", {
223
+ className: "flex flex-1 items-center justify-center",
224
+ children: /* @__PURE__ */ _(C, {
225
+ illustration: "empty-notifications",
226
+ title: D("proserviceworld.messages.emptyConversation.title", "Select a conversation"),
227
+ description: D("proserviceworld.messages.emptyConversation.description", "Choose a conversation to start messaging.")
207
228
  })
208
229
  })
209
- ] }) : /* @__PURE__ */ _("div", {
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.")
215
- })
216
- })
217
- })]
218
- })]
230
+ })]
231
+ })
232
+ ]
219
233
  });
220
234
  }
221
235
  //#endregion
222
- export { T as MessagesPage };
236
+ export { E as MessagesPage };
223
237
 
224
238
  //# sourceMappingURL=MessagesPage.js.map