diff options
| author | Deepanshu Mishra <d4deepanshu723@gmail.com> | 2025-06-23 22:51:34 +0530 |
|---|---|---|
| committer | Deepanshu Mishra <d4deepanshu723@gmail.com> | 2025-06-23 22:51:34 +0530 |
| commit | 8bcd226bdb4eb3468df0590dbe6d3d8d68b2acbd (patch) | |
| tree | f380594174a4816010980246ac2641ce483644ec /apps/web/src/app/auth/login/page.tsx | |
| parent | 13817a5ff847762a3ac4eb7cb09d17012b59e520 (diff) | |
| download | opencut-8bcd226bdb4eb3468df0590dbe6d3d8d68b2acbd.tar.gz | |
Added google auth and some auth page ui optimisations
Diffstat (limited to 'apps/web/src/app/auth/login/page.tsx')
| -rw-r--r-- | apps/web/src/app/auth/login/page.tsx | 134 |
1 files changed, 99 insertions, 35 deletions
diff --git a/apps/web/src/app/auth/login/page.tsx b/apps/web/src/app/auth/login/page.tsx index 5eadb85c..ebf2eb3f 100644 --- a/apps/web/src/app/auth/login/page.tsx +++ b/apps/web/src/app/auth/login/page.tsx @@ -1,7 +1,7 @@ "use client"; -import { useSearchParams, useRouter } from "next/navigation"; -import { authClient } from "@/lib/auth-client"; +import { useRouter } from "next/navigation"; +import { signIn } from "@/lib/auth-client"; import { Button } from "@/components/ui/button"; import { Card, @@ -13,81 +13,145 @@ import { import { Suspense, useState } from "react"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; +import { Separator } from "@/components/ui/separator"; import Link from "next/link"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { ArrowLeft, Loader2 } from "lucide-react"; +import { GoogleIcon } from "@/components/icons"; function LoginForm() { - const searchParams = useSearchParams(); const router = useRouter(); - const redirectUrl = searchParams.get("redirect"); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState<string | null>(null); + const [isEmailLoading, setIsEmailLoading] = useState(false); + const [isGoogleLoading, setIsGoogleLoading] = useState(false); const handleLogin = async () => { setError(null); - const { error } = await authClient.signIn.email({ + setIsEmailLoading(true); + + const { error } = await signIn.email({ email, password, }); if (error) { setError(error.message || "An unexpected error occurred."); + setIsEmailLoading(false); return; } - router.push(redirectUrl || "/"); + router.push("/editor"); + }; + + const handleGoogleLogin = async () => { + setError(null); + setIsGoogleLoading(true); + + try { + await signIn.social({ + provider: "google", + }); + router.push("/editor"); + } catch (error) { + setError("Failed to sign in with Google. Please try again."); + setIsGoogleLoading(false); + } }; + const isAnyLoading = isEmailLoading || isGoogleLoading; + return ( - <div className="flex flex-col space-y-4"> + <div className="flex flex-col space-y-6"> {error && ( <Alert variant="destructive"> <AlertTitle>Error</AlertTitle> <AlertDescription>{error}</AlertDescription> </Alert> )} - <div className="space-y-2"> - <Label htmlFor="email">Email</Label> - <Input - id="email" - type="email" - placeholder="m@example.com" - value={email} - onChange={(e) => setEmail(e.target.value)} - /> + + <Button + onClick={handleGoogleLogin} + variant="outline" + size="lg" + disabled={isAnyLoading} + > + {isGoogleLoading ? <Loader2 className="animate-spin" /> : (<GoogleIcon />)} Continue with Google + </Button> + <div className="relative"> + <div className="absolute inset-0 flex items-center"> + <Separator className="w-full" /> + </div> + <div className="relative flex justify-center text-xs uppercase"> + <span className="bg-background px-2 text-muted-foreground">Or continue with</span> + </div> </div> - <div className="space-y-2"> - <Label htmlFor="password">Password</Label> - <Input - id="password" - type="password" - value={password} - onChange={(e) => setPassword(e.target.value)} - /> + <div className="space-y-4"> + <div className="space-y-2"> + <Label htmlFor="email">Email</Label> + <Input + id="email" + type="email" + placeholder="m@example.com" + value={email} + onChange={(e) => setEmail(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="password">Password</Label> + <Input + id="password" + type="password" + value={password} + onChange={(e) => setPassword(e.target.value)} + disabled={isAnyLoading} + className="h-11" + /> + </div> + <Button + onClick={handleLogin} + disabled={isAnyLoading || !email || !password} + className="w-full h-11" + size="lg" + > + {isEmailLoading ? <Loader2 className="animate-spin" /> : "Sign in"} + </Button> </div> - <Button onClick={handleLogin}>Login</Button> </div> ); } export default function LoginPage() { + const router = useRouter(); + return ( - <div className="flex h-screen items-center justify-center"> - <Card className="w-[350px]"> - <CardHeader> - <CardTitle>Login</CardTitle> - <CardDescription> - Enter your email and password to login. + <div className="flex h-screen items-center justify-center relative"> + <Button + variant="ghost" + onClick={() => router.back()} + className="absolute top-6 left-6" + > + <ArrowLeft className="h-5 w-5" /> Back + </Button> + <Card className="w-[400px] shadow-lg border-0"> + <CardHeader className="text-center pb-4"> + <CardTitle className="text-2xl font-semibold">Welcome back</CardTitle> + <CardDescription className="text-base"> + Sign in to your account to continue </CardDescription> </CardHeader> - <CardContent> - <Suspense fallback={<div>Loading...</div>}> + <CardContent className="pt-0"> + <Suspense fallback={<div className="text-center"> + <Loader2 className="animate-spin" /> + </div>}> <LoginForm /> </Suspense> - <div className="mt-4 text-center text-sm"> + <div className="mt-6 text-center text-sm"> Don't have an account?{" "} - <Link href="/auth/signup" className="underline"> + <Link href="/auth/signup" className="font-medium text-primary underline-offset-4 hover:underline"> Sign up </Link> </div> |
