"use client" import * as React from "react" import { Area, AreaChart, CartesianGrid, XAxis } from "recharts" import { useQuery } from "convex/react" import { api } from "@/convex/_generated/api" import type { Id } from "@/convex/_generated/dataModel" import { useAuth } from "@/lib/auth-client" import { DEFAULT_TENANT_ID } from "@/lib/constants" import { useIsMobile } from "@/hooks/use-mobile" import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card" import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent, } from "@/components/ui/chart" import { Skeleton } from "@/components/ui/skeleton" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { ToggleGroup, ToggleGroupItem, } from "@/components/ui/toggle-group" export const description = "Distribuição semanal de tickets por canal" export function ChartAreaInteractive() { const [mounted, setMounted] = React.useState(false) const isMobile = useIsMobile() const [timeRange, setTimeRange] = React.useState("7d") const { session, convexUserId } = useAuth() const tenantId = session?.user.tenantId ?? DEFAULT_TENANT_ID React.useEffect(() => { setMounted(true) }, []) React.useEffect(() => { if (isMobile) { setTimeRange("7d") } }, [isMobile]) const report = useQuery( api.reports.ticketsByChannel, convexUserId ? ({ tenantId, viewerId: convexUserId as Id<"users">, range: timeRange }) : "skip" ) const channels = React.useMemo(() => report?.channels ?? [], [report]) const palette = React.useMemo( () => [ "var(--chart-1)", "var(--chart-2)", "var(--chart-3)", "var(--chart-4)", "var(--chart-5)", ], [] ) const chartConfig = React.useMemo(() => { const entries = channels.map((channel: string, index: number) => [ channel, { label: channel .toLowerCase() .replace(/_/g, " ") .replace(/\b\w/g, (letter) => letter.toUpperCase()), color: palette[index % palette.length], }, ]) return Object.fromEntries(entries) as ChartConfig }, [channels, palette]) const chartData = React.useMemo(() => { if (!report?.points) return [] return report.points.map((point: { date: string; values: Record }) => { const entry: Record = { date: point.date } for (const channel of channels) { entry[channel] = point.values[channel] ?? 0 } return entry }) }, [channels, report]) if (!mounted) { return (
Carregando gráfico...
) } return ( Entrada de tickets por canal Distribuição dos canais nos últimos {timeRange.replace("d", " dias")} Período: {timeRange} 90 dias 30 dias 7 dias {report === undefined ? (
) : chartData.length === 0 || channels.length === 0 ? (
Sem dados suficientes no período selecionado.
) : ( {channels.map((channel: string) => ( ))} { const date = new Date(value) return date.toLocaleDateString("pt-BR", { month: "short", day: "2-digit", }) }} /> new Date(value).toLocaleDateString("pt-BR", { day: "2-digit", month: "long", }) } indicator="dot" /> } /> {channels .slice() .reverse() .map((channel: string) => ( ))} )}
) } export default ChartAreaInteractive