sistema-de-chamados/src/components/login-form.tsx

124 lines
3.9 KiB
TypeScript

"use client"
import { useState } from "react"
import { useRouter, useSearchParams } from "next/navigation"
import Link from "next/link"
import { Loader2 } from "lucide-react"
import { toast } from "sonner"
import { cn } from "@/lib/utils"
import { signIn } from "@/lib/auth-client"
import { Button } from "@/components/ui/button"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldSeparator,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
type LoginFormProps = React.ComponentProps<"form"> & {
callbackUrl?: string
disabled?: boolean
}
export function LoginForm({ className, callbackUrl, disabled = false, ...props }: LoginFormProps) {
const router = useRouter()
const searchParams = useSearchParams()
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
const [isSubmitting, setIsSubmitting] = useState(false)
const destination = callbackUrl ?? searchParams?.get("callbackUrl") ?? "/dashboard"
async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault()
if (isSubmitting || disabled) return
if (!email || !password) {
toast.error("Informe e-mail e senha")
return
}
setIsSubmitting(true)
try {
const result = await signIn.email({ email, password, callbackURL: destination })
if (result?.error) {
toast.error("E-mail ou senha inválidos")
setIsSubmitting(false)
return
}
toast.success("Sessão iniciada com sucesso")
router.replace(destination)
} catch (error) {
console.error("Erro ao autenticar", error)
toast.error("Não foi possível entrar. Tente novamente")
setIsSubmitting(false)
}
}
return (
<form
onSubmit={handleSubmit}
className={cn("flex flex-col gap-6", disabled && "pointer-events-none opacity-70", className)}
{...props}
>
<FieldGroup>
<div className="flex flex-col items-center gap-1 text-center">
<h1 className="text-2xl font-bold">Acesse sua conta</h1>
<p className="text-muted-foreground text-sm text-balance">
Informe seu e-mail corporativo e senha para continuar atendendo os chamados.
</p>
</div>
<Field>
<FieldLabel htmlFor="email">E-mail</FieldLabel>
<Input
id="email"
type="email"
placeholder="agente@sistema.dev"
autoComplete="email"
value={email}
onChange={(event) => setEmail(event.target.value)}
disabled={isSubmitting || disabled}
required
/>
</Field>
<Field>
<div className="flex items-center">
<FieldLabel htmlFor="password">Senha</FieldLabel>
<Link
href="/recuperar"
className="ml-auto text-sm underline-offset-4 hover:underline"
>
Esqueceu a senha?
</Link>
</div>
<Input
id="password"
type="password"
autoComplete="current-password"
value={password}
onChange={(event) => setPassword(event.target.value)}
disabled={isSubmitting || disabled}
required
/>
</Field>
<Field>
<Button type="submit" disabled={isSubmitting || disabled} className="gap-2">
{(isSubmitting || disabled) && <Loader2 className="size-4 animate-spin" />}
Entrar
</Button>
</Field>
<FieldSeparator />
<Field>
<div className="space-y-1 text-left">
<p className="text-sm font-semibold">Primeiro acesso?</p>
<FieldDescription className="text-sm">
Fale com o nosso suporte por telefone ou e-mail para receber um convite e definir sua senha inicial.
</FieldDescription>
</div>
</Field>
</FieldGroup>
</form>
)
}