"use client"; import { createFileRoute } from "@tanstack/react-router"; import { useState, useEffect } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { IMaskInput } from "react-imask"; import { toast } from "sonner"; import { Loader2, LogOut } from "lucide-react"; import { supabase } from "@/integrations/supabase/client"; import { useAuth } from "@/hooks/use-auth"; import { useProfile } from "@/hooks/use-profile"; import { translateAuthError } from "@/lib/auth-errors"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Skeleton } from "@/components/ui/skeleton"; export const Route = createFileRoute("/painel/configuracoes")({ component: SettingsPage, }); const profileSchema = z.object({ full_name: z.string().min(2, "Informe seu nome completo.").max(120), company_name: z.string().max(120).optional().or(z.literal("")), cpf_cnpj: z.string().optional().or(z.literal("")), phone: z.string().optional().or(z.literal("")), }); type ProfileForm = z.infer; function SettingsPage() { const { user } = useAuth(); const { data: profile, isLoading } = useProfile(); const queryClient = useQueryClient(); const { register, handleSubmit, setValue, watch, reset, formState: { errors } } = useForm({ resolver: zodResolver(profileSchema), }); useEffect(() => { if (profile) { reset({ full_name: profile.full_name, company_name: profile.company_name ?? "", cpf_cnpj: profile.cpf_cnpj ?? "", phone: profile.phone ?? "", }); } }, [profile, reset]); const cpfCnpj = watch("cpf_cnpj") || ""; const phone = watch("phone") || ""; const cpfCnpjDigits = cpfCnpj.replace(/\D/g, ""); const cpfCnpjMask = cpfCnpjDigits.length > 11 ? "00.000.000/0000-00" : "000.000.000-00"; const updateProfile = useMutation({ mutationFn: async (data: ProfileForm) => { if (!user) throw new Error("Sem sessão"); const { error } = await supabase .from("profiles") .update({ full_name: data.full_name, company_name: data.company_name || null, cpf_cnpj: data.cpf_cnpj || null, phone: data.phone || null, }) .eq("id", user.id); if (error) throw error; }, onSuccess: () => { toast.success("Perfil atualizado com sucesso."); queryClient.invalidateQueries({ queryKey: ["profile"] }); }, onError: (e: Error) => toast.error(translateAuthError(e.message)), }); const signOutAll = async () => { const { error } = await supabase.auth.signOut({ scope: "global" }); if (error) toast.error(translateAuthError(error.message)); else toast.success("Saiu de todos os dispositivos."); }; if (isLoading) return ; return (

Configurações

Gerencie seu perfil e segurança.

Perfil

Informações para faturamento e suporte.

updateProfile.mutate(d))} className="space-y-4">
{errors.full_name &&

{errors.full_name.message}

}
setValue("cpf_cnpj", v as string, { shouldValidate: true })} placeholder="000.000.000-00" className="flex h-10 w-full rounded-lg border border-input bg-transparent px-3 py-2 text-sm focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20" />
setValue("phone", v as string, { shouldValidate: true })} placeholder="(11) 99999-9999" className="flex h-10 w-full rounded-lg border border-input bg-transparent px-3 py-2 text-sm focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20" />

Segurança

Para alterar sua senha, use o link de recuperação no e-mail.

); }