Refactor: Make UI responsive
This commit is contained in:
@@ -113,31 +113,33 @@ export const AgentView = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full bg-background">
|
||||
<div className="p-6 border-b border-border">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h1 className="text-3xl font-bold text-foreground">Agente de Parecer Jurídico</h1>
|
||||
<div className="flex gap-2">
|
||||
<Button onClick={() => setShowSearch(true)} variant="outline" className="gap-2">
|
||||
<Search className="w-4 h-4" />
|
||||
Pesquisar Base de Pareceres
|
||||
<div className="flex flex-col h-full bg-background pb-16 md:pb-0">
|
||||
<div className="p-3 md:p-6 border-b border-border">
|
||||
<div className="flex flex-col md:flex-row items-start md:items-center justify-between gap-3 mb-4">
|
||||
<h1 className="text-xl md:text-3xl font-bold text-foreground">Agente de Parecer Jurídico</h1>
|
||||
<div className="flex gap-2 w-full md:w-auto">
|
||||
<Button onClick={() => setShowSearch(true)} variant="outline" className="gap-1 md:gap-2 flex-1 md:flex-none text-xs md:text-sm">
|
||||
<Search className="w-3 h-3 md:w-4 md:h-4" />
|
||||
<span className="hidden sm:inline">Pesquisar Base</span>
|
||||
<span className="sm:hidden">Base</span>
|
||||
</Button>
|
||||
<Button onClick={handleNewOpinion} className="gap-2">
|
||||
<Plus className="w-4 h-4" />
|
||||
Novo Parecer
|
||||
<Button onClick={handleNewOpinion} className="gap-1 md:gap-2 flex-1 md:flex-none text-xs md:text-sm">
|
||||
<Plus className="w-3 h-3 md:w-4 md:h-4" />
|
||||
<span className="hidden sm:inline">Novo Parecer</span>
|
||||
<span className="sm:hidden">Novo</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex flex-col md:flex-row items-stretch md:items-center gap-2 md:gap-4">
|
||||
<Input
|
||||
placeholder="Buscar pareceres..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="max-w-sm"
|
||||
className="w-full md:max-w-sm text-sm"
|
||||
/>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm text-muted-foreground">Itens por página:</span>
|
||||
<div className="flex items-center gap-2 justify-between md:justify-start">
|
||||
<span className="text-xs md:text-sm text-muted-foreground whitespace-nowrap">Itens:</span>
|
||||
<Select
|
||||
value={itemsPerPage.toString()}
|
||||
onValueChange={(value) => {
|
||||
@@ -145,7 +147,7 @@ export const AgentView = () => {
|
||||
setCurrentPage(1);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-20">
|
||||
<SelectTrigger className="w-16 md:w-20">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
@@ -159,42 +161,42 @@ export const AgentView = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-auto p-6">
|
||||
<div className="border rounded-lg">
|
||||
<div className="flex-1 overflow-auto p-3 md:p-6">
|
||||
<div className="border rounded-lg overflow-x-auto">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>
|
||||
<TableHead className="min-w-[200px]">
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => handleSort("title")}
|
||||
className="flex items-center gap-1 font-semibold"
|
||||
className="flex items-center gap-1 font-semibold text-xs md:text-sm p-1 md:p-2"
|
||||
>
|
||||
Título
|
||||
<ArrowUpDown className="w-4 h-4" />
|
||||
<ArrowUpDown className="w-3 h-3 md:w-4 md:h-4" />
|
||||
</Button>
|
||||
</TableHead>
|
||||
<TableHead>
|
||||
<TableHead className="hidden md:table-cell">
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => handleSort("category")}
|
||||
className="flex items-center gap-1 font-semibold"
|
||||
className="flex items-center gap-1 font-semibold text-sm"
|
||||
>
|
||||
Categoria
|
||||
<ArrowUpDown className="w-4 h-4" />
|
||||
</Button>
|
||||
</TableHead>
|
||||
<TableHead>
|
||||
<TableHead className="hidden sm:table-cell">
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() => handleSort("createdAt")}
|
||||
className="flex items-center gap-1 font-semibold"
|
||||
className="flex items-center gap-1 font-semibold text-xs md:text-sm p-1 md:p-2"
|
||||
>
|
||||
Data de Criação
|
||||
<ArrowUpDown className="w-4 h-4" />
|
||||
Data
|
||||
<ArrowUpDown className="w-3 h-3 md:w-4 md:h-4" />
|
||||
</Button>
|
||||
</TableHead>
|
||||
<TableHead className="text-center">Ações</TableHead>
|
||||
<TableHead className="text-center text-xs md:text-sm">Ações</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
@@ -209,29 +211,30 @@ export const AgentView = () => {
|
||||
) : (
|
||||
paginatedOpinions.map((opinion) => (
|
||||
<TableRow key={opinion.id}>
|
||||
<TableCell className="font-medium">{opinion.title}</TableCell>
|
||||
<TableCell>{opinion.category || "-"}</TableCell>
|
||||
<TableCell>
|
||||
<TableCell className="font-medium text-xs md:text-sm">{opinion.title}</TableCell>
|
||||
<TableCell className="hidden md:table-cell text-sm">{opinion.category || "-"}</TableCell>
|
||||
<TableCell className="hidden sm:table-cell text-xs md:text-sm">
|
||||
{new Date(opinion.createdAt).toLocaleDateString("pt-BR")}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<div className="flex items-center justify-center gap-1">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => handleViewOpinion(opinion)}
|
||||
title="Visualizar"
|
||||
className="h-7 w-7 md:h-9 md:w-9"
|
||||
>
|
||||
<Eye className="w-4 h-4" />
|
||||
<Eye className="w-3 h-3 md:w-4 md:h-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => handleDeleteOpinion(opinion.id)}
|
||||
className="text-destructive hover:text-destructive"
|
||||
className="text-destructive hover:text-destructive h-7 w-7 md:h-9 md:w-9"
|
||||
title="Excluir"
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
<Trash2 className="w-3 h-3 md:w-4 md:h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
@@ -243,40 +246,55 @@ export const AgentView = () => {
|
||||
</div>
|
||||
|
||||
{totalPages > 1 && (
|
||||
<div className="flex items-center justify-between mt-4">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Mostrando {startIndex + 1} a {Math.min(startIndex + itemsPerPage, sortedOpinions.length)} de{" "}
|
||||
{sortedOpinions.length} pareceres
|
||||
<div className="flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-2 mt-4">
|
||||
<p className="text-xs md:text-sm text-muted-foreground text-center sm:text-left">
|
||||
{startIndex + 1}-{Math.min(startIndex + itemsPerPage, sortedOpinions.length)} de {sortedOpinions.length}
|
||||
</p>
|
||||
<div className="flex gap-2">
|
||||
<div className="flex gap-1 md:gap-2 justify-center">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
|
||||
disabled={currentPage === 1}
|
||||
className="text-xs md:text-sm px-2 md:px-4"
|
||||
>
|
||||
Anterior
|
||||
<span className="hidden sm:inline">Anterior</span>
|
||||
<span className="sm:hidden">Ant</span>
|
||||
</Button>
|
||||
<div className="flex items-center gap-1">
|
||||
{Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => (
|
||||
<Button
|
||||
key={page}
|
||||
variant={currentPage === page ? "default" : "outline"}
|
||||
size="sm"
|
||||
onClick={() => setCurrentPage(page)}
|
||||
className="w-10"
|
||||
>
|
||||
{page}
|
||||
</Button>
|
||||
))}
|
||||
{Array.from({ length: Math.min(totalPages, 5) }, (_, i) => {
|
||||
let page;
|
||||
if (totalPages <= 5) {
|
||||
page = i + 1;
|
||||
} else if (currentPage <= 3) {
|
||||
page = i + 1;
|
||||
} else if (currentPage >= totalPages - 2) {
|
||||
page = totalPages - 4 + i;
|
||||
} else {
|
||||
page = currentPage - 2 + i;
|
||||
}
|
||||
return (
|
||||
<Button
|
||||
key={page}
|
||||
variant={currentPage === page ? "default" : "outline"}
|
||||
size="sm"
|
||||
onClick={() => setCurrentPage(page)}
|
||||
className="w-8 h-8 md:w-10 md:h-9 p-0 text-xs md:text-sm"
|
||||
>
|
||||
{page}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setCurrentPage((p) => Math.min(totalPages, p + 1))}
|
||||
disabled={currentPage === totalPages}
|
||||
className="text-xs md:text-sm px-2 md:px-4"
|
||||
>
|
||||
Próxima
|
||||
<span className="hidden sm:inline">Próxima</span>
|
||||
<span className="sm:hidden">Prox</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -152,7 +152,7 @@ Profissional responsável: IA Jurídica HGTX Codex`;
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-4xl max-h-[90vh]">
|
||||
<DialogContent className="max-w-[95vw] md:max-w-4xl max-h-[90vh]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>
|
||||
{selectedOpinion ? "Gerar Novo Modelo do Parecer" : "Novo Parecer Jurídico"}
|
||||
|
||||
Reference in New Issue
Block a user