Skip to content

Commit c7b06ea

Browse files
committed
feat(auth): add password field back to login form
1 parent 5f56764 commit c7b06ea

1 file changed

Lines changed: 56 additions & 21 deletions

File tree

app/login/page.tsx

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Input } from "@/components/ui/input"
88
import { Label } from "@/components/ui/label"
99
import Link from "next/link"
1010
import { motion, AnimatePresence } from "framer-motion"
11-
import { signInWithEmail, checkRememberMe } from "@/lib/features/auth"
11+
import { signIn, checkRememberMe } from "@/lib/features/auth"
1212
import { getTranslations, getUserLanguage } from "@/lib/config"
1313
import { LanguageSwitcher } from "@/components/language-switcher"
1414
import {
@@ -26,8 +26,10 @@ import {
2626
export default function LoginPage() {
2727
const router = useRouter()
2828
const [email, setEmail] = useState("")
29+
const [password, setPassword] = useState("")
30+
const [rememberMe, setRememberMe] = useState(false)
2931
const [error, setError] = useState("")
30-
const [message, setMessage] = useState("")
32+
const [showPassword, setShowPassword] = useState(false)
3133
const [t, setT] = useState(getTranslations("en"))
3234

3335
useEffect(() => {
@@ -46,17 +48,16 @@ export default function LoginPage() {
4648
const handleLogin = async (e: React.FormEvent) => {
4749
e.preventDefault()
4850
setError("")
49-
setMessage("")
5051

51-
if (!email) {
52-
setError(t.auth.email + " is required")
52+
if (!email || !password) {
53+
setError("Email and password are required")
5354
return
5455
}
5556

56-
const result = await signInWithEmail(email)
57+
const result = await signIn(email, password, rememberMe)
5758

5859
if (result.success) {
59-
setMessage("Check your email for the magic link to sign in!")
60+
router.push("/dashboard")
6061
} else {
6162
setError(result.error || "Login failed")
6263
}
@@ -177,19 +178,6 @@ export default function LoginPage() {
177178
</div>
178179
</motion.div>
179180
)}
180-
{message && (
181-
<motion.div
182-
initial={{ opacity: 0, height: 0 }}
183-
animate={{ opacity: 1, height: "auto" }}
184-
exit={{ opacity: 0, height: 0 }}
185-
className="rounded-2xl border border-green-500/50 bg-green-500/5 p-4 text-sm text-green-400 overflow-hidden"
186-
>
187-
<div className="flex items-center gap-3">
188-
<div className="w-1.5 h-6 bg-green-500 rounded-full"></div>
189-
<p className="font-medium">{message}</p>
190-
</div>
191-
</motion.div>
192-
)}
193181
</AnimatePresence>
194182

195183
<div className="space-y-5">
@@ -212,13 +200,60 @@ export default function LoginPage() {
212200
/>
213201
</div>
214202
</div>
203+
204+
<div className="space-y-2">
205+
<Label htmlFor="password" className="text-xs font-bold uppercase tracking-widest text-slate-500 ml-1">
206+
{t.auth.password}
207+
</Label>
208+
<div className="relative group">
209+
<div className="absolute left-4 top-1/2 -translate-y-1/2 flex items-center justify-center">
210+
<LockClosedIcon className="h-5 w-5 text-slate-500 group-focus-within:text-primary transition-colors" />
211+
</div>
212+
<Input
213+
id="password"
214+
type={showPassword ? "text" : "password"}
215+
placeholder="••••••••"
216+
value={password}
217+
onChange={(e) => setPassword(e.target.value)}
218+
className="pl-12 pr-12 h-14 bg-white/[0.03] border-white/5 hover:border-white/10 focus:border-primary/50 transition-all rounded-2xl text-lg placeholder:text-slate-600 focus:ring-0 focus:bg-white/[0.05]"
219+
required
220+
/>
221+
<button
222+
type="button"
223+
onClick={() => setShowPassword(!showPassword)}
224+
className="absolute right-4 top-1/2 -translate-y-1/2 text-slate-500 hover:text-white transition-colors"
225+
>
226+
{showPassword ? <EyeSlashIcon className="h-5 w-5" /> : <EyeIcon className="h-5 w-5" />}
227+
</button>
228+
</div>
229+
</div>
230+
</div>
231+
232+
<div className="flex items-center justify-between px-1">
233+
<label className="flex items-center gap-3 cursor-pointer group">
234+
<div className="relative">
235+
<input
236+
type="checkbox"
237+
checked={rememberMe}
238+
onChange={(e) => setRememberMe(e.target.checked)}
239+
className="peer appearance-none w-5 h-5 rounded-md border border-white/10 checked:bg-primary checked:border-primary transition-all cursor-pointer"
240+
/>
241+
<CheckCircleIcon className="absolute top-0.5 left-0.5 w-4 h-4 text-slate-950 opacity-0 peer-checked:opacity-100 transition-opacity pointer-events-none" />
242+
</div>
243+
<span className="text-sm font-medium text-slate-400 group-hover:text-slate-300 transition-colors">
244+
{t.auth.rememberMe}
245+
</span>
246+
</label>
247+
<Link href="#" className="text-sm text-primary hover:text-white font-bold transition-colors">
248+
Forgot password?
249+
</Link>
215250
</div>
216251

217252
<Button
218253
type="submit"
219254
className="w-full h-14 text-lg font-black uppercase tracking-widest bg-primary hover:bg-primary/90 text-slate-950 shadow-[0_0_20px_rgba(var(--primary-rgb),0.3)] hover:shadow-[0_0_30px_rgba(var(--primary-rgb),0.5)] transition-all group rounded-2xl"
220255
>
221-
Send Magic Link
256+
Sign In
222257
<ArrowRightIcon className="ml-3 h-5 w-5 group-hover:translate-x-1.5 transition-transform" />
223258
</Button>
224259
</form>

0 commit comments

Comments
 (0)