Skip to content

Commit 8a00cb4

Browse files
authored
Merge pull request #87 from ayushpandey101/FIX2_Branch
[Enhancement] Login/Signup Page UI/UX Improvements + Light Mode Bug Fix
2 parents 2c21351 + f10f3ef commit 8a00cb4

File tree

2 files changed

+359
-168
lines changed

2 files changed

+359
-168
lines changed

frontend/app/login/page.tsx

Lines changed: 126 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"use client";
2-
import { Eye, EyeClosed, Moon, StepBack, Sun } from "lucide-react";
2+
import { Eye, EyeClosed, Moon, StepBack, Sun, Mail, Lock, Github, Chrome, LogIn as LoginIcon } from "lucide-react";
33
import { signIn } from "next-auth/react";
44
import { useRouter } from "next/navigation";
55
import { useEffect, useState } from "react";
@@ -84,9 +84,8 @@ export default function LoginPage() {
8484

8585
if (isNavigating) {
8686
return (
87-
<main className="flex flex-col items-center justify-center min-h-screen relative overflow-hidden">
88-
{/* Background Gradient Animation */}
89-
<div className="absolute inset-0 z-0">
87+
<main className="flex flex-col items-center justify-center min-h-screen relative overflow-hidden bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50 dark:from-slate-900 dark:via-slate-900 dark:to-slate-900">
88+
<div className="absolute inset-0 z-0 dark:opacity-100 opacity-0">
9089
<BackgroundGradientAnimation
9190
gradientBackgroundStart="rgb(15, 23, 42)"
9291
gradientBackgroundEnd="rgb(30, 41, 59)"
@@ -101,30 +100,19 @@ export default function LoginPage() {
101100
containerClassName="h-screen w-screen"
102101
/>
103102
</div>
104-
105-
{/* Exit to Landing Page Button */}
106-
<button
107-
onClick={() => router.push("/")}
108-
className="absolute z-20 top-6 left-6 p-2 rounded-full bg-white/90 dark:bg-gray-800/90 backdrop-blur-lg border border-white/20 dark:border-gray-700/50 shadow-lg hover:shadow-xl transition-all duration-200"
109-
aria-label="Back to landing page"
110-
>
111-
<StepBack className="h-5 w-5 text-gray-600 dark:text-gray-300" />
112-
</button>
113103

114-
<div className="relative z-10 w-full max-w-md mx-auto mt-20 p-8 bg-white/90 dark:bg-gray-800/90 backdrop-blur-lg rounded-3xl shadow-2xl border border-white/20 dark:border-gray-700/50">
115-
<div className="flex flex-col items-center justify-center py-8">
116-
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
117-
<p className="text-gray-600 dark:text-gray-300 mt-4">Loading...</p>
118-
</div>
104+
<div className="relative z-10 flex flex-col items-center justify-center">
105+
<div className="animate-spin rounded-full h-12 w-12 border-4 border-blue-200 dark:border-blue-900 border-t-blue-600 dark:border-t-blue-400 mb-4"></div>
106+
<p className="text-gray-700 dark:text-gray-300 font-medium">Loading...</p>
119107
</div>
120108
</main>
121109
);
122110
}
123111

124112
return (
125-
<main className="flex flex-col items-center justify-center min-h-screen relative overflow-hidden">
126-
{/* Background Gradient Animation */}
127-
<div className="absolute inset-0 z-0">
113+
<main className="flex flex-col items-center justify-center min-h-screen relative overflow-hidden bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50 dark:from-slate-900 dark:via-slate-900 dark:to-slate-900">
114+
{/* Background Gradient Animation - Only visible in dark mode */}
115+
<div className="absolute inset-0 z-0 dark:opacity-100 opacity-0 transition-opacity duration-300">
128116
<BackgroundGradientAnimation
129117
gradientBackgroundStart="rgb(15, 23, 42)"
130118
gradientBackgroundEnd="rgb(30, 41, 59)"
@@ -140,123 +128,196 @@ export default function LoginPage() {
140128
/>
141129
</div>
142130

131+
{/* Decorative Elements for Light Mode */}
132+
<div className="absolute inset-0 z-0 dark:opacity-0 opacity-100 transition-opacity duration-300">
133+
<div className="absolute top-0 left-0 w-96 h-96 bg-blue-300/20 rounded-full blur-3xl"></div>
134+
<div className="absolute top-1/4 right-0 w-96 h-96 bg-purple-300/20 rounded-full blur-3xl"></div>
135+
<div className="absolute bottom-0 left-1/4 w-96 h-96 bg-indigo-300/20 rounded-full blur-3xl"></div>
136+
</div>
137+
143138
{/* Exit to Landing Page Button */}
144139
<button
145140
onClick={() => router.push("/")}
146-
className="absolute z-20 top-6 left-6 p-2 rounded-full bg-white/90 dark:bg-gray-800/90 backdrop-blur-lg border border-white/20 dark:border-gray-700/50 shadow-lg hover:shadow-xl transition-all duration-200"
141+
className="absolute z-20 top-6 left-6 p-3 rounded-full bg-white dark:bg-gray-800 border-2 border-gray-200 dark:border-gray-700 shadow-lg hover:shadow-xl hover:scale-110 transition-all duration-200"
147142
aria-label="Back to landing page"
148143
>
149-
<StepBack className="h-5 w-5 text-gray-600 dark:text-gray-300" />
144+
<StepBack className="h-5 w-5 text-gray-700 dark:text-gray-300" />
150145
</button>
151146

152147
{/* Theme Toggle Button */}
153148
<button
154149
onClick={toggleTheme}
155-
className="absolute z-20 top-6 right-6 p-2 rounded-full bg-white/90 dark:bg-gray-800/90 backdrop-blur-lg border border-white/20 dark:border-gray-700/50 shadow-lg hover:shadow-xl transition-all duration-200"
150+
className="absolute z-20 top-6 right-6 p-3 rounded-full bg-white dark:bg-gray-800 border-2 border-gray-200 dark:border-gray-700 shadow-lg hover:shadow-xl hover:scale-110 transition-all duration-200"
156151
aria-label="Toggle theme"
157152
>
158-
{isDark ? <Sun className="h-5 w-5 text-yellow-500" /> : <Moon className="h-5 w-5 text-gray-600" />}
153+
{isDark ? <Sun className="h-5 w-5 text-yellow-500" /> : <Moon className="h-5 w-5 text-indigo-600" />}
159154
</button>
160155

161-
<div className="relative z-10 w-full max-w-xs md:max-w-md mx-auto mt-20 p-8 bg-white/90 dark:bg-gray-800/90 backdrop-blur-lg rounded-3xl shadow-2xl border border-white/20 dark:border-gray-700/50">
162-
<h1 className="text-2xl md:text-3xl font-bold text-center text-gray-900 dark:text-white mb-8">Sign In</h1>
156+
<div className="relative z-10 w-full max-w-md mx-auto my-8 p-6 md:p-8 bg-white dark:bg-gray-800 backdrop-blur-lg rounded-3xl shadow-2xl border border-gray-200 dark:border-gray-700 max-h-[calc(100vh-4rem)] overflow-y-auto">
157+
{/* Header */}
158+
<div className="text-center mb-6">
159+
<div className="inline-flex items-center justify-center w-14 h-14 rounded-full bg-gradient-to-br from-blue-500 to-purple-600 mb-3 shadow-lg">
160+
<LoginIcon className="h-7 w-7 text-white" />
161+
</div>
162+
<h1 className="text-2xl md:text-3xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent mb-1">
163+
Welcome Back
164+
</h1>
165+
<p className="text-gray-600 dark:text-gray-400 text-xs">
166+
Sign in to access your dashboard
167+
</p>
168+
</div>
169+
163170
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
164-
<div className="space-y-2">
165-
<input
166-
type="email"
167-
placeholder="Email"
168-
value={email}
169-
onChange={(e) => setEmail(e.target.value)}
170-
className="w-full px-2 py-2 md:px-4 md:py-3 rounded-xl bg-gray-50 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-blue-400 dark:focus:border-blue-400 transition-all duration-200"
171-
required
172-
/>
173-
<div className="relative">
171+
<div className="space-y-3">
172+
{/* Email Input */}
173+
<div className="relative group">
174+
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
175+
<Mail className="h-4 w-4 text-gray-400 group-focus-within:text-blue-500 transition-colors" />
176+
</div>
177+
<input
178+
type="email"
179+
placeholder="Email address"
180+
value={email}
181+
onChange={(e) => setEmail(e.target.value)}
182+
className="w-full pl-9 pr-4 py-2.5 text-sm rounded-xl bg-gray-50 dark:bg-gray-700/50 border-2 border-gray-200 dark:border-gray-600 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500 dark:focus:border-blue-400 transition-all duration-200"
183+
required
184+
/>
185+
</div>
186+
187+
{/* Password Input */}
188+
<div className="relative group">
189+
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
190+
<Lock className="h-4 w-4 text-gray-400 group-focus-within:text-blue-500 transition-colors" />
191+
</div>
174192
<input
175193
type={showPassword ? "text" : "password"}
176194
placeholder="Password"
177195
value={password}
178196
onChange={(e) => setPassword(e.target.value)}
179-
className="w-full px-2 py-2 md:px-4 md:py-3 pr-12 rounded-xl bg-gray-50 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:focus:ring-blue-400 dark:focus:border-blue-400 transition-all duration-200"
197+
className="w-full pl-9 pr-11 py-2.5 text-sm rounded-xl bg-gray-50 dark:bg-gray-700/50 border-2 border-gray-200 dark:border-gray-600 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500 dark:focus:border-blue-400 transition-all duration-200"
180198
required
181199
/>
182200
<button
183201
type="button"
184202
onClick={() => setShowPassword(!showPassword)}
185-
className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors duration-200"
203+
className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 transition-colors duration-200"
186204
>
187205
{showPassword ? (
188-
<Eye className="h-5 w-5" />
206+
<Eye className="h-4 w-4" />
189207
) : (
190-
<EyeClosed className="h-5 w-5" />
208+
<EyeClosed className="h-4 w-4" />
191209
)}
192210
</button>
193211
</div>
194212
</div>
195213

196214
{/* Forgot Password Link */}
197-
<div className="text-right">
215+
<div className="flex items-center justify-between">
216+
<div className="flex items-center">
217+
<input
218+
type="checkbox"
219+
id="remember"
220+
className="w-4 h-4 text-blue-600 bg-gray-100 dark:bg-gray-700 border-gray-300 dark:border-gray-600 rounded focus:ring-blue-500 focus:ring-2"
221+
/>
222+
<label htmlFor="remember" className="ml-2 text-sm text-gray-600 dark:text-gray-400">
223+
Remember me
224+
</label>
225+
</div>
198226
<button
199227
type="button"
200228
onClick={() => router.push("/forgot-password")}
201-
className="text-yellow-500 dark:text-yellow-400 hover:underline text-sm"
229+
className="text-sm text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 font-medium transition-colors"
202230
>
203231
Forgot Password?
204232
</button>
205233
</div>
206234

207235
{error && (
208-
<div className="text-red-600 dark:text-red-400 text-sm text-center bg-red-50 dark:bg-red-900/20 px-4 py-2 rounded-lg border border-red-200 dark:border-red-800">
209-
{error}
236+
<div className="flex items-center gap-2 text-red-600 dark:text-red-400 text-sm bg-red-50 dark:bg-red-900/20 px-4 py-3 rounded-xl border-2 border-red-200 dark:border-red-800">
237+
<div className="flex-shrink-0">
238+
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
239+
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
240+
</svg>
241+
</div>
242+
<span>{error}</span>
210243
</div>
211244
)}
212245

213246
<button
214247
type="submit"
215-
className="w-full px-4 py-2 md:px-6 md:py-3 bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 hover:to-blue-800 text-white rounded-xl shadow-lg transition-all duration-200 font-semibold transform hover:scale-105 active:scale-95"
248+
className="w-full px-4 py-2.5 text-sm bg-gradient-to-r from-blue-600 via-blue-700 to-purple-600 hover:from-blue-700 hover:via-blue-800 hover:to-purple-700 text-white rounded-xl font-semibold shadow-lg shadow-blue-500/30 hover:shadow-xl hover:shadow-blue-600/40 transition-all duration-300 transform hover:scale-[1.02] active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none disabled:shadow-none flex items-center justify-center gap-2"
216249
disabled={loading}
217250
>
218-
{loading ? "Signing in..." : "Sign In"}
251+
{loading ? (
252+
<>
253+
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
254+
Signing in...
255+
</>
256+
) : (
257+
<>
258+
<LoginIcon className="h-4 w-4" />
259+
Sign In
260+
</>
261+
)}
219262
</button>
220263
</form>
221264

265+
{/* Divider */}
266+
<div className="relative my-4">
267+
<div className="absolute inset-0 flex items-center">
268+
<div className="w-full border-t border-gray-300 dark:border-gray-600"></div>
269+
</div>
270+
<div className="relative flex justify-center text-xs">
271+
<span className="px-3 bg-white dark:bg-gray-800 text-gray-500 dark:text-gray-400 font-medium">
272+
Or continue with
273+
</span>
274+
</div>
275+
</div>
276+
222277
{/* Social Sign-In Buttons */}
223-
<div className="flex flex-col gap-3 mt-6">
278+
<div className="flex gap-3">
224279
<button
225-
className="w-full px-4 py-2 md:px-6 md:py-3 bg-gray-900 dark:bg-gray-700 hover:bg-gray-800 dark:hover:bg-gray-600 text-white rounded-xl shadow-lg transition-all duration-200 font-semibold border border-gray-300 dark:border-gray-600 transform hover:scale-105 active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none"
280+
className="flex-1 px-3 py-2.5 text-sm bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 text-gray-900 dark:text-white rounded-xl font-semibold border-2 border-gray-300 dark:border-gray-600 transition-all duration-200 transform hover:scale-[1.02] active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none flex items-center justify-center gap-2 shadow-sm hover:shadow-md"
226281
onClick={() => handleSocialSignIn("github")}
227282
disabled={socialLoading !== null}
228283
>
229284
{socialLoading === "github" ? (
230-
<div className="flex items-center justify-center gap-2">
231-
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
232-
Signing in with GitHub...
233-
</div>
285+
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-gray-900 dark:border-white"></div>
234286
) : (
235-
"Sign in with GitHub"
287+
<>
288+
<Github className="h-4 w-4" />
289+
<span className="hidden sm:inline">GitHub</span>
290+
</>
236291
)}
237292
</button>
238293

239294
<button
240-
className="w-full px-4 py-2 md:px-6 md:py-3 bg-red-600 hover:bg-red-700 text-white rounded-xl shadow-lg transition-all duration-200 font-semibold border border-red-300 dark:border-red-600 transform hover:scale-105 active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none"
295+
className="flex-1 px-3 py-2.5 text-sm bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 text-gray-900 dark:text-white rounded-xl font-semibold border-2 border-gray-300 dark:border-gray-600 transition-all duration-200 transform hover:scale-[1.02] active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed disabled:transform-none flex items-center justify-center gap-2 shadow-sm hover:shadow-md"
241296
onClick={() => handleSocialSignIn("google")}
242297
disabled={socialLoading !== null}
243298
>
244299
{socialLoading === "google" ? (
245-
<div className="flex items-center justify-center gap-2">
246-
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
247-
Signing in with Google...
248-
</div>
300+
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-gray-900 dark:border-white"></div>
249301
) : (
250-
"Sign in with Google"
302+
<>
303+
<Chrome className="h-4 w-4" />
304+
<span className="hidden sm:inline">Google</span>
305+
</>
251306
)}
252307
</button>
253308
</div>
254309

255-
<div className="text-center mt-6 text-gray-600 dark:text-gray-300">
256-
Don't have an account?{" "}
257-
<button onClick={() => handleNavigation("/signup")} className="text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300 underline transition-colors">
258-
Sign Up
259-
</button>
310+
{/* Sign Up Link */}
311+
<div className="text-center mt-5 pt-4 border-t border-gray-200 dark:border-gray-700">
312+
<p className="text-gray-600 dark:text-gray-400 text-xs">
313+
Don't have an account?{" "}
314+
<button
315+
onClick={() => handleNavigation("/signup")}
316+
className="text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 font-semibold transition-colors"
317+
>
318+
Sign Up
319+
</button>
320+
</p>
260321
</div>
261322
</div>
262323
</main>

0 commit comments

Comments
 (0)