diff --git a/openspec/changes/user-accounts/tasks.md b/openspec/changes/user-accounts/tasks.md index a277f73..32069b4 100644 --- a/openspec/changes/user-accounts/tasks.md +++ b/openspec/changes/user-accounts/tasks.md @@ -56,7 +56,7 @@ ## 10. Login Page -- [ ] 10.1 `[sonnet]` Create `src/app/(public)/login/page.tsx` — login form matching Lovable design: email/password inputs, "Sign In" button calling `signIn("credentials")`, "Continue with Google" button calling `signIn("google")` +- [x] 10.1 `[sonnet]` Create `src/app/(public)/login/page.tsx` — login form matching Lovable design: email/password inputs, "Sign In" button calling `signIn("credentials")`, "Continue with Google" button calling `signIn("google")` - [ ] 10.2 `[haiku]` Add error state display for invalid credentials - [ ] 10.3 `[haiku]` Add "Forgot password?" link (shows toast: "Not yet available"), "Sign up" link to `/register` diff --git a/src/app/(public)/login/page.tsx b/src/app/(public)/login/page.tsx new file mode 100644 index 0000000..407a6d6 --- /dev/null +++ b/src/app/(public)/login/page.tsx @@ -0,0 +1,132 @@ +"use client"; + +import { useState } from "react"; +import Link from "next/link"; +import { signIn } from "next-auth/react"; +import { ChartColumn } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; + +export default function LoginPage() { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [isLoading, setIsLoading] = useState(false); + + async function handleSubmit(e: React.FormEvent) { + e.preventDefault(); + setIsLoading(true); + try { + await signIn("credentials", { + email, + password, + redirectTo: "/app", + }); + } finally { + setIsLoading(false); + } + } + + async function handleGoogleSignIn() { + await signIn("google", { redirectTo: "/app" }); + } + + return ( +
+ {/* Navbar */} + + + {/* Login Form */} +
+ + + Welcome back + + Sign in to your workspace + + + +
+
+ + setEmail(e.target.value)} + className="font-mono text-sm" + /> +
+
+ + setPassword(e.target.value)} + className="font-mono text-sm" + /> +
+ +
+ +
+
+ +
+
+ + or + +
+
+ + + +

+ Don't have an account?{" "} + + Sign up + +

+
+
+
+
+ ); +}