diff --git a/src/components/tickets/tickets-filters.tsx b/src/components/tickets/tickets-filters.tsx index d744e32..37da284 100644 --- a/src/components/tickets/tickets-filters.tsx +++ b/src/components/tickets/tickets-filters.tsx @@ -1,7 +1,8 @@ "use client" import { useEffect, useMemo, useState } from "react" -import { IconFilter, IconRefresh } from "@tabler/icons-react" +import { IconCalendar, IconFilter, IconRefresh } from "@tabler/icons-react" +import type { DateRange } from "react-day-picker" import { ticketChannelSchema, @@ -13,10 +14,11 @@ import { defaultTicketFilters } from "@/lib/ticket-filters" export type { TicketFiltersState } export { defaultTicketFilters } + import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" +import { Calendar } from "@/components/ui/calendar" import { Popover, PopoverContent, @@ -29,7 +31,6 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select" -import { DatePicker } from "@/components/ui/date-picker" type QueueOption = string @@ -79,6 +80,93 @@ const channelOptions = ticketChannelSchema.options.map((channel) => ({ }[channel], })) +function strToDate(value?: string | null): Date | undefined { + if (!value) return undefined + const [y, m, d] = value.split("-").map(Number) + if (!y || !m || !d) return undefined + return new Date(y, m - 1, d) +} + +function dateToStr(value?: Date): string | null { + if (!value) return null + const y = value.getFullYear() + const m = String(value.getMonth() + 1).padStart(2, "0") + const d = String(value.getDate()).padStart(2, "0") + return `${y}-${m}-${d}` +} + +function formatPtBR(value?: Date): string { + return value ? value.toLocaleDateString("pt-BR") : "" +} + +type DateRangeButtonProps = { + from: string | null + to: string | null + onChange: (next: { from: string | null; to: string | null }) => void + className?: string +} + +function DateRangeButton({ from, to, onChange, className }: DateRangeButtonProps) { + const range: DateRange | undefined = useMemo( + () => ({ + from: strToDate(from), + to: strToDate(to), + }), + [from, to] + ) + + const label = + range?.from && range?.to + ? `${formatPtBR(range.from)} - ${formatPtBR(range.to)}` + : "Período" + + const handleSelect = (next?: DateRange) => { + if (!next?.from && !next?.to) { + onChange({ from: null, to: null }) + return + } + + if (next?.from && !next?.to) { + const single = dateToStr(next.from) + if (from && to && from === to && single === from) { + onChange({ from: null, to: null }) + return + } + onChange({ from: single, to: single }) + return + } + + const nextFrom = dateToStr(next?.from) ?? null + const nextTo = dateToStr(next?.to) ?? nextFrom + onChange({ from: nextFrom, to: nextTo }) + } + + return ( + + + + + + + + + ) +} + export function TicketsFilters({ onChange, queues = [], @@ -136,227 +224,215 @@ export function TicketsFilters({ return (
-
-
- setPartial({ search: event.target.value })} - className="md:max-w-sm" - /> - {canUseAdvancedFilters ? ( - - ) : null} - {canUseAdvancedFilters ? ( - - ) : null} - -
-
- {canUseAdvancedFilters ? ( - - ) : null} - - - - +
+
+
+
+ setPartial({ search: event.target.value })} + className="w-full rounded-xl border-slate-300 bg-white/90" + /> +
+
+ + + + + +
+

Status

+ +
+
+

Prioridade

+ +
+
+

Canal

+ +
+
+
- - -
-

- Status -

- -
-
-

- Prioridade -

- -
-
-

- Canal -

- -
-
- - -
-
-
-
-

Período

-
-
-
- - setPartial({ dateFrom: value })} - placeholder="Selecionar data" - /> +
-
- - setPartial({ dateTo: value })} - placeholder="Selecionar data" +
+ {canUseAdvancedFilters && ( + + )} + {canUseAdvancedFilters && ( + + )} + + {canUseAdvancedFilters && ( + + )} +
+
+ + + setPartial({ dateFrom: from, dateTo: to })} + className="w-full" />
-
+
{activeFilters.length > 0 && (
{activeFilters.map((chip) => ( - + {chip} ))} diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx index 8ab6bb4..91604aa 100644 --- a/src/components/ui/calendar.tsx +++ b/src/components/ui/calendar.tsx @@ -103,18 +103,32 @@ function CalendarDropdown(props: CalendarDropdownProps) { export function Calendar({ className, classNames, + styles, + modifiersClassNames, showOutsideDays = true, captionLayout = "dropdown", startMonth, endMonth, ...props }: CalendarProps) { + const mergedStyles = React.useMemo( + () => ({ + day_selected: { backgroundColor: "transparent" }, + day_range_start: { backgroundColor: "transparent" }, + day_range_end: { backgroundColor: "transparent" }, + day_range_middle: { backgroundColor: "transparent" }, + ...(styles ?? {}), + }), + [styles] + ) + return (