+
diff --git a/src/features/auth/components/auth-code-form.tsx b/src/features/auth/components/auth-code-form.tsx
new file mode 100644
index 0000000..d0a734b
--- /dev/null
+++ b/src/features/auth/components/auth-code-form.tsx
@@ -0,0 +1,153 @@
+"use client"
+
+import { Lock } from "lucide-react"
+import Link from "next/link"
+import { Controller, useForm } from "react-hook-form"
+import { zodResolver } from "@hookform/resolvers/zod"
+import * as z from "zod"
+
+import { cn } from "@/shared/utils"
+import { Button } from "@/shared/ui/button"
+import {
+ Field,
+ FieldDescription,
+ FieldError,
+ FieldGroup,
+ FieldLabel,
+ FieldSeparator,
+} from "@/shared/ui/field"
+import { Input } from "@/shared/ui/input"
+
+const codeSchema = z.object({
+ code: z
+ .string()
+ .trim()
+ .regex(/^\d{6}$/, { message: "Enter the 6-digit code" }),
+})
+
+type AuthCodeFormProps = React.ComponentProps<"div"> & {
+ email: string
+ mode: "login" | "signup"
+ onDifferentAccount?: () => void
+ onResendCode?: () => void
+ onSubmitCode?: (code: string) => void | Promise
+}
+
+export function AuthCodeForm({
+ className,
+ email,
+ mode,
+ onDifferentAccount,
+ onResendCode,
+ onSubmitCode,
+ ...props
+}: AuthCodeFormProps) {
+ const form = useForm>({
+ resolver: zodResolver(codeSchema),
+ defaultValues: {
+ code: "",
+ },
+ })
+
+ const actionLabel = mode === "login" ? "Log in" : "Sign up"
+ const flowLabel = mode === "login" ? "login" : "sign up"
+ const switchLabel =
+ mode === "login"
+ ? "Log in to a different account"
+ : "Sign up with a different account"
+
+ const onSubmit = async (data: z.infer) => {
+ await onSubmitCode?.(data.code)
+ }
+
+ return (
+
+
+
+ Check your inbox
+
+
+ Enter the 6-digit code we sent to{" "}
+ {email} to finish
+ your {flowLabel}.
+
+
+
+
+
+
+ {onDifferentAccount ? (
+
+ ) : (
+
+ {switchLabel}
+
+ )}
+
+
+
+ Use the code sent to your email address to continue.
+
+
+ )
+}
diff --git a/src/features/auth/components/auth-google-button.tsx b/src/features/auth/components/auth-google-button.tsx
new file mode 100644
index 0000000..476291f
--- /dev/null
+++ b/src/features/auth/components/auth-google-button.tsx
@@ -0,0 +1,42 @@
+import { Button } from "@/shared/ui/button"
+
+function GoogleMark() {
+ return (
+
+ )
+}
+
+export function AuthGoogleButton({ label }: { label: string }) {
+ return (
+
+ )
+}
diff --git a/src/features/auth/components/login-form.tsx b/src/features/auth/components/login-form.tsx
index 7f6dec8..2291b24 100644
--- a/src/features/auth/components/login-form.tsx
+++ b/src/features/auth/components/login-form.tsx
@@ -1,126 +1,115 @@
"use client"
+import { useState } from "react"
import { cn } from "@/shared/utils"
import { Button } from "@/shared/ui/button"
-import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
-} from "@/shared/ui/card"
import {
Field,
FieldDescription,
+ FieldError,
FieldGroup,
FieldLabel,
+ FieldSeparator,
} from "@/shared/ui/field"
import { Input } from "@/shared/ui/input"
import { Controller, useForm } from "react-hook-form"
import * as z from "zod"
import { zodResolver } from "@hookform/resolvers/zod"
-import { auth } from "@/infrastructure/auth/auth"
-import { authClient } from "@/infrastructure/auth/client"
import Link from "next/link"
+import { AuthCodeForm } from "@/features/auth/components/auth-code-form"
+import { AuthGoogleButton } from "@/features/auth/components/auth-google-button"
const formSchema = z.object({
email: z.email({
message: "Invalid email address",
}),
- password: z
- .string({
- message: "Password is required",
- })
- .min(8, { error: "Must be more than 8 characters" }),
})
export function LoginForm({
className,
...props
}: React.ComponentProps<"div">) {
+ const [loginEmail, setLoginEmail] = useState(null)
const form = useForm>({
resolver: zodResolver(formSchema),
defaultValues: {
email: "",
- password: "",
},
})
const onSubmit = async (data: z.infer) => {
- try {
- await authClient.signIn.email(data)
- } catch (error) {
- console.error(error)
- }
+ setLoginEmail(data.email)
+ }
+
+ if (loginEmail) {
+ return (
+ setLoginEmail(null)}
+ className={className}
+ {...props}
+ />
+ )
}
return (
-
-
-
- Login to your account
-
- Enter your email below to login to your account
-
-
-
-