Melhora filtros no desktop e adiciona ícone em Todos os tickets
This commit is contained in:
parent
11cd4927e9
commit
b00e52475f
2 changed files with 99 additions and 2 deletions
|
|
@ -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" },
|
||||
],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue