Melhora filtros no desktop e adiciona ícone em Todos os tickets

This commit is contained in:
Esdras Renan 2025-11-13 15:06:00 -03:00
parent 11cd4927e9
commit b00e52475f
2 changed files with 99 additions and 2 deletions

View file

@ -79,7 +79,7 @@ const navigation: NavigationGroup[] = [
icon: Ticket,
requiredRole: "staff",
children: [
{ title: "Todos os tickets", url: "/tickets", requiredRole: "staff" },
{ title: "Todos os tickets", url: "/tickets", icon: Ticket, requiredRole: "staff" },
{ title: "Resolvidos", url: "/tickets/resolved", icon: ShieldCheck, requiredRole: "staff" },
],
},

View file

@ -5,6 +5,7 @@ import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { DatePicker } from "@/components/ui/date-picker"
export type PortalTicketFiltersState = {
queue: string | null
@ -62,6 +63,102 @@ export function PortalTicketFilters({
onFiltersChange(partial)
}
const hasAnyFilterApplied =
Boolean(filters.queue) ||
Boolean(filters.company) ||
Boolean(filters.categoryId) ||
Boolean(filters.assigneeId) ||
Boolean(filters.dateFrom) ||
Boolean(filters.dateTo) ||
filters.status !== "active" ||
filters.sort !== "recent"
if (hideAdvancedFilters) {
return (
<div className="rounded-2xl border border-slate-200 bg-white p-4 shadow-sm">
<div className="flex flex-col gap-4 lg:flex-row lg:items-stretch">
<div className="flex flex-1 flex-wrap gap-3">
<Select
value={filters.categoryId ?? ALL_VALUE}
onValueChange={(value) => handleChange({ categoryId: value === ALL_VALUE ? null : value })}
>
<SelectTrigger className="min-w-[200px] flex-1 rounded-xl border-slate-300 bg-slate-50/80 focus:ring-neutral-300">
<SelectValue placeholder="Categoria" />
</SelectTrigger>
<SelectContent>
<SelectItem value={ALL_VALUE}>Todas as categorias</SelectItem>
{categories.map((category) => (
<SelectItem key={category.id} value={category.id}>
{category.name}
</SelectItem>
))}
</SelectContent>
</Select>
<Select
value={filters.status}
onValueChange={(value) => handleChange({ status: value as PortalTicketFiltersState["status"] })}
>
<SelectTrigger className="min-w-[160px] flex-1 rounded-xl border-slate-300 bg-slate-50/80 focus:ring-neutral-300 lg:flex-none">
<SelectValue placeholder="Status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="active">Em andamento</SelectItem>
<SelectItem value="resolved">Concluídos</SelectItem>
</SelectContent>
</Select>
<Select
value={filters.sort}
onValueChange={(value) => handleChange({ sort: value as PortalTicketFiltersState["sort"] })}
>
<SelectTrigger className="min-w-[180px] flex-1 rounded-xl border-slate-300 bg-slate-50/80 focus:ring-neutral-300 lg:flex-none">
<SelectValue placeholder="Ordenação" />
</SelectTrigger>
<SelectContent>
<SelectItem value="recent">Mais recentes</SelectItem>
<SelectItem value="oldest">Mais antigos</SelectItem>
</SelectContent>
</Select>
</div>
<div className="w-full rounded-2xl border border-slate-200 bg-slate-50/70 p-4 shadow-inner lg:max-w-md">
<p className="text-xs font-semibold uppercase tracking-wide text-neutral-500">Período</p>
<div className="mt-3 grid gap-3 sm:grid-cols-2">
<div className="space-y-1">
<p className="text-xs font-semibold uppercase tracking-wide text-neutral-500">A partir de</p>
<DatePicker
value={filters.dateFrom}
onChange={(value) => handleChange({ dateFrom: value })}
placeholder="Selecionar data"
className="rounded-xl border-slate-300 bg-white"
/>
</div>
<div className="space-y-1">
<p className="text-xs font-semibold uppercase tracking-wide text-neutral-500">Até</p>
<DatePicker
value={filters.dateTo}
onChange={(value) => handleChange({ dateTo: value })}
placeholder="Selecionar data"
className="rounded-xl border-slate-300 bg-white"
/>
</div>
</div>
</div>
</div>
{hasAnyFilterApplied && (
<div className="mt-3 flex flex-wrap gap-2">
<Button
variant="ghost"
size="sm"
className="gap-2 rounded-full px-4 py-2 text-sm font-medium text-neutral-700"
onClick={onReset}
>
<IconRefresh className="size-4" /> Resetar
</Button>
</div>
)}
</div>
)
}
return (
<div className="rounded-2xl border border-slate-200 bg-white p-4 shadow-sm">
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
@ -184,7 +281,7 @@ export function PortalTicketFilters({
</div>
</PopoverContent>
</Popover>
{(filters.queue || filters.company || filters.categoryId || filters.assigneeId || filters.dateFrom || filters.dateTo || filters.status !== "active" || filters.sort !== "recent") && (
{hasAnyFilterApplied && (
<Button
variant="ghost"
size="sm"