Pular para o conteúdo

Custom Hooks

Total: 9 hooks


Arquivo: src/hooks/use-auth.ts

Hook de autenticação. Busca user e account do Supabase. Gerencia login/logout.

CampoTipoDescrição
userIdstring | nullID do usuário
accountAccount | nullConta ativa
roleAccountRole | nullRole na conta ativa
accountsAccountWithRole[]Todas as contas
isLoadingbooleanEstado de carregamento
isAdminbooleanSe e platform admin
supportModeobject | nullSupport mode info
logout() => Promise<void>Função de logout
  1. No mount, busca supabase.auth.getUser()
  2. Se autenticado, busca /api/accounts para obter contas + active_account_id
  3. Determina conta ativa: cookie > store > primeira da lista
  4. Persiste em useAuthStore
  5. Escuta onAuthStateChange para redirect em SIGNED_OUT
  6. Logout: supabase.auth.signOut() + clearAuth + redirect
  • AppLayout (garante auth em toda area protegida)
  • SettingsLayout (botao logout)
  • TrackingPage
  • ProfileSettingsPage

Arquivo: src/hooks/use-api-query.ts

Hook genérico para GET requests com cache e AbortController.

ParamTipoDefaultDescrição
urlstring | nullrequiredURL da API. null desabilita a query.
options.enabledbooleantrueSe a query deve ser executada
options.refreshIntervalnumber0Intervalo de refresh em ms (0 = sem refresh)
options.refreshWhenHiddenbooleantrueSe deve fazer refresh quando tab está hidden
CampoTipoDescrição
dataT | nullDados retornados
isLoadingbooleanEstado de carregamento
errorstring | nullMensagem de erro
refetch() => Promise<void>Função para re-buscar dados
  • Faz fetch(url) com AbortController
  • Cancela request anterior ao fazer nova (abort)
  • Extrai json.data ?? json do response
  • Suporta refresh periodico via setInterval
  • Re-fetch automático quando url ou enabled mudam

Usado em praticamente TODAS as páginas do app (Dashboard, Chat, Contacts, Analytics, etc.).


Arquivo: src/hooks/use-api-mutation.ts

Hook genérico para POST/PUT/PATCH/DELETE requests com toast notifications.

ParamTipoDefaultDescrição
method"POST" | "PUT" | "PATCH" | "DELETE""POST"Método HTTP
successMessagestringundefinedMensagem de sucesso (toast)
onSuccess(data: unknown) => voidundefinedCallback após sucesso
CampoTipoDescrição
mutate(url: string, body?: TInput) => Promise<unknown | null>Função de mutação
isLoadingbooleanEstado de carregamento
errorstring | nullMensagem de erro
  • Faz fetch(url, { method, body: JSON.stringify(body) })
  • Em sucesso: toast success (se configurado) + chama onSuccess
  • Em erro: toast error + retorna null
  • Extrai data?.data ?? data do response

Usado em todas as operações de escrita (criar contato, atualizar template, excluir automação, etc.).


Arquivo: src/hooks/use-páginated-query.ts

Hook para queries com paginação offset-based (page + limit).

ParamTipoDefaultDescrição
fetcher(params) => Promise<PáginatedResult<T>>requiredFunção de fetch
options.initialPagenumber1Página inicial
options.initialLimitnumber20Itens por página
options.initialSearchstring""Busca inicial
CampoTipoDescrição
dataT[]Dados da página atual
totalnumberTotal de itens
pagenumberPágina atual
totalPagesnumberTotal de páginas
searchstringBusca atual
isLoadingbooleanEstado de carregamento
setPage(page: number) => voidNavegar para página
setSearch(search: string) => voidAlterar busca (reseta page=1)
refresh() => voidRecarregar página atual

Arquivo: src/hooks/use-cursor-páginated-query.ts

Hook para queries com paginação cursor-based (infinite scroll).

