sistema-de-chamados/apps/desktop/src/chat/index.tsx
esdrasrenan c51b08f127 feat(desktop): implementa Convex React subscriptions para chat em tempo real
- Adiciona ConvexMachineProvider para autenticacao via machine token
- Cria hooks customizados (useMachineSessions, useMachineMessages, etc)
- Refatora ChatWidget e ChatHubWidget para usar useQuery/useMutation
- Remove polling e dependencia de Tauri events para mensagens
- Adiciona copia local dos arquivos _generated do Convex
- Remove componentes obsoletos (ChatSessionItem, ChatSessionList)

Beneficios:
- Tempo real verdadeiro via WebSocket (sem polling)
- Melhor escalabilidade e performance
- Codigo mais simples e maintivel
- Consistencia de estado entre multiplas janelas

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 23:40:34 -03:00

65 lines
2 KiB
TypeScript

import { ConvexProvider } from "convex/react"
import { ChatWidget } from "./ChatWidget"
import { ChatHubWidget } from "./ChatHubWidget"
import { ConvexMachineProvider, useConvexMachine } from "./ConvexMachineProvider"
import { Loader2 } from "lucide-react"
function ChatAppContent() {
const { client, isReady, error } = useConvexMachine()
// Obter ticketId e ticketRef da URL
const params = new URLSearchParams(window.location.search)
const ticketId = params.get("ticketId")
const ticketRef = params.get("ticketRef")
const isHub = params.get("hub") === "true"
// Aguardar cliente Convex estar pronto
if (!isReady || !client) {
if (error) {
return (
<div className="pointer-events-none flex h-full w-full items-end justify-end bg-transparent p-2">
<div className="pointer-events-auto flex items-center gap-2 rounded-full bg-red-100 px-4 py-2 text-red-600 shadow-lg">
<span className="text-sm font-medium">Erro: {error}</span>
</div>
</div>
)
}
return (
<div className="pointer-events-none flex h-full w-full items-end justify-end bg-transparent p-2">
<div className="pointer-events-auto flex items-center gap-2 rounded-full bg-slate-200 px-4 py-2 text-slate-600 shadow-lg">
<Loader2 className="size-4 animate-spin" />
<span className="text-sm font-medium">Conectando...</span>
</div>
</div>
)
}
// Modo hub - lista de todas as sessoes
if (isHub || !ticketId) {
return (
<ConvexProvider client={client}>
<ChatHubWidget />
</ConvexProvider>
)
}
// Modo chat - conversa de um ticket especifico
return (
<ConvexProvider client={client}>
<ChatWidget ticketId={ticketId} ticketRef={ticketRef ? Number(ticketRef) : undefined} />
</ConvexProvider>
)
}
export function ChatApp() {
return (
<ConvexMachineProvider>
<ChatAppContent />
</ConvexMachineProvider>
)
}
export { ChatWidget }
export { ChatHubWidget }
export * from "./types"