@burdenoff/microfe-workspaces 2026.510.50 → 2026.511.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 (69) hide show
  1. package/dist/generated/wspace-operations.d.ts +91 -0
  2. package/dist/generated/wspace-operations.d.ts.map +1 -1
  3. package/dist/generated/wspace-operations.js +79 -51
  4. package/dist/generated/wspace-operations.js.map +1 -1
  5. package/dist/hooks/useMemberMutations.d.ts.map +1 -1
  6. package/dist/hooks/useMemberMutations.js +141 -60
  7. package/dist/hooks/useMemberMutations.js.map +1 -1
  8. package/dist/hooks/useProjectMutations.d.ts.map +1 -1
  9. package/dist/hooks/useProjectMutations.js +84 -44
  10. package/dist/hooks/useProjectMutations.js.map +1 -1
  11. package/dist/hooks/useWorkspaceMutations.d.ts.map +1 -1
  12. package/dist/hooks/useWorkspaceMutations.js +64 -29
  13. package/dist/hooks/useWorkspaceMutations.js.map +1 -1
  14. package/dist/hooks/useWorkspacesEventEmitter.d.ts +5 -1
  15. package/dist/hooks/useWorkspacesEventEmitter.d.ts.map +1 -1
  16. package/dist/hooks/useWorkspacesEventEmitter.js +8 -7
  17. package/dist/hooks/useWorkspacesEventEmitter.js.map +1 -1
  18. package/dist/hooks/useWorkspacesPageView.d.ts +27 -0
  19. package/dist/hooks/useWorkspacesPageView.d.ts.map +1 -0
  20. package/dist/hooks/useWorkspacesPageView.js +29 -0
  21. package/dist/hooks/useWorkspacesPageView.js.map +1 -0
  22. package/dist/pages/ActivityListPage.d.ts.map +1 -1
  23. package/dist/pages/ActivityListPage.js +59 -56
  24. package/dist/pages/ActivityListPage.js.map +1 -1
  25. package/dist/pages/CreateWorkspacePage.d.ts.map +1 -1
  26. package/dist/pages/CreateWorkspacePage.js +104 -104
  27. package/dist/pages/CreateWorkspacePage.js.map +1 -1
  28. package/dist/pages/InviteAcceptancePage.d.ts.map +1 -1
  29. package/dist/pages/InviteAcceptancePage.js +197 -216
  30. package/dist/pages/InviteAcceptancePage.js.map +1 -1
  31. package/dist/pages/MembersListPage.d.ts.map +1 -1
  32. package/dist/pages/MembersListPage.js +142 -138
  33. package/dist/pages/MembersListPage.js.map +1 -1
  34. package/dist/pages/ProjectDetailPage.d.ts.map +1 -1
  35. package/dist/pages/ProjectDetailPage.js +181 -176
  36. package/dist/pages/ProjectDetailPage.js.map +1 -1
  37. package/dist/pages/ProjectsListPage.d.ts.map +1 -1
  38. package/dist/pages/ProjectsListPage.js +175 -171
  39. package/dist/pages/ProjectsListPage.js.map +1 -1
  40. package/dist/pages/WorkspaceDetailPage.d.ts.map +1 -1
  41. package/dist/pages/WorkspaceDetailPage.js +104 -101
  42. package/dist/pages/WorkspaceDetailPage.js.map +1 -1
  43. package/dist/pages/WorkspaceSettingsPage.d.ts.map +1 -1
  44. package/dist/pages/WorkspaceSettingsPage.js +182 -137
  45. package/dist/pages/WorkspaceSettingsPage.js.map +1 -1
  46. package/dist/pages/WorkspacesListPage.d.ts.map +1 -1
  47. package/dist/pages/WorkspacesListPage.js +77 -77
  48. package/dist/pages/WorkspacesListPage.js.map +1 -1
  49. package/dist/pages/dashboard/DashboardCustomizer.d.ts.map +1 -1
  50. package/dist/pages/dashboard/DashboardCustomizer.js +53 -55
  51. package/dist/pages/dashboard/DashboardCustomizer.js.map +1 -1
  52. package/dist/pages/dashboard/DashboardGrid.d.ts.map +1 -1
  53. package/dist/pages/dashboard/DashboardGrid.js +33 -36
  54. package/dist/pages/dashboard/DashboardGrid.js.map +1 -1
  55. package/dist/pages/dashboard/DashboardPage.d.ts.map +1 -1
  56. package/dist/pages/dashboard/DashboardPage.js +67 -65
  57. package/dist/pages/dashboard/DashboardPage.js.map +1 -1
  58. package/dist/pages/dashboard/WidgetWrapper.d.ts.map +1 -1
  59. package/dist/pages/dashboard/WidgetWrapper.js +3 -6
  60. package/dist/pages/dashboard/WidgetWrapper.js.map +1 -1
  61. package/dist/utils/i18n.d.ts +13 -0
  62. package/dist/utils/i18n.d.ts.map +1 -0
  63. package/dist/utils/i18n.js +12 -0
  64. package/dist/utils/i18n.js.map +1 -0
  65. package/dist/utils/telemetryError.d.ts +2 -0
  66. package/dist/utils/telemetryError.d.ts.map +1 -0
  67. package/dist/utils/telemetryError.js +28 -0
  68. package/dist/utils/telemetryError.js.map +1 -0
  69. package/package.json +9 -4
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectsListPage.js","names":[],"sources":["../../src/pages/ProjectsListPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { FolderKanban, Plus, Grid3x3, List, Search } from 'lucide-react';\nimport { TagBadge } from '@burdenoff/fe-libs/tag';\nimport {\n Button,\n Input,\n Card,\n CardContent,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Skeleton,\n} from '@burdenoff/fe-libs/ui';\nimport { useDebounce } from '@burdenoff/fe-libs/shared/hooks';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { nativeConfirm, nativeImpact } from '../utils/nativeBridge';\nimport { useProjects } from '../hooks/useProjects';\nimport {\n useArchiveProject,\n useDeleteProject,\n useUnarchiveProject,\n} from '../hooks/useProjectMutations';\nimport { ProjectCard } from '../components/ProjectCard';\nimport { CreateProjectDialog } from '../components/CreateProjectDialog';\nimport { useWorkspacePermissions } from '../hooks/useWorkspacePermissions';\nimport type { ProjectTag, Workspace } from '../types';\n\nexport function ProjectsListPage() {\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n },\n [t]\n );\n\n const { workspaceId } = useParams<{ workspaceId: string }>();\n const {\n viewMode,\n setViewMode,\n projectFilters,\n setProjectFilters,\n clearProjectFilters,\n selectedProjectIds,\n toggleProjectSelection,\n clearProjectSelection,\n openCreateProjectDialog,\n isCreateProjectDialogOpen,\n } = useWorkspacesStore();\n\n const [searchValue, setSearchValue] = useState(projectFilters.search || '');\n const [activeTagFilters, setActiveTagFilters] = useState<ProjectTag[]>([]);\n const [matchAllTagFilters, setMatchAllTagFilters] = useState(true);\n const debouncedSearch = useDebounce(searchValue, 500);\n\n // Update filters when debounced search changes\n useEffect(() => {\n setProjectFilters({ search: debouncedSearch });\n }, [debouncedSearch, setProjectFilters]);\n\n useEffect(() => {\n if (activeTagFilters.length === 0) {\n setProjectFilters({\n tagIds: undefined,\n tagHierarchyPaths: undefined,\n matchAllTags: undefined,\n includeDescendants: undefined,\n });\n return;\n }\n\n setProjectFilters({\n tagIds: activeTagFilters.map((tag) => tag.tagId),\n tagHierarchyPaths: activeTagFilters\n .map((tag) => tag.hierarchyPath)\n .filter((tagPath): tagPath is string => typeof tagPath === 'string' && tagPath.length > 0),\n matchAllTags: matchAllTagFilters,\n includeDescendants: true,\n });\n }, [activeTagFilters, matchAllTagFilters, setProjectFilters]);\n\n useEffect(() => {\n return () => clearProjectSelection();\n }, [clearProjectSelection]);\n\n const { data, isLoading, error } = useProjects(projectFilters, undefined, workspaceId);\n const { mutateAsync: archiveProject } = useArchiveProject(workspaceId);\n const { mutateAsync: unarchiveProject } = useUnarchiveProject(workspaceId);\n const { mutateAsync: deleteProject } = useDeleteProject(workspaceId);\n\n const selectedProjects = useMemo(\n () => data?.items.filter((project) => selectedProjectIds.has(project.id)) ?? [],\n [data?.items, selectedProjectIds]\n );\n\n const archivableProjects = useMemo(\n () => selectedProjects.filter((project) => !project.archived),\n [selectedProjects]\n );\n\n const unarchivableProjects = useMemo(\n () => selectedProjects.filter((project) => project.archived),\n [selectedProjects]\n );\n\n const allVisibleSelected =\n (data?.items.length ?? 0) > 0 &&\n (data?.items ?? []).every((project) => selectedProjectIds.has(project.id));\n const partiallySelected =\n (data?.items ?? []).some((project) => selectedProjectIds.has(project.id)) &&\n !allVisibleSelected;\n\n const {\n canListProjects,\n canCreateProject,\n canDeleteProject,\n canArchiveProject,\n isLoading: permissionsLoading,\n } = useWorkspacePermissions();\n\n if (permissionsLoading) {\n return (\n <div className=\"space-y-4 p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n </div>\n );\n }\n\n if (!canListProjects) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold\">\n {tr('projectsList.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n 'projectsList.noPermissionToViewProjects',\n \"You don't have permission to view projects.\"\n )}\n </p>\n </div>\n </div>\n );\n }\n\n const handleCreateProject = () => {\n openCreateProjectDialog({} as Workspace);\n };\n\n const handleStatusFilter = (value: string) => {\n if (value === 'all') {\n const nextFilters = { ...projectFilters };\n delete nextFilters.status;\n setProjectFilters(nextFilters);\n } else {\n setProjectFilters({ status: value as 'ACTIVE' | 'INACTIVE' | 'ARCHIVED' });\n }\n };\n\n const handleArchivedFilter = (value: string) => {\n if (value === 'all') {\n const nextFilters = { ...projectFilters };\n delete nextFilters.archived;\n setProjectFilters(nextFilters);\n } else {\n setProjectFilters({ archived: value === 'true' });\n }\n };\n\n const toggleTagFilter = (tag: ProjectTag) => {\n setActiveTagFilters((current) => {\n const exists = current.some((entry) => entry.tagId === tag.tagId);\n if (exists) {\n return current.filter((entry) => entry.tagId !== tag.tagId);\n }\n\n return [...current, tag];\n });\n };\n\n const clearAllProjectFilters = () => {\n setSearchValue('');\n setActiveTagFilters([]);\n setMatchAllTagFilters(true);\n clearProjectFilters();\n };\n\n const toggleAllProjects = (checked: boolean) => {\n (data?.items ?? []).forEach((project) => {\n const isSelected = selectedProjectIds.has(project.id);\n if (checked !== isSelected) {\n toggleProjectSelection(project.id);\n }\n });\n };\n\n const handleBulkArchive = async () => {\n if (archivableProjects.length === 0) return;\n await Promise.allSettled(archivableProjects.map((project) => archiveProject(project.id)));\n clearProjectSelection();\n };\n\n const handleBulkUnarchive = async () => {\n if (unarchivableProjects.length === 0) return;\n await Promise.allSettled(unarchivableProjects.map((project) => unarchiveProject(project.id)));\n clearProjectSelection();\n };\n\n const handleBulkDelete = async () => {\n if (selectedProjects.length === 0) return;\n void nativeImpact('medium');\n const message =\n tr('projectsList.bulkDeleteConfirmPrefix', 'Delete ') +\n selectedProjects.length +\n ' ' +\n tr('projectsList.bulkDeleteConfirmProject', 'selected project') +\n (selectedProjects.length === 1 ? '' : tr('projectsList.bulkDeleteConfirmPluralSuffix', 's')) +\n tr('projectsList.bulkDeleteConfirmSuffix', '? This cannot be undone.');\n const native = await nativeConfirm({\n title: 'Delete projects',\n message,\n okButtonTitle: 'Delete',\n cancelButtonTitle: 'Cancel',\n });\n const confirmed = native === null ? window.confirm(message) : native;\n if (!confirmed) return;\n\n await Promise.allSettled(selectedProjects.map((project) => deleteProject(project.id)));\n clearProjectSelection();\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col sm:flex-row sm:items-center justify-between gap-4\">\n <div>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">\n {tr('projectsList.pageTitle', 'Projects')}\n </h1>\n <p className=\"text-muted-foreground\">\n {tr('projectsList.pageSubtitle', 'Manage and organize your projects')}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n {/* View mode toggle */}\n <div className=\"flex items-center gap-1 border rounded-lg p-1\">\n <Button\n variant={viewMode === 'grid' ? 'secondary' : 'ghost'}\n size=\"sm\"\n onClick={() => setViewMode('grid')}\n className=\"h-8 w-8 p-0\"\n aria-label={tr('projectsList.gridViewAriaLabel', 'Show projects in grid view')}\n >\n <Grid3x3 size={16} />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'secondary' : 'ghost'}\n size=\"sm\"\n onClick={() => setViewMode('list')}\n className=\"h-8 w-8 p-0\"\n aria-label={tr('projectsList.listViewAriaLabel', 'Show projects in list view')}\n >\n <List size={16} />\n </Button>\n </div>\n {canCreateProject && (\n <Button onClick={handleCreateProject}>\n <Plus className=\"h-4 w-4 sm:mr-2\" />\n <span className=\"hidden sm:inline\">\n {tr('projectsList.createProject', 'Create Project')}\n </span>\n </Button>\n )}\n </div>\n </div>\n\n {/* Filters & Search */}\n <div className=\"flex flex-col sm:flex-row gap-3\">\n <div className=\"relative flex-1\">\n <Search\n className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground\"\n size={18}\n />\n <Input\n placeholder={tr('projectsList.searchPlaceholder', 'Search projects...')}\n value={searchValue}\n onChange={(e) => setSearchValue(e.target.value)}\n className=\"pl-[3.25rem]\"\n />\n </div>\n <Select value={projectFilters.status || 'all'} onValueChange={handleStatusFilter}>\n <SelectTrigger className=\"w-full sm:w-[180px]\">\n <SelectValue placeholder={tr('projectsList.filterByStatus', 'Filter by status')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">{tr('projectsList.statusAll', 'All Statuses')}</SelectItem>\n <SelectItem value=\"ACTIVE\">{tr('projectsList.statusActive', 'Active')}</SelectItem>\n <SelectItem value=\"INACTIVE\">\n {tr('projectsList.statusInactive', 'Inactive')}\n </SelectItem>\n </SelectContent>\n </Select>\n <Select\n value={\n projectFilters.archived === undefined\n ? 'all'\n : projectFilters.archived\n ? 'true'\n : 'false'\n }\n onValueChange={handleArchivedFilter}\n >\n <SelectTrigger className=\"w-full sm:w-[180px]\">\n <SelectValue placeholder={tr('projectsList.filterByArchive', 'Filter by archive')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">{tr('projectsList.archiveAll', 'All Projects')}</SelectItem>\n <SelectItem value=\"false\">\n {tr('projectsList.archiveActiveProjects', 'Active Projects')}\n </SelectItem>\n <SelectItem value=\"true\">{tr('projectsList.archiveArchived', 'Archived')}</SelectItem>\n </SelectContent>\n </Select>\n {(projectFilters.search ||\n projectFilters.status ||\n projectFilters.archived !== undefined ||\n activeTagFilters.length > 0) && (\n <Button variant=\"outline\" onClick={clearAllProjectFilters}>\n {tr('projectsList.clearFilters', 'Clear Filters')}\n </Button>\n )}\n </div>\n\n {activeTagFilters.length > 0 && (\n <div className=\"flex flex-col gap-3 rounded-lg border border-border bg-card px-4 py-3\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <p className=\"text-sm font-medium\">\n {tr('projectsList.activeTagFilters', 'Active tag filters')}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {tr(\n 'projectsList.activeTagFiltersDescription',\n 'Click a project tag to add or remove it from the current filter set.'\n )}\n </p>\n </div>\n <Select\n value={matchAllTagFilters ? 'all' : 'any'}\n onValueChange={(value) => setMatchAllTagFilters(value === 'all')}\n >\n <SelectTrigger className=\"w-full sm:w-[180px]\">\n <SelectValue placeholder={tr('projectsList.tagMatchMode', 'Tag match mode')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tr('projectsList.tagMatchAll', 'Match all tags')}\n </SelectItem>\n <SelectItem value=\"any\">\n {tr('projectsList.tagMatchAny', 'Match any tag')}\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex flex-wrap gap-2\">\n {activeTagFilters.map((tag) => (\n <TagBadge\n key={tag.tagId}\n id={tag.tagId}\n label={tag.label}\n color={tag.color ?? undefined}\n icon={tag.icon ?? undefined}\n description={tag.description ?? undefined}\n removable\n onRemove={() => toggleTagFilter(tag)}\n size=\"sm\"\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Error State */}\n {error && (\n <Card className=\"border-destructive\">\n <CardContent className=\"pt-6\">\n <div className=\"flex flex-col items-center justify-center py-8 text-center\">\n <p className=\"text-destructive font-semibold mb-2\">\n {tr('projectsList.errorLoading', 'Error loading projects')}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {error instanceof Error\n ? error.message\n : tr('projectsList.unknownError', 'An unknown error occurred')}\n </p>\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Loading State */}\n {isLoading && (\n <div className=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4\">\n {Array.from({ length: 6 }).map((_, i) => (\n <Card key={i}>\n <CardContent className=\"pt-6\">\n <div className=\"space-y-3\">\n <Skeleton className=\"h-12 w-12 rounded-lg\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {/* Empty State */}\n {!isLoading && !error && data?.items.length === 0 && (\n <Card>\n <CardContent className=\"pt-6\">\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <div className=\"rounded-full bg-muted p-6 mb-4\">\n <FolderKanban size={48} className=\"text-muted-foreground\" />\n </div>\n <h3 className=\"text-lg font-semibold mb-2\">\n {tr('projectsList.noProjectsFound', 'No projects found')}\n </h3>\n <p className=\"text-muted-foreground max-w-sm mb-4\">\n {projectFilters.search\n ? tr('projectsList.adjustSearchOrFilters', 'Try adjusting your search or filters')\n : tr(\n 'projectsList.createFirstProject',\n 'Create your first project to get started organizing your work'\n )}\n </p>\n {!projectFilters.search && canCreateProject && (\n <Button onClick={handleCreateProject}>\n <Plus size={16} className=\"mr-2\" />\n {tr('projectsList.createProject', 'Create Project')}\n </Button>\n )}\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Projects Grid */}\n {!isLoading && !error && data && data.items.length > 0 && (\n <>\n <div className=\"flex flex-col gap-3 rounded-lg border bg-card p-4 sm:flex-row sm:items-center sm:justify-between\">\n <label className=\"flex items-center gap-2 text-sm text-foreground\">\n <input\n type=\"checkbox\"\n checked={allVisibleSelected}\n ref={(input) => {\n if (input) {\n input.indeterminate = partiallySelected && !allVisibleSelected;\n }\n }}\n onChange={(event) => toggleAllProjects(event.target.checked)}\n aria-label={tr('projectsList.selectAllAriaLabel', 'Select all projects')}\n className=\"h-4 w-4 rounded border-border text-primary\"\n />\n <span>{tr('projectsList.selectAllVisible', 'Select all visible')}</span>\n </label>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">\n {selectedProjectIds.size} {tr('projectsList.selected', 'selected')}\n </span>\n {selectedProjectIds.size > 0 && (\n <Button variant=\"ghost\" size=\"sm\" onClick={clearProjectSelection}>\n {tr('projectsList.clearSelection', 'Clear selection')}\n </Button>\n )}\n {canArchiveProject && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleBulkArchive}\n disabled={archivableProjects.length === 0}\n >\n {tr('projectsList.archiveSelected', 'Archive Selected')}\n {archivableProjects.length > 0 ? ` (${archivableProjects.length})` : ''}\n </Button>\n )}\n {canArchiveProject && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleBulkUnarchive}\n disabled={unarchivableProjects.length === 0}\n >\n {tr('projectsList.unarchiveSelected', 'Unarchive Selected')}\n {unarchivableProjects.length > 0 ? ` (${unarchivableProjects.length})` : ''}\n </Button>\n )}\n {canDeleteProject && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleBulkDelete}\n disabled={selectedProjects.length === 0}\n className=\"text-destructive\"\n >\n {tr('projectsList.deleteSelected', 'Delete Selected')}\n {selectedProjects.length > 0 ? ` (${selectedProjects.length})` : ''}\n </Button>\n )}\n </div>\n </div>\n\n <div\n className={\n viewMode === 'list'\n ? 'space-y-3'\n : 'grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4'\n }\n >\n {data.items.map((project) => (\n <ProjectCard\n key={project.id}\n project={project}\n selected={selectedProjectIds.has(project.id)}\n canArchive={canArchiveProject}\n canDelete={canDeleteProject}\n onTagClick={toggleTagFilter}\n onToggleSelect={(checked) => {\n const isSelected = selectedProjectIds.has(project.id);\n if (checked !== isSelected) {\n toggleProjectSelection(project.id);\n }\n }}\n />\n ))}\n </div>\n\n {/* Pagination Info */}\n {data.total > data.items.length && (\n <div className=\"text-center text-sm text-muted-foreground\">\n {tr('projectsList.showingPrefix', 'Showing')} {data.items.length}{' '}\n {tr('projectsList.showingOf', 'of')} {data.total}{' '}\n {tr('projectsList.showingProjects', 'projects')}\n </div>\n )}\n </>\n )}\n\n {/* Create Project Dialog */}\n {isCreateProjectDialogOpen && <CreateProjectDialog workspaceId={workspaceId} />}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA+BA,SAAgB,IAAmB;CACjC,IAAM,EAAE,SAAM,IAAS,EACjB,IAAK,GACR,GAAa,MAA6B;EACzC,IAAM,IAAQ,EAAE,EAAI;AACpB,SAAO,MAAU,IAAM,IAAW;IAEpC,CAAC,EAAE,CACJ,EAEK,EAAE,mBAAgB,IAAoC,EACtD,EACJ,aACA,gBACA,mBACA,sBACA,yBACA,uBACA,2BACA,0BACA,6BACA,kCACE,GAAoB,EAElB,CAAC,GAAa,KAAkB,EAAS,EAAe,UAAU,GAAG,EACrE,CAAC,GAAkB,KAAuB,EAAuB,EAAE,CAAC,EACpE,CAAC,GAAoB,KAAyB,EAAS,GAAK,EAC5D,IAAkB,GAAY,GAAa,IAAI;AA4BrD,CAzBA,QAAgB;AACd,IAAkB,EAAE,QAAQ,GAAiB,CAAC;IAC7C,CAAC,GAAiB,EAAkB,CAAC,EAExC,QAAgB;AACd,MAAI,EAAiB,WAAW,GAAG;AACjC,KAAkB;IAChB,QAAQ,KAAA;IACR,mBAAmB,KAAA;IACnB,cAAc,KAAA;IACd,oBAAoB,KAAA;IACrB,CAAC;AACF;;AAGF,IAAkB;GAChB,QAAQ,EAAiB,KAAK,MAAQ,EAAI,MAAM;GAChD,mBAAmB,EAChB,KAAK,MAAQ,EAAI,cAAc,CAC/B,QAAQ,MAA+B,OAAO,KAAY,YAAY,EAAQ,SAAS,EAAE;GAC5F,cAAc;GACd,oBAAoB;GACrB,CAAC;IACD;EAAC;EAAkB;EAAoB;EAAkB,CAAC,EAE7D,cACe,GAAuB,EACnC,CAAC,EAAsB,CAAC;CAE3B,IAAM,EAAE,SAAM,cAAW,aAAU,EAAY,GAAgB,KAAA,GAAW,EAAY,EAChF,EAAE,aAAa,OAAmB,EAAkB,EAAY,EAChE,EAAE,aAAa,OAAqB,EAAoB,EAAY,EACpE,EAAE,aAAa,OAAkB,GAAiB,EAAY,EAE9D,IAAmB,QACjB,GAAM,MAAM,QAAQ,MAAY,EAAmB,IAAI,EAAQ,GAAG,CAAC,IAAI,EAAE,EAC/E,CAAC,GAAM,OAAO,EAAmB,CAClC,EAEK,IAAqB,QACnB,EAAiB,QAAQ,MAAY,CAAC,EAAQ,SAAS,EAC7D,CAAC,EAAiB,CACnB,EAEK,IAAuB,QACrB,EAAiB,QAAQ,MAAY,EAAQ,SAAS,EAC5D,CAAC,EAAiB,CACnB,EAEK,KACH,GAAM,MAAM,UAAU,KAAK,MAC3B,GAAM,SAAS,EAAE,EAAE,OAAO,MAAY,EAAmB,IAAI,EAAQ,GAAG,CAAC,EACtE,MACH,GAAM,SAAS,EAAE,EAAE,MAAM,MAAY,EAAmB,IAAI,EAAQ,GAAG,CAAC,IACzE,CAAC,GAEG,EACJ,qBACA,qBACA,qBACA,sBACA,WAAW,OACT,IAAyB;AAE7B,KAAI,GACF,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA,EACnC,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD,EAAU,WAAU,QAAS,CAAA;IAC7B,kBAAC,GAAD,EAAU,WAAU,QAAS,CAAA;IAC7B,kBAAC,GAAD,EAAU,WAAU,QAAS,CAAA;IACzB;KACF;;AAIV,KAAI,CAAC,GACH,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,MAAD;IAAI,WAAU;cACX,EAAG,6BAA6B,gBAAgB;IAC9C,CAAA,EACL,kBAAC,KAAD;IAAG,WAAU;cACV,EACC,2CACA,8CACD;IACC,CAAA,CACA;;EACF,CAAA;CAIV,IAAM,UAA4B;AAChC,KAAwB,EAAE,CAAc;IAGpC,MAAsB,MAAkB;AAC5C,MAAI,MAAU,OAAO;GACnB,IAAM,IAAc,EAAE,GAAG,GAAgB;AAEzC,GADA,OAAO,EAAY,QACnB,EAAkB,EAAY;QAE9B,GAAkB,EAAE,QAAQ,GAA6C,CAAC;IAIxE,MAAwB,MAAkB;AAC9C,MAAI,MAAU,OAAO;GACnB,IAAM,IAAc,EAAE,GAAG,GAAgB;AAEzC,GADA,OAAO,EAAY,UACnB,EAAkB,EAAY;QAE9B,GAAkB,EAAE,UAAU,MAAU,QAAQ,CAAC;IAI/C,KAAmB,MAAoB;AAC3C,KAAqB,MACJ,EAAQ,MAAM,MAAU,EAAM,UAAU,EAAI,MAAM,GAExD,EAAQ,QAAQ,MAAU,EAAM,UAAU,EAAI,MAAM,GAGtD,CAAC,GAAG,GAAS,EAAI,CACxB;IAGE,WAA+B;AAInC,EAHA,EAAe,GAAG,EAClB,EAAoB,EAAE,CAAC,EACvB,EAAsB,GAAK,EAC3B,IAAqB;IAGjB,MAAqB,MAAqB;AAC9C,GAAC,GAAM,SAAS,EAAE,EAAE,SAAS,MAAY;AAEvC,GAAI,MADe,EAAmB,IAAI,EAAQ,GAAG,IAEnD,EAAuB,EAAQ,GAAG;IAEpC;;AAsCJ,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eACX,EAAG,0BAA0B,WAAW;KACtC,CAAA,EACL,kBAAC,KAAD;KAAG,WAAU;eACV,EAAG,6BAA6B,oCAAoC;KACnE,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CAEE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD;OACE,SAAS,MAAa,SAAS,cAAc;OAC7C,MAAK;OACL,eAAe,EAAY,OAAO;OAClC,WAAU;OACV,cAAY,EAAG,kCAAkC,6BAA6B;iBAE9E,kBAAC,IAAD,EAAS,MAAM,IAAM,CAAA;OACd,CAAA,EACT,kBAAC,GAAD;OACE,SAAS,MAAa,SAAS,cAAc;OAC7C,MAAK;OACL,eAAe,EAAY,OAAO;OAClC,WAAU;OACV,cAAY,EAAG,kCAAkC,6BAA6B;iBAE9E,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;OACX,CAAA,CACL;SACL,KACC,kBAAC,GAAD;MAAQ,SAAS;gBAAjB,CACE,kBAAC,GAAD,EAAM,WAAU,mBAAoB,CAAA,EACpC,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAG,8BAA8B,iBAAiB;OAC9C,CAAA,CACA;QAEP;OACF;;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,IAAD;OACE,WAAU;OACV,MAAM;OACN,CAAA,EACF,kBAAC,IAAD;OACE,aAAa,EAAG,kCAAkC,qBAAqB;OACvE,OAAO;OACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;OAC/C,WAAU;OACV,CAAA,CACE;;KACN,kBAAC,GAAD;MAAQ,OAAO,EAAe,UAAU;MAAO,eAAe;gBAA9D,CACE,kBAAC,GAAD;OAAe,WAAU;iBACvB,kBAAC,GAAD,EAAa,aAAa,EAAG,+BAA+B,mBAAmB,EAAI,CAAA;OACrE,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA;OACE,kBAAC,GAAD;QAAY,OAAM;kBAAO,EAAG,0BAA0B,eAAe;QAAc,CAAA;OACnF,kBAAC,GAAD;QAAY,OAAM;kBAAU,EAAG,6BAA6B,SAAS;QAAc,CAAA;OACnF,kBAAC,GAAD;QAAY,OAAM;kBACf,EAAG,+BAA+B,WAAW;QACnC,CAAA;OACC,EAAA,CAAA,CACT;;KACT,kBAAC,GAAD;MACE,OACE,EAAe,aAAa,KAAA,IACxB,QACA,EAAe,WACb,SACA;MAER,eAAe;gBARjB,CAUE,kBAAC,GAAD;OAAe,WAAU;iBACvB,kBAAC,GAAD,EAAa,aAAa,EAAG,gCAAgC,oBAAoB,EAAI,CAAA;OACvE,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA;OACE,kBAAC,GAAD;QAAY,OAAM;kBAAO,EAAG,2BAA2B,eAAe;QAAc,CAAA;OACpF,kBAAC,GAAD;QAAY,OAAM;kBACf,EAAG,sCAAsC,kBAAkB;QACjD,CAAA;OACb,kBAAC,GAAD;QAAY,OAAM;kBAAQ,EAAG,gCAAgC,WAAW;QAAc,CAAA;OACxE,EAAA,CAAA,CACT;;MACP,EAAe,UACf,EAAe,UACf,EAAe,aAAa,KAAA,KAC5B,EAAiB,SAAS,MAC1B,kBAAC,GAAD;MAAQ,SAAQ;MAAU,SAAS;gBAChC,EAAG,6BAA6B,gBAAgB;MAC1C,CAAA;KAEP;;GAEL,EAAiB,SAAS,KACzB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAG,iCAAiC,qBAAqB;MACxD,CAAA,EACJ,kBAAC,KAAD;MAAG,WAAU;gBACV,EACC,4CACA,uEACD;MACC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,GAAD;MACE,OAAO,IAAqB,QAAQ;MACpC,gBAAgB,MAAU,EAAsB,MAAU,MAAM;gBAFlE,CAIE,kBAAC,GAAD;OAAe,WAAU;iBACvB,kBAAC,GAAD,EAAa,aAAa,EAAG,6BAA6B,iBAAiB,EAAI,CAAA;OACjE,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;OAAY,OAAM;iBACf,EAAG,4BAA4B,iBAAiB;OACtC,CAAA,EACb,kBAAC,GAAD;OAAY,OAAM;iBACf,EAAG,4BAA4B,gBAAgB;OACrC,CAAA,CACC,EAAA,CAAA,CACT;QACL;QAEN,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAiB,KAAK,MACrB,kBAAC,IAAD;MAEE,IAAI,EAAI;MACR,OAAO,EAAI;MACX,OAAO,EAAI,SAAS,KAAA;MACpB,MAAM,EAAI,QAAQ,KAAA;MAClB,aAAa,EAAI,eAAe,KAAA;MAChC,WAAA;MACA,gBAAgB,EAAgB,EAAI;MACpC,MAAK;MACL,EATK,EAAI,MAST,CACF;KACE,CAAA,CACF;;GAIP,KACC,kBAAC,GAAD;IAAM,WAAU;cACd,kBAAC,GAAD;KAAa,WAAU;eACrB,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAG,6BAA6B,yBAAyB;OACxD,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBACV,aAAiB,QACd,EAAM,UACN,EAAG,6BAA6B,4BAA4B;OAC9D,CAAA,CACA;;KACM,CAAA;IACT,CAAA;GAIR,KACC,kBAAC,OAAD;IAAK,WAAU;cACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;KAAa,WAAU;eACrB,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD,EAAU,WAAU,wBAAyB,CAAA;OAC7C,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA;OAClC,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA;OAC9B;;KACM,CAAA,EACT,EARI,EAQJ,CACP;IACE,CAAA;GAIP,CAAC,KAAa,CAAC,KAAS,GAAM,MAAM,WAAW,KAC9C,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAAa,WAAU;cACrB,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD;QAAc,MAAM;QAAI,WAAU;QAA0B,CAAA;OACxD,CAAA;MACN,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,gCAAgC,oBAAoB;OACrD,CAAA;MACL,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAe,SACZ,EAAG,sCAAsC,uCAAuC,GAChF,EACE,mCACA,gEACD;OACH,CAAA;MACH,CAAC,EAAe,UAAU,KACzB,kBAAC,GAAD;OAAQ,SAAS;iBAAjB,CACE,kBAAC,GAAD;QAAM,MAAM;QAAI,WAAU;QAAS,CAAA,EAClC,EAAG,8BAA8B,iBAAiB,CAC5C;;MAEP;;IACM,CAAA,EACT,CAAA;GAIR,CAAC,KAAa,CAAC,KAAS,KAAQ,EAAK,MAAM,SAAS,KACnD,kBAAA,IAAA,EAAA,UAAA;IACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACE,kBAAC,SAAD;OACE,MAAK;OACL,SAAS;OACT,MAAM,MAAU;AACd,QAAI,MACF,EAAM,gBAAgB,MAAqB,CAAC;;OAGhD,WAAW,MAAU,GAAkB,EAAM,OAAO,QAAQ;OAC5D,cAAY,EAAG,mCAAmC,sBAAsB;OACxE,WAAU;OACV,CAAA,EACF,kBAAC,QAAD,EAAA,UAAO,EAAG,iCAAiC,qBAAqB,EAAQ,CAAA,CAClE;SAER,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,QAAD;QAAM,WAAU;kBAAhB;SACG,EAAmB;SAAK;SAAE,EAAG,yBAAyB,WAAW;SAC7D;;OACN,EAAmB,OAAO,KACzB,kBAAC,GAAD;QAAQ,SAAQ;QAAQ,MAAK;QAAK,SAAS;kBACxC,EAAG,+BAA+B,kBAAkB;QAC9C,CAAA;OAEV,KACC,kBAAC,GAAD;QACE,SAAQ;QACR,MAAK;QACL,SA7RU,YAAY;AAChC,WAAmB,WAAW,MAClC,MAAM,QAAQ,WAAW,EAAmB,KAAK,MAAY,GAAe,EAAQ,GAAG,CAAC,CAAC,EACzF,GAAuB;;QA2RT,UAAU,EAAmB,WAAW;kBAJ1C,CAMG,EAAG,gCAAgC,mBAAmB,EACtD,EAAmB,SAAS,IAAI,KAAK,EAAmB,OAAO,KAAK,GAC9D;;OAEV,KACC,kBAAC,GAAD;QACE,SAAQ;QACR,MAAK;QACL,SAlSY,YAAY;AAClC,WAAqB,WAAW,MACpC,MAAM,QAAQ,WAAW,EAAqB,KAAK,MAAY,GAAiB,EAAQ,GAAG,CAAC,CAAC,EAC7F,GAAuB;;QAgST,UAAU,EAAqB,WAAW;kBAJ5C,CAMG,EAAG,kCAAkC,qBAAqB,EAC1D,EAAqB,SAAS,IAAI,KAAK,EAAqB,OAAO,KAAK,GAClE;;OAEV,KACC,kBAAC,GAAD;QACE,SAAQ;QACR,MAAK;QACL,SAvSS,YAAY;AACnC,aAAI,EAAiB,WAAW,EAAG;AAC9B,WAAa,SAAS;SAC3B,IAAM,IACJ,EAAG,wCAAwC,UAAU,GACrD,EAAiB,SACjB,MACA,EAAG,yCAAyC,mBAAmB,IAC9D,EAAiB,WAAW,IAAI,KAAK,EAAG,8CAA8C,IAAI,IAC3F,EAAG,wCAAwC,2BAA2B,EAClE,IAAS,MAAM,EAAc;UACjC,OAAO;UACP;UACA,eAAe;UACf,mBAAmB;UACpB,CAAC;AACgB,gBAAW,OAAO,OAAO,QAAQ,EAAQ,GAAG,OAG9D,MAAM,QAAQ,WAAW,EAAiB,KAAK,MAAY,GAAc,EAAQ,GAAG,CAAC,CAAC,EACtF,GAAuB;;QAoRT,UAAU,EAAiB,WAAW;QACtC,WAAU;kBALZ,CAOG,EAAG,+BAA+B,kBAAkB,EACpD,EAAiB,SAAS,IAAI,KAAK,EAAiB,OAAO,KAAK,GAC1D;;OAEP;QACF;;IAEN,kBAAC,OAAD;KACE,WACE,MAAa,SACT,cACA;eAGL,EAAK,MAAM,KAAK,MACf,kBAAC,GAAD;MAEW;MACT,UAAU,EAAmB,IAAI,EAAQ,GAAG;MAC5C,YAAY;MACZ,WAAW;MACX,YAAY;MACZ,iBAAiB,MAAY;AAE3B,OAAI,MADe,EAAmB,IAAI,EAAQ,GAAG,IAEnD,EAAuB,EAAQ,GAAG;;MAGtC,EAZK,EAAQ,GAYb,CACF;KACE,CAAA;IAGL,EAAK,QAAQ,EAAK,MAAM,UACvB,kBAAC,OAAD;KAAK,WAAU;eAAf;MACG,EAAG,8BAA8B,UAAU;MAAC;MAAE,EAAK,MAAM;MAAQ;MACjE,EAAG,0BAA0B,KAAK;MAAC;MAAE,EAAK;MAAO;MACjD,EAAG,gCAAgC,WAAW;MAC3C;;IAEP,EAAA,CAAA;GAIJ,MAA6B,kBAAC,IAAD,EAAkC,gBAAe,CAAA;GAC3E"}
1
+ {"version":3,"file":"ProjectsListPage.js","names":[],"sources":["../../src/pages/ProjectsListPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { FolderKanban, Plus, Grid3x3, List, Search } from 'lucide-react';\nimport { TagBadge } from '@burdenoff/fe-libs/tag';\nimport {\n Button,\n Input,\n Card,\n CardContent,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Skeleton,\n} from '@burdenoff/fe-libs/ui';\nimport { useDebounce } from '@burdenoff/fe-libs/shared/hooks';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { nativeConfirm, nativeImpact } from '../utils/nativeBridge';\nimport { useProjects } from '../hooks/useProjects';\nimport {\n useArchiveProject,\n useDeleteProject,\n useUnarchiveProject,\n} from '../hooks/useProjectMutations';\nimport { ProjectCard } from '../components/ProjectCard';\nimport { CreateProjectDialog } from '../components/CreateProjectDialog';\nimport { useWorkspacePermissions } from '../hooks/useWorkspacePermissions';\nimport { useWorkspacesPageView } from '../hooks/useWorkspacesPageView';\nimport { tWithFallback } from '../utils/i18n';\nimport type { ProjectTag, Workspace } from '../types';\n\nexport function ProjectsListPage() {\n const { t } = useI18n();\n\n const { workspaceId } = useParams<{ workspaceId: string }>();\n useWorkspacesPageView('workspaces.projects', { workspaceId, requireParams: true });\n const {\n viewMode,\n setViewMode,\n projectFilters,\n setProjectFilters,\n clearProjectFilters,\n selectedProjectIds,\n toggleProjectSelection,\n clearProjectSelection,\n openCreateProjectDialog,\n isCreateProjectDialogOpen,\n } = useWorkspacesStore();\n\n const [searchValue, setSearchValue] = useState(projectFilters.search || '');\n const [activeTagFilters, setActiveTagFilters] = useState<ProjectTag[]>([]);\n const [matchAllTagFilters, setMatchAllTagFilters] = useState(true);\n const debouncedSearch = useDebounce(searchValue, 500);\n\n // Update filters when debounced search changes\n useEffect(() => {\n setProjectFilters({ search: debouncedSearch });\n }, [debouncedSearch, setProjectFilters]);\n\n useEffect(() => {\n if (activeTagFilters.length === 0) {\n setProjectFilters({\n tagIds: undefined,\n tagHierarchyPaths: undefined,\n matchAllTags: undefined,\n includeDescendants: undefined,\n });\n return;\n }\n\n setProjectFilters({\n tagIds: activeTagFilters.map((tag) => tag.tagId),\n tagHierarchyPaths: activeTagFilters\n .map((tag) => tag.hierarchyPath)\n .filter((tagPath): tagPath is string => typeof tagPath === 'string' && tagPath.length > 0),\n matchAllTags: matchAllTagFilters,\n includeDescendants: true,\n });\n }, [activeTagFilters, matchAllTagFilters, setProjectFilters]);\n\n useEffect(() => {\n return () => clearProjectSelection();\n }, [clearProjectSelection]);\n\n const { data, isLoading, error } = useProjects(projectFilters, undefined, workspaceId);\n const { mutateAsync: archiveProject } = useArchiveProject(workspaceId);\n const { mutateAsync: unarchiveProject } = useUnarchiveProject(workspaceId);\n const { mutateAsync: deleteProject } = useDeleteProject(workspaceId);\n\n const selectedProjects = useMemo(\n () => data?.items.filter((project) => selectedProjectIds.has(project.id)) ?? [],\n [data?.items, selectedProjectIds]\n );\n\n const archivableProjects = useMemo(\n () => selectedProjects.filter((project) => !project.archived),\n [selectedProjects]\n );\n\n const unarchivableProjects = useMemo(\n () => selectedProjects.filter((project) => project.archived),\n [selectedProjects]\n );\n\n const allVisibleSelected =\n (data?.items.length ?? 0) > 0 &&\n (data?.items ?? []).every((project) => selectedProjectIds.has(project.id));\n const partiallySelected =\n (data?.items ?? []).some((project) => selectedProjectIds.has(project.id)) &&\n !allVisibleSelected;\n\n const {\n canListProjects,\n canCreateProject,\n canDeleteProject,\n canArchiveProject,\n isLoading: permissionsLoading,\n } = useWorkspacePermissions();\n\n if (permissionsLoading) {\n return (\n <div className=\"space-y-4 p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n </div>\n );\n }\n\n if (!canListProjects) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold\">\n {tWithFallback(t, 'projectsList.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(\n t,\n 'projectsList.noPermissionToViewProjects',\n \"You don't have permission to view projects.\"\n )}\n </p>\n </div>\n </div>\n );\n }\n\n const handleCreateProject = () => {\n openCreateProjectDialog({} as Workspace);\n };\n\n const handleStatusFilter = (value: string) => {\n if (value === 'all') {\n const nextFilters = { ...projectFilters };\n delete nextFilters.status;\n setProjectFilters(nextFilters);\n } else {\n setProjectFilters({ status: value as 'ACTIVE' | 'INACTIVE' | 'ARCHIVED' });\n }\n };\n\n const handleArchivedFilter = (value: string) => {\n if (value === 'all') {\n const nextFilters = { ...projectFilters };\n delete nextFilters.archived;\n setProjectFilters(nextFilters);\n } else {\n setProjectFilters({ archived: value === 'true' });\n }\n };\n\n const toggleTagFilter = (tag: ProjectTag) => {\n setActiveTagFilters((current) => {\n const exists = current.some((entry) => entry.tagId === tag.tagId);\n if (exists) {\n return current.filter((entry) => entry.tagId !== tag.tagId);\n }\n\n return [...current, tag];\n });\n };\n\n const clearAllProjectFilters = () => {\n setSearchValue('');\n setActiveTagFilters([]);\n setMatchAllTagFilters(true);\n clearProjectFilters();\n };\n\n const toggleAllProjects = (checked: boolean) => {\n (data?.items ?? []).forEach((project) => {\n const isSelected = selectedProjectIds.has(project.id);\n if (checked !== isSelected) {\n toggleProjectSelection(project.id);\n }\n });\n };\n\n const handleBulkArchive = async () => {\n if (archivableProjects.length === 0) return;\n await Promise.allSettled(archivableProjects.map((project) => archiveProject(project.id)));\n clearProjectSelection();\n };\n\n const handleBulkUnarchive = async () => {\n if (unarchivableProjects.length === 0) return;\n await Promise.allSettled(unarchivableProjects.map((project) => unarchiveProject(project.id)));\n clearProjectSelection();\n };\n\n const handleBulkDelete = async () => {\n if (selectedProjects.length === 0) return;\n void nativeImpact('medium');\n const message =\n tWithFallback(t, 'projectsList.bulkDeleteConfirmPrefix', 'Delete ') +\n selectedProjects.length +\n ' ' +\n tWithFallback(t, 'projectsList.bulkDeleteConfirmProject', 'selected project') +\n (selectedProjects.length === 1\n ? ''\n : tWithFallback(t, 'projectsList.bulkDeleteConfirmPluralSuffix', 's')) +\n tWithFallback(t, 'projectsList.bulkDeleteConfirmSuffix', '? This cannot be undone.');\n const native = await nativeConfirm({\n title: 'Delete projects',\n message,\n okButtonTitle: 'Delete',\n cancelButtonTitle: 'Cancel',\n });\n const confirmed = native === null ? window.confirm(message) : native;\n if (!confirmed) return;\n\n await Promise.allSettled(selectedProjects.map((project) => deleteProject(project.id)));\n clearProjectSelection();\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col sm:flex-row sm:items-center justify-between gap-4\">\n <div>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">\n {tWithFallback(t, 'projectsList.pageTitle', 'Projects')}\n </h1>\n <p className=\"text-muted-foreground\">\n {tWithFallback(t, 'projectsList.pageSubtitle', 'Manage and organize your projects')}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n {/* View mode toggle */}\n <div className=\"flex items-center gap-1 border rounded-lg p-1\">\n <Button\n variant={viewMode === 'grid' ? 'secondary' : 'ghost'}\n size=\"sm\"\n onClick={() => setViewMode('grid')}\n className=\"h-8 w-8 p-0\"\n aria-label={tWithFallback(\n t,\n 'projectsList.gridViewAriaLabel',\n 'Show projects in grid view'\n )}\n >\n <Grid3x3 size={16} />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'secondary' : 'ghost'}\n size=\"sm\"\n onClick={() => setViewMode('list')}\n className=\"h-8 w-8 p-0\"\n aria-label={tWithFallback(\n t,\n 'projectsList.listViewAriaLabel',\n 'Show projects in list view'\n )}\n >\n <List size={16} />\n </Button>\n </div>\n {canCreateProject && (\n <Button onClick={handleCreateProject}>\n <Plus className=\"h-4 w-4 sm:mr-2\" />\n <span className=\"hidden sm:inline\">\n {tWithFallback(t, 'projectsList.createProject', 'Create Project')}\n </span>\n </Button>\n )}\n </div>\n </div>\n\n {/* Filters & Search */}\n <div className=\"flex flex-col sm:flex-row gap-3\">\n <div className=\"relative flex-1\">\n <Search\n className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground\"\n size={18}\n />\n <Input\n placeholder={tWithFallback(t, 'projectsList.searchPlaceholder', 'Search projects...')}\n value={searchValue}\n onChange={(e) => setSearchValue(e.target.value)}\n className=\"pl-[3.25rem]\"\n />\n </div>\n <Select value={projectFilters.status || 'all'} onValueChange={handleStatusFilter}>\n <SelectTrigger className=\"w-full sm:w-[180px]\">\n <SelectValue\n placeholder={tWithFallback(t, 'projectsList.filterByStatus', 'Filter by status')}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(t, 'projectsList.statusAll', 'All Statuses')}\n </SelectItem>\n <SelectItem value=\"ACTIVE\">\n {tWithFallback(t, 'projectsList.statusActive', 'Active')}\n </SelectItem>\n <SelectItem value=\"INACTIVE\">\n {tWithFallback(t, 'projectsList.statusInactive', 'Inactive')}\n </SelectItem>\n </SelectContent>\n </Select>\n <Select\n value={\n projectFilters.archived === undefined\n ? 'all'\n : projectFilters.archived\n ? 'true'\n : 'false'\n }\n onValueChange={handleArchivedFilter}\n >\n <SelectTrigger className=\"w-full sm:w-[180px]\">\n <SelectValue\n placeholder={tWithFallback(t, 'projectsList.filterByArchive', 'Filter by archive')}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(t, 'projectsList.archiveAll', 'All Projects')}\n </SelectItem>\n <SelectItem value=\"false\">\n {tWithFallback(t, 'projectsList.archiveActiveProjects', 'Active Projects')}\n </SelectItem>\n <SelectItem value=\"true\">\n {tWithFallback(t, 'projectsList.archiveArchived', 'Archived')}\n </SelectItem>\n </SelectContent>\n </Select>\n {(projectFilters.search ||\n projectFilters.status ||\n projectFilters.archived !== undefined ||\n activeTagFilters.length > 0) && (\n <Button variant=\"outline\" onClick={clearAllProjectFilters}>\n {tWithFallback(t, 'projectsList.clearFilters', 'Clear Filters')}\n </Button>\n )}\n </div>\n\n {activeTagFilters.length > 0 && (\n <div className=\"flex flex-col gap-3 rounded-lg border border-border bg-card px-4 py-3\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <p className=\"text-sm font-medium\">\n {tWithFallback(t, 'projectsList.activeTagFilters', 'Active tag filters')}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {tWithFallback(\n t,\n 'projectsList.activeTagFiltersDescription',\n 'Click a project tag to add or remove it from the current filter set.'\n )}\n </p>\n </div>\n <Select\n value={matchAllTagFilters ? 'all' : 'any'}\n onValueChange={(value) => setMatchAllTagFilters(value === 'all')}\n >\n <SelectTrigger className=\"w-full sm:w-[180px]\">\n <SelectValue\n placeholder={tWithFallback(t, 'projectsList.tagMatchMode', 'Tag match mode')}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(t, 'projectsList.tagMatchAll', 'Match all tags')}\n </SelectItem>\n <SelectItem value=\"any\">\n {tWithFallback(t, 'projectsList.tagMatchAny', 'Match any tag')}\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex flex-wrap gap-2\">\n {activeTagFilters.map((tag) => (\n <TagBadge\n key={tag.tagId}\n id={tag.tagId}\n label={tag.label}\n color={tag.color ?? undefined}\n icon={tag.icon ?? undefined}\n description={tag.description ?? undefined}\n removable\n onRemove={() => toggleTagFilter(tag)}\n size=\"sm\"\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Error State */}\n {error && (\n <Card className=\"border-destructive\">\n <CardContent className=\"pt-6\">\n <div className=\"flex flex-col items-center justify-center py-8 text-center\">\n <p className=\"text-destructive font-semibold mb-2\">\n {tWithFallback(t, 'projectsList.errorLoading', 'Error loading projects')}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {error instanceof Error\n ? error.message\n : tWithFallback(t, 'projectsList.unknownError', 'An unknown error occurred')}\n </p>\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Loading State */}\n {isLoading && (\n <div className=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4\">\n {Array.from({ length: 6 }).map((_, i) => (\n <Card key={i}>\n <CardContent className=\"pt-6\">\n <div className=\"space-y-3\">\n <Skeleton className=\"h-12 w-12 rounded-lg\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {/* Empty State */}\n {!isLoading && !error && data?.items.length === 0 && (\n <Card>\n <CardContent className=\"pt-6\">\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <div className=\"rounded-full bg-muted p-6 mb-4\">\n <FolderKanban size={48} className=\"text-muted-foreground\" />\n </div>\n <h3 className=\"text-lg font-semibold mb-2\">\n {tWithFallback(t, 'projectsList.noProjectsFound', 'No projects found')}\n </h3>\n <p className=\"text-muted-foreground max-w-sm mb-4\">\n {projectFilters.search\n ? tWithFallback(\n t,\n 'projectsList.adjustSearchOrFilters',\n 'Try adjusting your search or filters'\n )\n : tWithFallback(\n t,\n 'projectsList.createFirstProject',\n 'Create your first project to get started organizing your work'\n )}\n </p>\n {!projectFilters.search && canCreateProject && (\n <Button onClick={handleCreateProject}>\n <Plus size={16} className=\"mr-2\" />\n {tWithFallback(t, 'projectsList.createProject', 'Create Project')}\n </Button>\n )}\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Projects Grid */}\n {!isLoading && !error && data && data.items.length > 0 && (\n <>\n <div className=\"flex flex-col gap-3 rounded-lg border bg-card p-4 sm:flex-row sm:items-center sm:justify-between\">\n <label className=\"flex items-center gap-2 text-sm text-foreground\">\n <input\n type=\"checkbox\"\n checked={allVisibleSelected}\n ref={(input) => {\n if (input) {\n input.indeterminate = partiallySelected && !allVisibleSelected;\n }\n }}\n onChange={(event) => toggleAllProjects(event.target.checked)}\n aria-label={tWithFallback(\n t,\n 'projectsList.selectAllAriaLabel',\n 'Select all projects'\n )}\n className=\"h-4 w-4 rounded border-border text-primary\"\n />\n <span>{tWithFallback(t, 'projectsList.selectAllVisible', 'Select all visible')}</span>\n </label>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">\n {selectedProjectIds.size} {tWithFallback(t, 'projectsList.selected', 'selected')}\n </span>\n {selectedProjectIds.size > 0 && (\n <Button variant=\"ghost\" size=\"sm\" onClick={clearProjectSelection}>\n {tWithFallback(t, 'projectsList.clearSelection', 'Clear selection')}\n </Button>\n )}\n {canArchiveProject && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleBulkArchive}\n disabled={archivableProjects.length === 0}\n >\n {tWithFallback(t, 'projectsList.archiveSelected', 'Archive Selected')}\n {archivableProjects.length > 0 ? ` (${archivableProjects.length})` : ''}\n </Button>\n )}\n {canArchiveProject && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleBulkUnarchive}\n disabled={unarchivableProjects.length === 0}\n >\n {tWithFallback(t, 'projectsList.unarchiveSelected', 'Unarchive Selected')}\n {unarchivableProjects.length > 0 ? ` (${unarchivableProjects.length})` : ''}\n </Button>\n )}\n {canDeleteProject && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleBulkDelete}\n disabled={selectedProjects.length === 0}\n className=\"text-destructive\"\n >\n {tWithFallback(t, 'projectsList.deleteSelected', 'Delete Selected')}\n {selectedProjects.length > 0 ? ` (${selectedProjects.length})` : ''}\n </Button>\n )}\n </div>\n </div>\n\n <div\n className={\n viewMode === 'list'\n ? 'space-y-3'\n : 'grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4'\n }\n >\n {data.items.map((project) => (\n <ProjectCard\n key={project.id}\n project={project}\n selected={selectedProjectIds.has(project.id)}\n canArchive={canArchiveProject}\n canDelete={canDeleteProject}\n onTagClick={toggleTagFilter}\n onToggleSelect={(checked) => {\n const isSelected = selectedProjectIds.has(project.id);\n if (checked !== isSelected) {\n toggleProjectSelection(project.id);\n }\n }}\n />\n ))}\n </div>\n\n {/* Pagination Info */}\n {data.total > data.items.length && (\n <div className=\"text-center text-sm text-muted-foreground\">\n {tWithFallback(t, 'projectsList.showingPrefix', 'Showing')} {data.items.length}{' '}\n {tWithFallback(t, 'projectsList.showingOf', 'of')} {data.total}{' '}\n {tWithFallback(t, 'projectsList.showingProjects', 'projects')}\n </div>\n )}\n </>\n )}\n\n {/* Create Project Dialog */}\n {isCreateProjectDialogOpen && <CreateProjectDialog workspaceId={workspaceId} />}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceDetailPage.d.ts","sourceRoot":"","sources":["../../src/pages/WorkspaceDetailPage.tsx"],"names":[],"mappings":"AAqBA,wBAAgB,mBAAmB,4CA8PlC"}
1
+ {"version":3,"file":"WorkspaceDetailPage.d.ts","sourceRoot":"","sources":["../../src/pages/WorkspaceDetailPage.tsx"],"names":[],"mappings":"AAsBA,wBAAgB,mBAAmB,4CA2PlC"}
@@ -1,223 +1,226 @@
1
1
  import { useWorkspacesContext as e } from "../providers/WorkspacesProvider.js";
2
2
  import { useWorkspace as t } from "../hooks/useWorkspaces.js";
3
3
  import { useScopedNavigation as n } from "../hooks/useScopedNavigation.js";
4
- import { useWorkspaceMembers as r } from "../hooks/useWorkspaceMembers.js";
5
- import { useProjects as i } from "../hooks/useProjects.js";
6
- import { useWorkspaceActivity as a } from "../hooks/useWorkspaceActivity.js";
7
- import { useWorkspacePermissions as o } from "../hooks/useWorkspacePermissions.js";
8
- import { useCallback as s } from "react";
9
- import { Activity as c, ArrowLeft as l, ChevronRight as u, FolderKanban as d, Settings as f, Users as p } from "lucide-react";
10
- import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
11
- import { Badge as _, Button as v, Card as y, CardContent as b, CardHeader as x, CardTitle as S, Skeleton as C } from "@burdenoff/fe-libs/ui";
12
- import { useNavigate as w, useParams as T } from "react-router-dom";
13
- import { useI18n as E } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
4
+ import { tWithFallback as r } from "../utils/i18n.js";
5
+ import { useWorkspacesPageView as i } from "../hooks/useWorkspacesPageView.js";
6
+ import { useWorkspaceMembers as a } from "../hooks/useWorkspaceMembers.js";
7
+ import { useProjects as o } from "../hooks/useProjects.js";
8
+ import { useWorkspaceActivity as s } from "../hooks/useWorkspaceActivity.js";
9
+ import { useWorkspacePermissions as c } from "../hooks/useWorkspacePermissions.js";
10
+ import { Activity as l, ArrowLeft as u, ChevronRight as d, FolderKanban as f, Settings as p, Users as m } from "lucide-react";
11
+ import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
12
+ import { Badge as v, Button as y, Card as b, CardContent as x, CardHeader as S, CardTitle as C, Skeleton as w } from "@burdenoff/fe-libs/ui";
13
+ import { useNavigate as T, useParams as E } from "react-router-dom";
14
+ import { useI18n as D } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
14
15
  //#region src/pages/WorkspaceDetailPage.tsx
15
- function D() {
16
- let { t: D } = E(), O = s((e, t) => {
17
- let n = D(e);
18
- return n === e ? t : n;
19
- }, [D]), { workspaceId: k } = T(), A = w(), { basePath: j = "/" } = e(), { withCurrentSearch: M } = n(), { data: N, isLoading: P, error: F } = t(k || ""), { data: I } = i({ workspaceId: k }, { limit: 1 }, k), { data: L } = r(k || "", { limit: 1 }), { data: R } = a(k), { canViewWorkspace: z, canUpdateWorkspace: B, isLoading: V } = o();
20
- if (V) return /* @__PURE__ */ g("div", {
16
+ function O() {
17
+ let { workspaceId: O } = E();
18
+ i("workspaces.detail", {
19
+ workspaceId: O,
20
+ requireParams: !0
21
+ });
22
+ let { t: k } = D(), A = T(), { basePath: j = "/" } = e(), { withCurrentSearch: M } = n(), { data: N, isLoading: P, error: F } = t(O || ""), { data: I } = o({ workspaceId: O }, { limit: 1 }, O), { data: L } = a(O || "", { limit: 1 }), { data: R } = s(O), { canViewWorkspace: z, canUpdateWorkspace: B, isLoading: V } = c();
23
+ if (V) return /* @__PURE__ */ _("div", {
21
24
  className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
22
- children: [/* @__PURE__ */ h(C, { className: "h-10 w-1/3" }), /* @__PURE__ */ g("div", {
25
+ children: [/* @__PURE__ */ g(w, { className: "h-10 w-1/3" }), /* @__PURE__ */ _("div", {
23
26
  className: "grid grid-cols-1 md:grid-cols-3 gap-4",
24
27
  children: [
25
- /* @__PURE__ */ h(C, { className: "h-32" }),
26
- /* @__PURE__ */ h(C, { className: "h-32" }),
27
- /* @__PURE__ */ h(C, { className: "h-32" })
28
+ /* @__PURE__ */ g(w, { className: "h-32" }),
29
+ /* @__PURE__ */ g(w, { className: "h-32" }),
30
+ /* @__PURE__ */ g(w, { className: "h-32" })
28
31
  ]
29
32
  })]
30
33
  });
31
- if (!z) return /* @__PURE__ */ h("div", {
34
+ if (!z) return /* @__PURE__ */ g("div", {
32
35
  className: "flex items-center justify-center min-h-[400px]",
33
- children: /* @__PURE__ */ g("div", {
36
+ children: /* @__PURE__ */ _("div", {
34
37
  className: "text-center space-y-2",
35
- children: [/* @__PURE__ */ h("h2", {
38
+ children: [/* @__PURE__ */ g("h2", {
36
39
  className: "text-lg font-semibold",
37
- children: O("workspaceDetail.accessDenied", "Access Denied")
38
- }), /* @__PURE__ */ h("p", {
40
+ children: r(k, "workspaceDetail.accessDenied", "Access Denied")
41
+ }), /* @__PURE__ */ g("p", {
39
42
  className: "text-sm text-muted-foreground",
40
- children: O("workspaceDetail.accessDeniedDesc", "You don't have permission to view this workspace.")
43
+ children: r(k, "workspaceDetail.accessDeniedDesc", "You don't have permission to view this workspace.")
41
44
  })]
42
45
  })
43
46
  });
44
- if (P) return /* @__PURE__ */ g("div", {
47
+ if (P) return /* @__PURE__ */ _("div", {
45
48
  className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
46
- children: [/* @__PURE__ */ h(C, { className: "h-10 w-1/3" }), /* @__PURE__ */ g("div", {
49
+ children: [/* @__PURE__ */ g(w, { className: "h-10 w-1/3" }), /* @__PURE__ */ _("div", {
47
50
  className: "grid grid-cols-1 md:grid-cols-3 gap-4",
48
51
  children: [
49
- /* @__PURE__ */ h(C, { className: "h-32" }),
50
- /* @__PURE__ */ h(C, { className: "h-32" }),
51
- /* @__PURE__ */ h(C, { className: "h-32" })
52
+ /* @__PURE__ */ g(w, { className: "h-32" }),
53
+ /* @__PURE__ */ g(w, { className: "h-32" }),
54
+ /* @__PURE__ */ g(w, { className: "h-32" })
52
55
  ]
53
56
  })]
54
57
  });
55
- if (F || !N) return /* @__PURE__ */ g("div", {
58
+ if (F || !N) return /* @__PURE__ */ _("div", {
56
59
  className: "space-y-4 p-6",
57
- children: [/* @__PURE__ */ g(v, {
60
+ children: [/* @__PURE__ */ _(y, {
58
61
  variant: "ghost",
59
62
  onClick: () => A(M(`${j}/list`)),
60
63
  className: "gap-2",
61
- children: [/* @__PURE__ */ h(l, { size: 20 }), O("workspaceDetail.backToWorkspaces", "Back to Workspaces")]
62
- }), /* @__PURE__ */ h("div", {
64
+ children: [/* @__PURE__ */ g(u, { size: 20 }), r(k, "workspaceDetail.backToWorkspaces", "Back to Workspaces")]
65
+ }), /* @__PURE__ */ g("div", {
63
66
  className: "text-center py-12",
64
- children: /* @__PURE__ */ h("p", {
67
+ children: /* @__PURE__ */ g("p", {
65
68
  className: "text-destructive",
66
- children: O("workspaceDetail.notFound", "Workspace not found")
69
+ children: r(k, "workspaceDetail.notFound", "Workspace not found")
67
70
  })
68
71
  })]
69
72
  });
70
73
  let H = (e, t) => {
71
74
  (e.key === "Enter" || e.key === " ") && (e.preventDefault(), A(t));
72
75
  };
73
- return /* @__PURE__ */ g("div", {
76
+ return /* @__PURE__ */ _("div", {
74
77
  className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
75
78
  children: [
76
- /* @__PURE__ */ g("div", {
79
+ /* @__PURE__ */ _("div", {
77
80
  className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",
78
- children: [/* @__PURE__ */ g("div", { children: [
79
- /* @__PURE__ */ g(v, {
81
+ children: [/* @__PURE__ */ _("div", { children: [
82
+ /* @__PURE__ */ _(y, {
80
83
  variant: "ghost",
81
84
  onClick: () => A(M(`${j}/list`)),
82
85
  className: "gap-2 mb-2 -ml-2",
83
- children: [/* @__PURE__ */ h(l, { size: 20 }), O("workspaceDetail.backToWorkspaces", "Back to Workspaces")]
86
+ children: [/* @__PURE__ */ g(u, { size: 20 }), r(k, "workspaceDetail.backToWorkspaces", "Back to Workspaces")]
84
87
  }),
85
- /* @__PURE__ */ h("h1", {
88
+ /* @__PURE__ */ g("h1", {
86
89
  className: "text-2xl sm:text-3xl font-bold",
87
90
  children: N.name
88
91
  }),
89
- /* @__PURE__ */ g("div", {
92
+ /* @__PURE__ */ _("div", {
90
93
  className: "flex items-center gap-2 mt-2",
91
- children: [/* @__PURE__ */ h(_, {
94
+ children: [/* @__PURE__ */ g(v, {
92
95
  variant: "outline",
93
96
  children: N.type
94
- }), /* @__PURE__ */ h(_, { children: N.status })]
97
+ }), /* @__PURE__ */ g(v, { children: N.status })]
95
98
  })
96
- ] }), B && /* @__PURE__ */ g(v, {
97
- onClick: () => A(M(`${j}/${k}/settings`)),
99
+ ] }), B && /* @__PURE__ */ _(y, {
100
+ onClick: () => A(M(`${j}/${O}/settings`)),
98
101
  className: "gap-2",
99
- children: [/* @__PURE__ */ h(f, { size: 20 }), O("workspaceDetail.settings", "Settings")]
102
+ children: [/* @__PURE__ */ g(p, { size: 20 }), r(k, "workspaceDetail.settings", "Settings")]
100
103
  })]
101
104
  }),
102
- /* @__PURE__ */ g("div", {
105
+ /* @__PURE__ */ _("div", {
103
106
  className: "grid grid-cols-1 md:grid-cols-3 gap-4",
104
107
  children: [
105
- /* @__PURE__ */ g(y, {
108
+ /* @__PURE__ */ _(b, {
106
109
  className: "cursor-pointer hover:border-primary/50 hover:shadow-md transition-all duration-200",
107
- onClick: () => A(M(`${j}/${k}/projects`)),
110
+ onClick: () => A(M(`${j}/${O}/projects`)),
108
111
  role: "button",
109
112
  tabIndex: 0,
110
- onKeyDown: (e) => H(e, M(`${j}/${k}/projects`)),
111
- children: [/* @__PURE__ */ g(x, {
113
+ onKeyDown: (e) => H(e, M(`${j}/${O}/projects`)),
114
+ children: [/* @__PURE__ */ _(S, {
112
115
  className: "flex flex-row items-center justify-between pb-2",
113
- children: [/* @__PURE__ */ g(S, {
116
+ children: [/* @__PURE__ */ _(C, {
114
117
  className: "flex items-center gap-2",
115
- children: [/* @__PURE__ */ h(d, {
118
+ children: [/* @__PURE__ */ g(f, {
116
119
  size: 20,
117
120
  className: "text-muted-foreground"
118
- }), O("workspaceDetail.projects", "Projects")]
119
- }), /* @__PURE__ */ h(u, {
121
+ }), r(k, "workspaceDetail.projects", "Projects")]
122
+ }), /* @__PURE__ */ g(d, {
120
123
  size: 20,
121
124
  className: "text-muted-foreground"
122
125
  })]
123
- }), /* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h("p", {
126
+ }), /* @__PURE__ */ _(x, { children: [/* @__PURE__ */ g("p", {
124
127
  className: "text-3xl font-bold",
125
128
  children: I?.total ?? N.projectCount ?? 0
126
- }), /* @__PURE__ */ h("p", {
129
+ }), /* @__PURE__ */ g("p", {
127
130
  className: "text-sm text-muted-foreground",
128
- children: O("workspaceDetail.projectsDesc", "Projects in this workspace")
131
+ children: r(k, "workspaceDetail.projectsDesc", "Projects in this workspace")
129
132
  })] })]
130
133
  }),
131
- /* @__PURE__ */ g(y, {
134
+ /* @__PURE__ */ _(b, {
132
135
  className: "cursor-pointer hover:border-primary/50 hover:shadow-md transition-all duration-200",
133
- onClick: () => A(M(`${j}/${k}/members`)),
136
+ onClick: () => A(M(`${j}/${O}/members`)),
134
137
  role: "button",
135
138
  tabIndex: 0,
136
- onKeyDown: (e) => H(e, M(`${j}/${k}/members`)),
137
- children: [/* @__PURE__ */ g(x, {
139
+ onKeyDown: (e) => H(e, M(`${j}/${O}/members`)),
140
+ children: [/* @__PURE__ */ _(S, {
138
141
  className: "flex flex-row items-center justify-between pb-2",
139
- children: [/* @__PURE__ */ g(S, {
142
+ children: [/* @__PURE__ */ _(C, {
140
143
  className: "flex items-center gap-2",
141
- children: [/* @__PURE__ */ h(p, {
144
+ children: [/* @__PURE__ */ g(m, {
142
145
  size: 20,
143
146
  className: "text-muted-foreground"
144
- }), O("workspaceDetail.members", "Members")]
145
- }), /* @__PURE__ */ h(u, {
147
+ }), r(k, "workspaceDetail.members", "Members")]
148
+ }), /* @__PURE__ */ g(d, {
146
149
  size: 20,
147
150
  className: "text-muted-foreground"
148
151
  })]
149
- }), /* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h("p", {
152
+ }), /* @__PURE__ */ _(x, { children: [/* @__PURE__ */ g("p", {
150
153
  className: "text-3xl font-bold",
151
154
  children: L?.total ?? N.memberCount ?? 0
152
- }), /* @__PURE__ */ h("p", {
155
+ }), /* @__PURE__ */ g("p", {
153
156
  className: "text-sm text-muted-foreground",
154
- children: O("workspaceDetail.membersDesc", "Workspace members")
157
+ children: r(k, "workspaceDetail.membersDesc", "Workspace members")
155
158
  })] })]
156
159
  }),
157
- /* @__PURE__ */ g(y, {
160
+ /* @__PURE__ */ _(b, {
158
161
  className: "cursor-pointer hover:border-primary/50 hover:shadow-md transition-all duration-200",
159
- onClick: () => A(M(`${j}/${k}/activity`)),
162
+ onClick: () => A(M(`${j}/${O}/activity`)),
160
163
  role: "button",
161
164
  tabIndex: 0,
162
- onKeyDown: (e) => H(e, M(`${j}/${k}/activity`)),
163
- children: [/* @__PURE__ */ g(x, {
165
+ onKeyDown: (e) => H(e, M(`${j}/${O}/activity`)),
166
+ children: [/* @__PURE__ */ _(S, {
164
167
  className: "flex flex-row items-center justify-between pb-2",
165
- children: [/* @__PURE__ */ g(S, {
168
+ children: [/* @__PURE__ */ _(C, {
166
169
  className: "flex items-center gap-2",
167
- children: [/* @__PURE__ */ h(c, {
170
+ children: [/* @__PURE__ */ g(l, {
168
171
  size: 20,
169
172
  className: "text-muted-foreground"
170
- }), O("workspaceDetail.activity", "Activity")]
171
- }), /* @__PURE__ */ h(u, {
173
+ }), r(k, "workspaceDetail.activity", "Activity")]
174
+ }), /* @__PURE__ */ g(d, {
172
175
  size: 20,
173
176
  className: "text-muted-foreground"
174
177
  })]
175
- }), /* @__PURE__ */ g(b, { children: [/* @__PURE__ */ h("p", {
178
+ }), /* @__PURE__ */ _(x, { children: [/* @__PURE__ */ g("p", {
176
179
  className: "text-3xl font-bold",
177
180
  children: R?.length ?? 0
178
- }), /* @__PURE__ */ h("p", {
181
+ }), /* @__PURE__ */ g("p", {
179
182
  className: "text-sm text-muted-foreground",
180
- children: O("workspaceDetail.activityDesc", "Recent activity items")
183
+ children: r(k, "workspaceDetail.activityDesc", "Recent activity items")
181
184
  })] })]
182
185
  })
183
186
  ]
184
187
  }),
185
- /* @__PURE__ */ g(y, { children: [/* @__PURE__ */ h(x, { children: /* @__PURE__ */ h(S, { children: O("workspaceDetail.workspaceInformation", "Workspace Information") }) }), /* @__PURE__ */ h(b, {
188
+ /* @__PURE__ */ _(b, { children: [/* @__PURE__ */ g(S, { children: /* @__PURE__ */ g(C, { children: r(k, "workspaceDetail.workspaceInformation", "Workspace Information") }) }), /* @__PURE__ */ g(x, {
186
189
  className: "space-y-2",
187
- children: /* @__PURE__ */ g("div", {
190
+ children: /* @__PURE__ */ _("div", {
188
191
  className: "grid grid-cols-2 gap-2 text-sm",
189
192
  children: [
190
- /* @__PURE__ */ h("span", {
193
+ /* @__PURE__ */ g("span", {
191
194
  className: "text-muted-foreground",
192
- children: O("workspaceDetail.id", "ID:")
195
+ children: r(k, "workspaceDetail.id", "ID:")
193
196
  }),
194
- /* @__PURE__ */ h("span", {
197
+ /* @__PURE__ */ g("span", {
195
198
  className: "font-mono text-xs",
196
199
  children: N.id
197
200
  }),
198
- N.domain && /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("span", {
201
+ N.domain && /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g("span", {
199
202
  className: "text-muted-foreground",
200
- children: O("workspaceDetail.domain", "Domain:")
201
- }), /* @__PURE__ */ h("span", { children: N.domain })] }),
202
- N.contactEmail && /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("span", {
203
+ children: r(k, "workspaceDetail.domain", "Domain:")
204
+ }), /* @__PURE__ */ g("span", { children: N.domain })] }),
205
+ N.contactEmail && /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g("span", {
203
206
  className: "text-muted-foreground",
204
- children: O("workspaceDetail.contactEmail", "Contact Email:")
205
- }), /* @__PURE__ */ h("span", { children: N.contactEmail })] }),
206
- N.website && /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("span", {
207
+ children: r(k, "workspaceDetail.contactEmail", "Contact Email:")
208
+ }), /* @__PURE__ */ g("span", { children: N.contactEmail })] }),
209
+ N.website && /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g("span", {
207
210
  className: "text-muted-foreground",
208
- children: O("workspaceDetail.website", "Website:")
209
- }), /* @__PURE__ */ h("a", {
211
+ children: r(k, "workspaceDetail.website", "Website:")
212
+ }), /* @__PURE__ */ g("a", {
210
213
  href: N.website,
211
214
  target: "_blank",
212
215
  rel: "noopener noreferrer",
213
216
  className: "text-primary hover:underline transition-colors duration-200",
214
217
  children: N.website
215
218
  })] }),
216
- /* @__PURE__ */ h("span", {
219
+ /* @__PURE__ */ g("span", {
217
220
  className: "text-muted-foreground",
218
- children: O("workspaceDetail.created", "Created:")
221
+ children: r(k, "workspaceDetail.created", "Created:")
219
222
  }),
220
- /* @__PURE__ */ h("span", { children: new Date(N.createdAt).toLocaleDateString() })
223
+ /* @__PURE__ */ g("span", { children: new Date(N.createdAt).toLocaleDateString() })
221
224
  ]
222
225
  })
223
226
  })] })
@@ -225,6 +228,6 @@ function D() {
225
228
  });
226
229
  }
227
230
  //#endregion
228
- export { D as WorkspaceDetailPage };
231
+ export { O as WorkspaceDetailPage };
229
232
 
230
233
  //# sourceMappingURL=WorkspaceDetailPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceDetailPage.js","names":[],"sources":["../../src/pages/WorkspaceDetailPage.tsx"],"sourcesContent":["import { useCallback } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport { Settings, ArrowLeft, FolderKanban, Users, Activity, ChevronRight } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n Button,\n Card,\n CardHeader,\n CardTitle,\n CardContent,\n Badge,\n Skeleton,\n} from '@burdenoff/fe-libs/ui';\nimport { useWorkspace } from '../hooks/useWorkspaces';\nimport { useProjects } from '../hooks/useProjects';\nimport { useWorkspaceMembers } from '../hooks/useWorkspaceMembers';\nimport { useWorkspaceActivity } from '../hooks/useWorkspaceActivity';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport { useScopedNavigation } from '../hooks/useScopedNavigation';\nimport { useWorkspacePermissions } from '../hooks/useWorkspacePermissions';\n\nexport function WorkspaceDetailPage() {\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n },\n [t]\n );\n const { workspaceId } = useParams<{ workspaceId: string }>();\n const navigate = useNavigate();\n const { basePath = '/' } = useWorkspacesContext();\n const { withCurrentSearch } = useScopedNavigation();\n const { data: workspace, isLoading, error } = useWorkspace(workspaceId || '');\n const { data: projects } = useProjects({ workspaceId }, { limit: 1 }, workspaceId);\n const { data: members } = useWorkspaceMembers(workspaceId || '', { limit: 1 });\n const { data: activities } = useWorkspaceActivity(workspaceId);\n const {\n canViewWorkspace,\n canUpdateWorkspace,\n isLoading: permissionsLoading,\n } = useWorkspacePermissions();\n\n if (permissionsLoading) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n </div>\n );\n }\n\n if (!canViewWorkspace) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold\">\n {tr('workspaceDetail.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n 'workspaceDetail.accessDeniedDesc',\n \"You don't have permission to view this workspace.\"\n )}\n </p>\n </div>\n </div>\n );\n }\n\n if (isLoading) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n </div>\n );\n }\n\n if (error || !workspace) {\n return (\n <div className=\"space-y-4 p-6\">\n <Button\n variant=\"ghost\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/list`))}\n className=\"gap-2\"\n >\n <ArrowLeft size={20} />\n {tr('workspaceDetail.backToWorkspaces', 'Back to Workspaces')}\n </Button>\n <div className=\"text-center py-12\">\n <p className=\"text-destructive\">\n {tr('workspaceDetail.notFound', 'Workspace not found')}\n </p>\n </div>\n </div>\n );\n }\n\n const handleCardKeyDown = (e: React.KeyboardEvent, path: string) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigate(path);\n }\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3\">\n <div>\n <Button\n variant=\"ghost\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/list`))}\n className=\"gap-2 mb-2 -ml-2\"\n >\n <ArrowLeft size={20} />\n {tr('workspaceDetail.backToWorkspaces', 'Back to Workspaces')}\n </Button>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">{workspace.name}</h1>\n <div className=\"flex items-center gap-2 mt-2\">\n <Badge variant=\"outline\">{workspace.type}</Badge>\n <Badge>{workspace.status}</Badge>\n </div>\n </div>\n {canUpdateWorkspace && (\n <Button\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/settings`))}\n className=\"gap-2\"\n >\n <Settings size={20} />\n {tr('workspaceDetail.settings', 'Settings')}\n </Button>\n )}\n </div>\n\n {/* Stats Cards */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Card\n className=\"cursor-pointer hover:border-primary/50 hover:shadow-md transition-all duration-200\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/projects`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2\">\n <FolderKanban size={20} className=\"text-muted-foreground\" />\n {tr('workspaceDetail.projects', 'Projects')}\n </CardTitle>\n <ChevronRight size={20} className=\"text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold\">{projects?.total ?? workspace.projectCount ?? 0}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tr('workspaceDetail.projectsDesc', 'Projects in this workspace')}\n </p>\n </CardContent>\n </Card>\n\n <Card\n className=\"cursor-pointer hover:border-primary/50 hover:shadow-md transition-all duration-200\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/members`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/members`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2\">\n <Users size={20} className=\"text-muted-foreground\" />\n {tr('workspaceDetail.members', 'Members')}\n </CardTitle>\n <ChevronRight size={20} className=\"text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold\">{members?.total ?? workspace.memberCount ?? 0}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tr('workspaceDetail.membersDesc', 'Workspace members')}\n </p>\n </CardContent>\n </Card>\n\n <Card\n className=\"cursor-pointer hover:border-primary/50 hover:shadow-md transition-all duration-200\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/activity`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/activity`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2\">\n <Activity size={20} className=\"text-muted-foreground\" />\n {tr('workspaceDetail.activity', 'Activity')}\n </CardTitle>\n <ChevronRight size={20} className=\"text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold\">{activities?.length ?? 0}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tr('workspaceDetail.activityDesc', 'Recent activity items')}\n </p>\n </CardContent>\n </Card>\n </div>\n\n {/* Workspace Info */}\n <Card>\n <CardHeader>\n <CardTitle>\n {tr('workspaceDetail.workspaceInformation', 'Workspace Information')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2 text-sm\">\n <span className=\"text-muted-foreground\">{tr('workspaceDetail.id', 'ID:')}</span>\n <span className=\"font-mono text-xs\">{workspace.id}</span>\n\n {workspace.domain && (\n <>\n <span className=\"text-muted-foreground\">\n {tr('workspaceDetail.domain', 'Domain:')}\n </span>\n <span>{workspace.domain}</span>\n </>\n )}\n\n {workspace.contactEmail && (\n <>\n <span className=\"text-muted-foreground\">\n {tr('workspaceDetail.contactEmail', 'Contact Email:')}\n </span>\n <span>{workspace.contactEmail}</span>\n </>\n )}\n\n {workspace.website && (\n <>\n <span className=\"text-muted-foreground\">\n {tr('workspaceDetail.website', 'Website:')}\n </span>\n <a\n href={workspace.website}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline transition-colors duration-200\"\n >\n {workspace.website}\n </a>\n </>\n )}\n\n <span className=\"text-muted-foreground\">\n {tr('workspaceDetail.created', 'Created:')}\n </span>\n <span>{new Date(workspace.createdAt).toLocaleDateString()}</span>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"WorkspaceDetailPage.js","names":[],"sources":["../../src/pages/WorkspaceDetailPage.tsx"],"sourcesContent":["import { useParams, useNavigate } from 'react-router-dom';\nimport { Settings, ArrowLeft, FolderKanban, Users, Activity, ChevronRight } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n Button,\n Card,\n CardHeader,\n CardTitle,\n CardContent,\n Badge,\n Skeleton,\n} from '@burdenoff/fe-libs/ui';\nimport { useWorkspace } from '../hooks/useWorkspaces';\nimport { useProjects } from '../hooks/useProjects';\nimport { useWorkspaceMembers } from '../hooks/useWorkspaceMembers';\nimport { useWorkspaceActivity } from '../hooks/useWorkspaceActivity';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport { useScopedNavigation } from '../hooks/useScopedNavigation';\nimport { useWorkspacePermissions } from '../hooks/useWorkspacePermissions';\nimport { useWorkspacesPageView } from '../hooks/useWorkspacesPageView';\n\nexport function WorkspaceDetailPage() {\n const { workspaceId } = useParams<{ workspaceId: string }>();\n useWorkspacesPageView('workspaces.detail', { workspaceId, requireParams: true });\n const { t } = useI18n();\n const navigate = useNavigate();\n const { basePath = '/' } = useWorkspacesContext();\n const { withCurrentSearch } = useScopedNavigation();\n const { data: workspace, isLoading, error } = useWorkspace(workspaceId || '');\n const { data: projects } = useProjects({ workspaceId }, { limit: 1 }, workspaceId);\n const { data: members } = useWorkspaceMembers(workspaceId || '', { limit: 1 });\n const { data: activities } = useWorkspaceActivity(workspaceId);\n const {\n canViewWorkspace,\n canUpdateWorkspace,\n isLoading: permissionsLoading,\n } = useWorkspacePermissions();\n\n if (permissionsLoading) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n </div>\n );\n }\n\n if (!canViewWorkspace) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold\">\n {tWithFallback(t, 'workspaceDetail.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(\n t,\n 'workspaceDetail.accessDeniedDesc',\n \"You don't have permission to view this workspace.\"\n )}\n </p>\n </div>\n </div>\n );\n }\n\n if (isLoading) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n </div>\n );\n }\n\n if (error || !workspace) {\n return (\n <div className=\"space-y-4 p-6\">\n <Button\n variant=\"ghost\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/list`))}\n className=\"gap-2\"\n >\n <ArrowLeft size={20} />\n {tWithFallback(t, 'workspaceDetail.backToWorkspaces', 'Back to Workspaces')}\n </Button>\n <div className=\"text-center py-12\">\n <p className=\"text-destructive\">\n {tWithFallback(t, 'workspaceDetail.notFound', 'Workspace not found')}\n </p>\n </div>\n </div>\n );\n }\n\n const handleCardKeyDown = (e: React.KeyboardEvent, path: string) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigate(path);\n }\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3\">\n <div>\n <Button\n variant=\"ghost\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/list`))}\n className=\"gap-2 mb-2 -ml-2\"\n >\n <ArrowLeft size={20} />\n {tWithFallback(t, 'workspaceDetail.backToWorkspaces', 'Back to Workspaces')}\n </Button>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">{workspace.name}</h1>\n <div className=\"flex items-center gap-2 mt-2\">\n <Badge variant=\"outline\">{workspace.type}</Badge>\n <Badge>{workspace.status}</Badge>\n </div>\n </div>\n {canUpdateWorkspace && (\n <Button\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/settings`))}\n className=\"gap-2\"\n >\n <Settings size={20} />\n {tWithFallback(t, 'workspaceDetail.settings', 'Settings')}\n </Button>\n )}\n </div>\n\n {/* Stats Cards */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Card\n className=\"cursor-pointer hover:border-primary/50 hover:shadow-md transition-all duration-200\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/projects`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2\">\n <FolderKanban size={20} className=\"text-muted-foreground\" />\n {tWithFallback(t, 'workspaceDetail.projects', 'Projects')}\n </CardTitle>\n <ChevronRight size={20} className=\"text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold\">{projects?.total ?? workspace.projectCount ?? 0}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(t, 'workspaceDetail.projectsDesc', 'Projects in this workspace')}\n </p>\n </CardContent>\n </Card>\n\n <Card\n className=\"cursor-pointer hover:border-primary/50 hover:shadow-md transition-all duration-200\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/members`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/members`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2\">\n <Users size={20} className=\"text-muted-foreground\" />\n {tWithFallback(t, 'workspaceDetail.members', 'Members')}\n </CardTitle>\n <ChevronRight size={20} className=\"text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold\">{members?.total ?? workspace.memberCount ?? 0}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(t, 'workspaceDetail.membersDesc', 'Workspace members')}\n </p>\n </CardContent>\n </Card>\n\n <Card\n className=\"cursor-pointer hover:border-primary/50 hover:shadow-md transition-all duration-200\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/activity`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/activity`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2\">\n <Activity size={20} className=\"text-muted-foreground\" />\n {tWithFallback(t, 'workspaceDetail.activity', 'Activity')}\n </CardTitle>\n <ChevronRight size={20} className=\"text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold\">{activities?.length ?? 0}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(t, 'workspaceDetail.activityDesc', 'Recent activity items')}\n </p>\n </CardContent>\n </Card>\n </div>\n\n {/* Workspace Info */}\n <Card>\n <CardHeader>\n <CardTitle>\n {tWithFallback(t, 'workspaceDetail.workspaceInformation', 'Workspace Information')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2 text-sm\">\n <span className=\"text-muted-foreground\">\n {tWithFallback(t, 'workspaceDetail.id', 'ID:')}\n </span>\n <span className=\"font-mono text-xs\">{workspace.id}</span>\n\n {workspace.domain && (\n <>\n <span className=\"text-muted-foreground\">\n {tWithFallback(t, 'workspaceDetail.domain', 'Domain:')}\n </span>\n <span>{workspace.domain}</span>\n </>\n )}\n\n {workspace.contactEmail && (\n <>\n <span className=\"text-muted-foreground\">\n {tWithFallback(t, 'workspaceDetail.contactEmail', 'Contact Email:')}\n </span>\n <span>{workspace.contactEmail}</span>\n </>\n )}\n\n {workspace.website && (\n <>\n <span className=\"text-muted-foreground\">\n {tWithFallback(t, 'workspaceDetail.website', 'Website:')}\n </span>\n <a\n href={workspace.website}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline transition-colors duration-200\"\n >\n {workspace.website}\n </a>\n </>\n )}\n\n <span className=\"text-muted-foreground\">\n {tWithFallback(t, 'workspaceDetail.created', 'Created:')}\n </span>\n <span>{new Date(workspace.createdAt).toLocaleDateString()}</span>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceSettingsPage.d.ts","sourceRoot":"","sources":["../../src/pages/WorkspaceSettingsPage.tsx"],"names":[],"mappings":"AA8BA,wBAAgB,qBAAqB,4CAoMpC"}
1
+ {"version":3,"file":"WorkspaceSettingsPage.d.ts","sourceRoot":"","sources":["../../src/pages/WorkspaceSettingsPage.tsx"],"names":[],"mappings":"AAsCA,wBAAgB,qBAAqB,4CAyRpC"}