Skip to content

Instantly share code, notes, and snippets.

@allipiopereira
Last active February 26, 2025 04:18
Show Gist options
  • Save allipiopereira/ad313c76c1de64b7a340bade932275ec to your computer and use it in GitHub Desktop.
Save allipiopereira/ad313c76c1de64b7a340bade932275ec to your computer and use it in GitHub Desktop.
// login-form.tsx
"use client";
import { useState } from "react";
import { useServerAction } from "zsa-react";
import { EbdoLogo } from "@/components/icons";
import { Spinner } from "@/components/ui/spinner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { loginAction } from "@/actions/login-actions";
export function LoginForm() {
const [step, setStep] = useState<"email" | "otp">("email");
const [email, setEmail] = useState<string>("");
const { isPending, execute, isError, error } = useServerAction(loginAction);
return (
<div className="flex h-screen flex-col items-center justify-center">
<div className="flex w-72 flex-col items-center">
<EbdoLogo className="h-24 w-24 fill-white" />
<h2 className="text-2xl font-semibold">Command Center</h2>
{step === "otp" && (
<div>
<span>Enviamos um código para seu email.</span>
<span>{email}</span>
</div>
)}
<form
className="mt-10 w-full space-y-6"
onSubmit={async (e) => {
e.preventDefault();
const form = e.currentTarget;
const formData = new FormData(form);
const [data, err] = await execute(formData, {
step,
email: email || (formData.get("email") as string),
});
if (err) {
console.log(err);
return;
}
console.log("Data: ", data);
setStep("otp");
setEmail(data?.email!);
form.reset();
}}
>
{step === "email" ? (
<Input placeholder="Email" name="email" />
) : (
<Input placeholder="OTP" name="otp" />
)}
{isError && (
<span className="text-red-500">
{error.fieldErrors?.email || error.fieldErrors?.otp}
</span>
)}
<Button type="submit" className="w-full" disabled={isPending}>
{isPending && <Spinner className="bg-white" />}
Continue
</Button>
</form>
</div>
</div>
);
}
// login-actions.tsx
"use server"
import z from "zod";
import {createServerAction} from 'zsa'
export const loginAction = createServerAction().input(
z.object({
step: z.enum(["email", "otp"]),
email: z.string().email(),
otp: z.string().min(6).max(6).regex(/^\d+$/).optional()
}),
{type: "formData"}
).handler(async ({input}) => {
if (input.step === "email") {
return {success: true, email: input.email};
}
if (input.step === "otp") {
return {success: true,};
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment