import { PencilIcon, CheckIcon, XMarkIcon } from "@heroicons/react/20/solid"; import clsx from "clsx"; import { formatters } from "@/utils"; import { usePermissions } from "@/hooks/usePermissions"; import { Permission } from "@/types/permissions"; interface Session { id: string; mode: string; nickname?: string; identity?: string; source?: string; createdAt?: string; } interface SessionsListProps { sessions: Session[]; currentSessionId?: string; onEditNickname?: (sessionId: string) => void; onApprove?: (sessionId: string) => void; onDeny?: (sessionId: string) => void; onTransfer?: (sessionId: string) => void; formatDuration?: (createdAt: string) => string; } export default function SessionsList({ sessions, currentSessionId, onEditNickname, onApprove, onDeny, onTransfer, formatDuration = (createdAt: string) => formatters.timeAgo(new Date(createdAt)) || "" }: SessionsListProps) { const { hasPermission } = usePermissions(); return (
{sessions.map(session => (
{session.id === currentSessionId && ( (You) )}
{session.createdAt ? formatDuration(session.createdAt) : ""} {/* Show approve/deny for pending sessions if user has permission */} {session.mode === "pending" && hasPermission(Permission.SESSION_APPROVE) && onApprove && onDeny && (
)} {/* Show Transfer button if user has permission to transfer */} {hasPermission(Permission.SESSION_TRANSFER) && session.mode === "observer" && session.id !== currentSessionId && onTransfer && ( )} {/* Allow users with session manage permission to edit any nickname, or anyone to edit their own */} {onEditNickname && (hasPermission(Permission.SESSION_MANAGE) || session.id === currentSessionId) && ( )}
{session.nickname && (

{session.nickname}

)} {session.identity && (

{session.source === "cloud" ? "☁️ " : ""}{session.identity}

)} {session.mode === "pending" && (

Awaiting approval

)}
))}
); } export function SessionModeBadge({ mode }: { mode: string }) { const getBadgeStyle = () => { switch (mode) { case "primary": return "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400"; case "observer": return "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400"; case "queued": return "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400"; case "pending": return "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400"; default: return "bg-slate-100 text-slate-700 dark:bg-slate-900/30 dark:text-slate-400"; } }; return ( {mode} ); }