"use client" import { useQuery } from "convex/react" import { IconMoodSmile, IconStars, IconMessageCircle2 } from "@tabler/icons-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 { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Skeleton } from "@/components/ui/skeleton" import { Badge } from "@/components/ui/badge" import { useState } from "react" import { Bar, BarChart, CartesianGrid, XAxis } from "recharts" import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart" import { Button } from "@/components/ui/button" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group" import { usePersistentCompanyFilter } from "@/lib/use-company-filter" function formatScore(value: number | null) { if (value === null) return "—" return value.toFixed(2) } export function CsatReport() { const [companyId, setCompanyId] = usePersistentCompanyFilter("all") const [timeRange, setTimeRange] = useState("90d") const { session, convexUserId, isStaff } = useAuth() const tenantId = session?.user.tenantId ?? DEFAULT_TENANT_ID const enabled = Boolean(isStaff && convexUserId) const data = useQuery( api.reports.csatOverview, enabled ? ({ tenantId, viewerId: convexUserId as Id<"users">, range: timeRange, companyId: companyId === "all" ? undefined : (companyId as Id<"companies">) }) : "skip" ) const companies = useQuery(api.companies.list, enabled ? { tenantId, viewerId: convexUserId as Id<"users"> } : "skip") as Array<{ id: Id<"companies">; name: string }> | undefined if (!data) { return (
{Array.from({ length: 3 }).map((_, index) => ( ))}
) } return (
CSAT médio Média das respostas recebidas.
90 dias 30 dias 7 dias
{formatScore(data.averageScore)}
Total de respostas Avaliações coletadas nos tickets. {data.totalSurveys} Últimas avaliações Até 10 registros mais recentes. {data.recent.length === 0 ? (

Ainda não coletamos nenhuma avaliação.

) : ( data.recent.map((item: { ticketId: string; reference: number; score: number; receivedAt: number }) => (
#{item.reference} Nota {item.score}
)) )}
Distribuição das notas Frequência de respostas para cada valor na escala de 1 a 5. {data.totalSurveys === 0 ? (

Sem respostas no período.

) : ( ({ score: `Nota ${d.score}`, total: d.total }))}> } /> )}
) }