import { Card, CardContent, CardHeader, CardTitle, } from "@/shared/common/ui/card"; import { Button } from "@/shared/common/ui/button"; import { Users, FileText, Building2, Files, Upload, AlertCircle, RefreshCw, } from "lucide-react"; import { useNavigate } from "react-router-dom"; import { Navigate } from "react-router-dom"; import { useOrganizationReport } from "@/shared/hooks/useOrganizationReport"; import { Alert, AlertDescription } from "@/shared/common/ui/alert"; import { Skeleton } from "@/shared/common/ui/skeleton"; import { useAuth } from "@/shared/context/AuthContext"; import { t } from "i18next"; import SmartOfficeAuditPage from "@/record-management/pages/AuditLog/SmartOfficeAuditPage"; import { useUnit } from "@/user-management/hooks/useUnit"; import type { UnitDto } from "@/user-management/dto/unit/unitDto"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/shared/common/ui/select"; import { useEffect, useState } from "react"; import { useLocalizedName } from "@/shared/common/localizedName"; import { useUnitReport } from "@/shared/hooks/useUnitReport"; import { useTenantConfig, resolveModuleConfig, } from "@/layout/components/TenantConfig"; import { hasComplaintVerification } from "@/complaints/utils/complaintVerificationStorage"; import { COMPLAINT_RECORDS_PATH } from "@/complaints/utils/complaintRoutes"; const MODULE_PATHS: Record = { recordManagement: "/record-management/dashboard", performance: "/performance-management/plan-years", objective: "/objective-management/plan-years", dms: "/dms/dashboard", }; const OrgAdminDashboard = () => { const navigate = useNavigate(); const { user } = useAuth(); const { config: tenantConfig } = useTenantConfig(); const localizedName = useLocalizedName(); const organizationId = user?.employee?.[0]?.organizationId ?? ""; const isOrganizationAdmin = user?.roles?.some((role) => role.key === "organization_admin") ?? false; const hasUnitAdminRole = user?.roles?.some((role) => role.key === "unit_admin") ?? false; const isUnitAdmin = !isOrganizationAdmin && hasUnitAdminRole; const [selectedUnitId, setSelectedUnitId] = useState(""); const { getAccessibleList } = useUnit(); const { data: unitsResponse, isLoading: isUnitsLoading } = getAccessibleList( organizationId, { take: 1000, skip: 0 }, isUnitAdmin && !!organizationId, ); const units = (unitsResponse?.data?.items ?? []) as UnitDto[]; useEffect(() => { if (!units.some((unit) => unit.id === selectedUnitId)) { setSelectedUnitId(units[0]?.id ?? ""); } }, [selectedUnitId, units]); const { report, isLoading, isError, error, refetch } = useOrganizationReport(organizationId, { enabled: !isUnitAdmin }); const unitReportQuery = useUnitReport(organizationId, selectedUnitId, { enabled: isUnitAdmin, }); const activeReport = isUnitAdmin ? unitReportQuery.data : report; const isDashboardLoading = isUnitAdmin ? isUnitsLoading || (!!selectedUnitId && unitReportQuery.isLoading) : isLoading; const isDashboardError = isUnitAdmin ? unitReportQuery.isError : isError; const dashboardError = isUnitAdmin ? unitReportQuery.error : error; const refetchDashboard = () => isUnitAdmin ? unitReportQuery.refetch() : refetch(); const statusCode: number | undefined = (dashboardError as any)?.response ?.status; const isUnauthorized = isDashboardError && (statusCode === 401 || statusCode === 403); const fallbackPath = (() => { if (hasComplaintVerification()) return COMPLAINT_RECORDS_PATH; const modules = resolveModuleConfig(tenantConfig); const enabledModulePaths = Object.entries(MODULE_PATHS) .filter(([key]) => modules[key as keyof typeof modules]) .map(([, path]) => path); if (enabledModulePaths.length === 1) return enabledModulePaths[0]; return "/homepage"; })(); if (isUnauthorized) { return ; } // Define stats structure for the dashboard const getStats = () => [ // One brand hue, stepped depth per tile — identity comes from the icon // and title, so the chips stay cohesive instead of competing hues. { id: "employees", title: t("dashboard.totalEmployees"), value: activeReport?.employeesCount?.toLocaleString() || "0", icon: Users, color: "from-primary-500 to-primary-600", }, ...(!isUnitAdmin ? [{ id: "units", title: t("dashboard.totalUnits"), value: report?.unitsCount?.toLocaleString() || "0", icon: Building2, color: "from-primary-600 to-primary-700", }] : []), { id: "positions", title: t("dashboard.totalPositions"), value: activeReport?.positionsCount?.toLocaleString() || "0", icon: FileText, color: "from-primary-700 to-primary-800", }, ]; // Use report activities if available, otherwise use static data // Brand gradient for all navigation actions; archive alone stays neutral // gray to read as the "dormant" destination. Icons carry the identity. const quickActions = [ { id: "user-mgmt", title: t("dashboard.userManagement"), description: t("dashboard.userManagementDesc"), icon: Users, action: () => navigate("/user-management/user_management"), color: "bg-gradient-to-r from-primary-500 to-primary-700", }, { id: "content-mgmt", title: t("dashboard.contentManagement"), description: t("dashboard.contentManagementDesc"), icon: Files, action: () => navigate("/user-management/content-management"), color: "bg-gradient-to-r from-primary-500 to-primary-700", }, { id: "excel-upload", title: t("dashboard.excelUploader"), description: t("dashboard.excelUploaderDesc"), icon: Upload, action: () => navigate("/user-management/bulk-upload"), color: "bg-gradient-to-r from-primary-500 to-primary-700", }, { id: "position-settings", title: t("dashboard.positionSettings"), description: t("dashboard.positionSettingsDesc"), icon: FileText, action: () => navigate("/user-management/position-management"), color: "bg-gradient-to-r from-primary-500 to-primary-700", }, { id: "archive-users", title: t("dashboard.archiveUsers"), description: t("dashboard.archiveUsersDesc"), icon: AlertCircle, action: () => navigate("/user-management/archives"), color: "bg-gradient-to-r from-gray-500 to-slate-600", }, { id: "web-management", title: t("dashboard.webManagement"), description: t("dashboard.webManagementDesc"), icon: FileText, action: () => navigate("/user-management/web-management"), color: "bg-gradient-to-r from-primary-500 to-primary-700", }, ]; return (

{isUnitAdmin ? t("dashboard.unitDashboard", "Unit Dashboard") : t("dashboard.organizationDashboard")}

{t("dashboard.orgMsg")}

{isUnitAdmin && ( )}
{/* Error display */} {isDashboardError && ( {t("dashboard.errorMsg")} {dashboardError instanceof Error && `: ${dashboardError.message}`} )} {/* Stats Grid */}
{isDashboardLoading ? // Loading skeletons for stats Array(isUnitAdmin ? 2 : 3) .fill(0) .map((_, index) => (
)) : getStats().map((stat) => (

{stat.title}

{stat.value}

))}
{/* Quick Actions */} {t("landingPage.quickActions")}
{quickActions.map((action) => ( ))}
{isUnitAdmin ? ( selectedUnitId && ) : ( organizationId && ( ) )}
); }; export default OrgAdminDashboard;