ParamTipoDefaultDescrição
baseUrlstringrequiredURL base da API
options.limitnumber20Itens por página
options.enabledbooleantrueSe a query deve ser executada
CampoTipoDescrição
dataT[]Todos os dados carregados (acumulados)
isLoadingbooleanLoading da primeira página
isLoadingMorebooleanLoading de páginas adicionais
hasMorebooleanSe existem mais itens
loadMore() => voidCarregar proxima página
refetch() => voidRecarregar desde o início
  • Acumula dados (append) ao fazer loadMore
  • refetch() reseta cursor e recarrega do zero
  • AbortController para cancelar requests pendentes
  • Response esperado: { data: T[], nextCursor: string | null, hasMore: boolean }
  • ContactsPage: lista de contatos com infinite scroll

Arquivo: src/hooks/use-realtime-conversations.ts

Hook para escutar mudancas em tempo real na tabela conversations via Supabase Realtime.

ParamTipoDescrição
accountIdstring | nullID da conta (filter)
onInsert(conversation) => voidCallback para nova conversa
onUpdate(conversation) => voidCallback para conversa atualizada
  • Cria channel Supabase: conversations:{accountId}
  • Escuta postgres_changes (INSERT + UPDATE) na tabela conversations
  • Filtra por account_id=eq.{accountId}
  • Cleanup: remove channel no unmount
  • ChatPage: refetch conversas em INSERT e UPDATE

Arquivo: src/hooks/use-realtime-messages.ts

Hook para escutar mudancas em tempo real na tabela messages via Supabase Realtime.

ParamTipoDescrição
conversationIdstring | nullID da conversa ativa
  • Cria channel Supabase: messages:{conversationId}
  • Escuta postgres_changes (INSERT + UPDATE) na tabela messages
  • INSERT: addMessage no chat store
  • UPDATE: updateMessageStatus no chat store
  • Cleanup: remove channel no unmount
  • ChatPage: adiciona mensagens em tempo real e atualiza status

Arquivo: src/hooks/use-onboarding.ts

Hook para gerenciar checklist de onboarding no dashboard.

ParamTipoDescrição
statsOnboardingStats | nullStats do dashboard
profilesOnboardingProfile[]WhatsApp profiles
accountIdstring | nullID da conta
CampoTipoDescrição
isDismissedbooleanSe usuário dismissou o checklist
stepsOnboardingStep[]5 steps com id, label, href, completed
progressnumberQuantos steps completos (0-5)
isCompletebooleanSe todos os 5 steps estão completos
dismiss() => voidFunção para dismissar
  1. Conta criada — sempre true
  2. WhatsApp conectado — profile com status “connected”
  3. Primeiro template criado — kpi.templates > 0
  4. Contatos importados — kpi.contacts > 0
  5. Primeira campanha enviada — alguma campanha com status != “draft”
  • Dismiss salvo em localStorage com key x17-onboarding-dismissed-{accountId}

Arquivo: src/hooks/use-undo-redo.ts

Hook para undo/redo no editor de automações.

ParamTipoDescrição
setNodes(updater) => voidSetter de nodes do ReactFlow
setEdges(updater) => voidSetter de edges do ReactFlow
CampoTipoDescrição
takeSnapshot(nodes, edges) => voidSalva estado atual no histórico
undo() => voidDesfaz última ação
redo() => voidRefaz última ação desfeita
canUndobooleanSe pode desfazer
canRedobooleanSe pode refazer
  • Usa useRef para histórico (past + future stacks)
  • MAX_HISTORY = 50 snapshots
  • takeSnapshot: push no past, limpa future
  • undo: pop do past, push no future, aplica estado
  • redo: pop do future, push no past, aplica estado
  • Usa structuredClone para deep copy
  • AutomationEditorPage: Ctrl+Z / Ctrl+Shift+Z / Ctrl+Y
  • Chamado antes de cada operação destrutiva (add node, delete node, drop, connect)