'use client'; import * as React from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import Image from 'next/image'; import { useAuth } from '@/lib/auth/auth-context'; import { useTenantTheme, TenantThemeProvider } from '@/lib/theme/theme-provider'; import { ApiError } from '@/lib/api/client'; import { loginSchema, type LoginFormValues } from '@/lib/validators/auth'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { FormField } from '@/components/ui/form-field'; import Link from 'next/link'; type LoginArea = 'tenant' | 'master'; function GenericInvalidCredentialsMessage(): string { return 'E-mail ou senha inválidos.'; } function LoginFormInner() { const router = useRouter(); const searchParams = useSearchParams(); const { loginMaster, loginTenant } = useAuth(); const { theme } = useTenantTheme(); // Estratégia de detecção de tipo de login (Etapa 13): o backend expõe // dois endpoints separados (`/auth/master/login` e `/auth/tenant/login`, // sem detecção automática por e-mail — ver observações da Etapa 13 no // controle de progresso). Escolhido um toggle explícito em vez de dois // formulários separados por ser a opção mais simples de implementar e // mais clara para o usuário; "tenant" é o padrão porque é o público // majoritário (clientes), master é uso interno raro. const [area, setArea] = React.useState('tenant'); const [submitError, setSubmitError] = React.useState(null); const { register, handleSubmit, formState: { errors, isSubmitting }, } = useForm({ resolver: zodResolver(loginSchema) }); const onSubmit = async (values: LoginFormValues) => { setSubmitError(null); try { if (area === 'master') { await loginMaster(values.email, values.senha); } else { await loginTenant(values.email, values.senha); } const redirectParam = searchParams.get('redirect'); const fallback = area === 'master' ? '/master/dashboard' : '/app/dashboard'; router.push(redirectParam && redirectParam.startsWith('/') ? redirectParam : fallback); } catch (err) { if (err instanceof ApiError && err.statusCode === 401) { setSubmitError(GenericInvalidCredentialsMessage()); } else if (err instanceof ApiError) { setSubmitError(err.message); } else { setSubmitError('Não foi possível conectar. Tente novamente.'); } } }; return (
{theme?.logoUrl ? ( {theme.nome} ) : null}

{theme?.nome ?? 'SeConectai Vendas'}

Entre com seu e-mail e senha

{submitError && (

{submitError}

)} Esqueci minha senha
); } export function LoginForm() { const searchParams = useSearchParams(); const tenantId = searchParams.get('tenant'); return ( ); }