refactor login

This commit is contained in:
Bill Yang 2025-02-17 18:27:24 -08:00
parent e61ec28531
commit f5ce57f772
3 changed files with 75 additions and 66 deletions

View file

@ -45,12 +45,18 @@ export default function RootLayout({
></script> ></script>
<ThemeProvider> <ThemeProvider>
<QueryProvider> <QueryProvider>
<div className="min-h-full"> {pathname === "/login" ? (
<TopBar /> <div className="min-h-full flex items-center justify-center">
<main className="flex min-h-screen flex-col items-center p-4"> {children}
<div className="w-full max-w-6xl">{children}</div> </div>
</main> ) : (
</div> <div className="min-h-full">
<TopBar />
<main className="flex min-h-screen flex-col items-center p-4">
<div className="w-full max-w-6xl">{children}</div>
</main>
</div>
)}
</QueryProvider> </QueryProvider>
</ThemeProvider> </ThemeProvider>
</body> </body>

View file

@ -1,31 +1,28 @@
"use client"; "use client";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { useState } from "react";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react";
import { authClient } from "../../lib/auth"; import { authClient } from "../../lib/auth";
import { userStore } from "../../lib/userStore"; import { userStore } from "../../lib/userStore";
import { AlertCircle } from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "../../components/ui/alert";
export default function Page() { export default function Page() {
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string>();
const router = useRouter(); const router = useRouter();
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
setIsLoading(true); setIsLoading(true);
setError("");
try { try {
const { data, error } = await authClient.signIn.username({ const { data, error } = await authClient.signIn.username({
username, username,
@ -37,62 +34,70 @@ export default function Page() {
}); });
router.push("/"); router.push("/");
} }
if (error) {
setError(error.message);
}
} catch (error) { } catch (error) {
console.error("Login error:", error); setError(String(error));
alert("Failed to login. Please try again.");
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }
}; };
return ( return (
<div className={cn("flex flex-col gap-6 items-center")}> <Card className="w-full max-w-sm">
<Card className="w-[500px]"> <CardHeader>
<CardHeader> <CardTitle className="text-2xl flex justify-center">
<CardTitle className="text-2xl">Login</CardTitle> Welcome back!
<CardDescription> </CardTitle>
Enter your email below to login to your account </CardHeader>
</CardDescription> <CardContent>
</CardHeader> <form onSubmit={handleSubmit}>
<CardContent> <div className="flex flex-col gap-6">
<form onSubmit={handleSubmit}> <div className="grid gap-2">
<div className="flex flex-col gap-6"> <Label htmlFor="username">Username</Label>
<div className="grid gap-2"> <Input
<Label htmlFor="username">Username</Label> id="username"
<Input type="username"
id="username" placeholder="username"
type="username" required
placeholder="username" value={username}
required onChange={(e) => setUsername(e.target.value)}
value={username} />
onChange={(e) => setUsername(e.target.value)}
/>
</div>
<div className="grid gap-2">
<div className="flex items-center">
<Label htmlFor="password">Password</Label>
<a
href="#"
className="ml-auto inline-block text-sm underline-offset-4 hover:underline"
>
Forgot your password?
</a>
</div>
<Input
id="password"
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? "Logging in..." : "Login"}
</Button>
</div> </div>
</form> <div className="grid gap-2">
</CardContent> <div className="flex items-center">
</Card> <Label htmlFor="password">Password</Label>
</div> <a
href="#"
className="ml-auto inline-block text-sm underline-offset-4 hover:underline"
>
Forgot your password?
</a>
</div>
<Input
id="password"
type="password"
placeholder="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? "Logging in..." : "Login"}
</Button>
{error && (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertTitle>Error Logging In</AlertTitle>
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
</div>
</form>
</CardContent>
</Card>
); );
} }

View file

@ -29,8 +29,6 @@ export const initAuth = (allowList: string[]) => {
defaultCookieAttributes: { defaultCookieAttributes: {
sameSite: process.env.NODE_ENV === "production" ? "none" : "lax", sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
path: "/", path: "/",
// httpOnly: true is default
// secure: false (implied by useSecureCookies false)
}, },
}, },
}); });