import type { Server } from "../types/Server"; interface Props { servers: Server[]; loading: boolean; error: string | null; page: number; pageSize: number; totalPages: number; totalItems: number; hideSensitive: boolean; onPageChange: (page: number) => void; onPageSizeChange: (size: number) => void; } const PAGE_SIZE_OPTIONS = [5, 10, 20, 50]; export const ServersTable = ({ servers, loading, error, page, pageSize, totalPages, totalItems, hideSensitive, onPageChange, onPageSizeChange, }: Props) => { const showingFrom = totalItems === 0 ? 0 : page * pageSize + 1; const showingTo = totalItems === 0 ? 0 : Math.min((page + 1) * pageSize, totalItems); const hasResults = servers.length > 0; const isInitialLoad = loading && !hasResults; const showOverlay = loading && hasResults; const formatSensitiveValue = (value: string | number) => (hideSensitive ? "••••" : value); return (
{isInitialLoad &&
Carregando servidores...
} {error &&
{error}
} {!loading && !error && servers.length === 0 && (
Nenhum servidor encontrado.
)} {hasResults && (
{showOverlay && (
Atualizando lista...
)}
{servers.map((server) => ( ))}
Nome IP Porta Usuário Senha Tipo Aplicação Banco
{server.name} {formatSensitiveValue(server.ip)} {formatSensitiveValue(server.port)} {formatSensitiveValue(server.user)} {hideSensitive ? "••••" : server.password} {server.type.toLowerCase()} {server.application.toLowerCase()} {server.dbType.toLowerCase()}
Mostrando {showingFrom} - {showingTo} de {totalItems}
Página {page + 1} de {Math.max(totalPages, 1)}
)}
); }; const Styles = { card: "overflow-hidden rounded-lg border border-cardBorder bg-card shadow-sm dark:border-slate-800 dark:bg-slate-900 dark:shadow-slate-900/40", status: "p-4 text-sm text-text-secondary dark:text-slate-400", error: "p-4 text-sm text-red-600 dark:text-red-400", tableWrapper: "overflow-x-auto rounded-lg border border-cardBorder shadow-sm dark:border-slate-800 dark:bg-slate-950/40", table: "min-w-full table-auto divide-y divide-cardBorder dark:divide-slate-800", tableHead: "sticky top-0 bg-gray-50 dark:bg-slate-800", tableHeadRow: "text-left text-text dark:text-slate-200", tableHeadCell: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-text-secondary dark:text-slate-300", tableBody: "divide-y divide-cardBorder bg-white dark:divide-slate-800 dark:bg-slate-900", tableRow: "transition-colors even:bg-gray-50/50 hover:bg-gray-50 dark:even:bg-slate-900 dark:hover:bg-slate-800", rowCell: "px-4 py-3 text-sm text-text dark:text-slate-100", password: "rounded bg-gray-100 px-2 py-1 text-xs dark:bg-slate-800 dark:text-slate-100", pagination: "flex flex-col gap-2 border-t border-cardBorder bg-white px-4 py-3 dark:border-slate-800 dark:bg-slate-900 sm:flex-row sm:items-center sm:justify-between", pageInfo: "text-sm text-text-secondary dark:text-slate-400", paginationControls: "flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-4", pageSizeLabel: "text-sm text-text dark:text-slate-100 flex items-center gap-2", pageSizeSelect: "rounded-md border border-cardBorder bg-white px-2 py-1 text-sm text-text outline-none focus:border-accent focus:ring-1 focus:ring-accent dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100", pageButtons: "flex items-center gap-3", pageButton: "rounded-md border border-cardBorder px-3 py-1.5 text-sm font-medium text-text transition-colors hover:bg-bg disabled:opacity-50 disabled:hover:bg-transparent dark:border-slate-700 dark:text-slate-100 dark:hover:bg-slate-800", pageIndicator: "text-sm text-text-secondary dark:text-slate-400", footerSpacer: "h-4", loadingOverlay: "absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-white/70 text-sm font-medium text-text backdrop-blur-sm dark:bg-slate-900/80 dark:text-slate-100", };