import { useState } from "react"; import type { Server } from "../types/Server"; interface Props { servers: Server[]; loading: boolean; error: string | null; page: number; pageSize: number; totalPages: number; totalItems: number; 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, onPageChange, onPageSizeChange, }: Props) => { const [hideSensitive, setHideSensitive] = useState(false); 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 formatSensitiveValue = (value: string | number) => (hideSensitive ? "••••" : value); return (
{loading &&
Carregando servidores...
} {error &&
{error}
} {!loading && !error && servers.length === 0 && (
Nenhum servidor encontrado.
)} {!loading && !error && hasResults && ( <>
{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: "relative bg-card border border-cardBorder shadow-sm rounded-lg overflow-hidden", status: "p-4 text-text-secondary text-sm", error: "p-4 text-red-600 text-sm", tableWrapper: "overflow-x-auto rounded-lg shadow-sm border border-cardBorder", table: "min-w-full divide-y divide-cardBorder table-auto", tableHead: "bg-gray-50 sticky top-0", tableHeadCell: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-text-secondary", tableBody: "bg-white divide-y divide-cardBorder", rowCell: "px-4 py-3 text-sm text-text", pagination: "flex flex-col gap-2 border-t border-cardBorder bg-white px-4 py-3 sm:flex-row sm:items-center sm:justify-between", pageInfo: "text-sm text-text-secondary", paginationControls: "flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-4", pageSizeLabel: "text-sm text-text 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", pageButtons: "flex items-center gap-3", pageButton: "rounded-md border border-cardBorder px-3 py-1.5 text-sm font-medium text-text hover:bg-bg disabled:opacity-50 disabled:hover:bg-transparent", pageIndicator: "text-sm text-text-secondary", hideButton: "absolute right-3 top-3 rounded-md border border-cardBorder px-3 py-1.5 text-xs font-semibold uppercase tracking-wide text-text-secondary hover:bg-bg disabled:opacity-50 disabled:hover:bg-transparent bg-white shadow-sm", };