Files
Deep-Package-Inspection/src/app/(dashboard)/user-accounts/columns.tsx
T
rafif dd4c8f6876 feat(source2): push all latest files - device labeling, help system, proxy docs, database isolation fix
- Added DOKUMENTASI-FILTER-PER-SITE.md (site isolation docs)
- Fixed start-with-env.js to force-load .env.production
- Fixed MONGODB_URI hostname from mongodb-netify to mongodb.prod.proit.id
- Updated .gitignore to exclude sensitive scripts and credential files
- Minor UI and labeling improvements
2026-07-29 14:14:29 +07:00

129 lines
4.5 KiB
TypeScript

// src/app/(dashboard)/user-accounts/columns.tsx
"use client";
import { Column } from "@/components/ui/DataTable";
import { type ManagedUser } from "@/lib/admin-api";
import { Eye, Loader2 } from "lucide-react";
interface GetColumnsProps {
role: string | null;
currentUsername?: string | null;
viewAsLoading?: string | null;
onEditClick: (user: ManagedUser) => void;
onViewAsClick?: (user: ManagedUser) => void;
}
export function getColumns({
role,
currentUsername,
viewAsLoading,
onEditClick,
onViewAsClick,
}: GetColumnsProps): Column<ManagedUser>[] {
return [
{
header: "#",
className: "w-[5%] text-center",
accessor: (_, i) => <span className="text-slate-400 font-mono">{i + 1}</span>
},
{
header: "Account Name",
className: "w-[22%] text-center",
accessor: (row) => (
<span className="text-sm font-medium text-slate-200">
{row.account_name || row.username}
</span>
)
},
{
header: "Username",
className: "w-[18%] text-center",
accessor: (row) => <code className="text-xs text-slate-400 font-mono">{row.username}</code>
},
{
header: "Role",
className: "w-[18%] text-center",
accessor: (row) => {
let badgeColor = "bg-slate-500/20 text-slate-400 border-slate-500/30";
if (row.role === "COMPANY_ADMIN") badgeColor = "bg-purple-500/20 text-purple-400 border-purple-500/30";
if (row.role === "COMPANY_OPERATOR") badgeColor = "bg-amber-500/20 text-amber-400 border-amber-500/30";
if (row.role === "COMPANY_VIEWER") badgeColor = "bg-blue-500/20 text-blue-400 border-blue-500/30";
return (
<span className={`px-2.5 py-1 rounded-full text-[10px] font-bold border uppercase tracking-wider ${badgeColor}`}>
{row.role.replace(/_/g, " ")}
</span>
);
}
},
{
header: "Assigned Devices",
className: "w-[15%] text-center",
accessor: (row) => {
const uuids = row.agent_uuids || [];
if (uuids.length === 0) return <span className="text-xs text-slate-500 italic">No device assigned</span>;
return (
<span className="text-xs font-mono text-cyan-400 bg-cyan-400/10 border border-cyan-400/20 px-2 py-0.5 rounded">
{uuids.length} Device{uuids.length > 1 ? "s" : ""}
</span>
);
}
},
{
header: "View As",
className: "w-[10%] text-center",
accessor: (row) => {
const isSelf = currentUsername && row.username === currentUsername;
const isCompanyAdmin = row.role === "COMPANY_ADMIN";
// View-As tersedia untuk COMPANY_OPERATOR dan COMPANY_VIEWER (bukan diri sendiri, bukan admin)
const canViewAs = onViewAsClick &&
!isSelf &&
!isCompanyAdmin &&
(row.role === "COMPANY_OPERATOR" || row.role === "COMPANY_VIEWER") &&
(role === "SUPER_ADMIN" || role === "COMPANY_ADMIN");
if (!canViewAs) {
return <span className="text-slate-600 text-xs">—</span>;
}
const isLoading = viewAsLoading === row.username;
return (
<button
type="button"
onClick={() => onViewAsClick(row)}
disabled={isLoading}
title={`View dashboard as ${row.account_name || row.username}`}
className="inline-flex items-center gap-1 px-2 py-1 rounded-lg text-[11px] font-semibold text-amber-400 bg-amber-400/10 border border-amber-400/20 hover:bg-amber-400/20 hover:border-amber-400/40 transition-all disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
>
{isLoading ? (
<Loader2 className="w-3 h-3 animate-spin" />
) : (
<Eye className="w-3 h-3" />
)}
View As
</button>
);
}
},
{
header: "Actions",
className: "w-[12%] text-center",
accessor: (row) => {
const isSelf = currentUsername && row.username === currentUsername;
const isDisabled = role === "EXECUTIVE" || isSelf;
return (
<button
type="button"
onClick={() => !isSelf && onEditClick(row)}
disabled={!!isDisabled}
title={isSelf ? "Cannot edit your own account from here" : undefined}
className="text-xs text-blue-400 hover:text-blue-300 disabled:opacity-50 disabled:cursor-not-allowed hover:underline font-medium cursor-pointer"
>
{isSelf ? "👤 (You)" : "⚙️ Edit User"}
</button>
);
}
}
];
}