Skip to content

Commit 3add1ce

Browse files
davedumtoPoulavBhowmick03
authored andcommitted
feat: built the signin and signup pages
1 parent 6338ea1 commit 3add1ce

10 files changed

Lines changed: 1345 additions & 3 deletions

File tree

web/app/signin/page.tsx

Lines changed: 376 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
'use client';
2+
3+
import React, { useState, useEffect } from 'react';
4+
import { Eye, EyeOff, Mail, Lock, Users, TrendingUp, ArrowRight, Loader2, Moon, Sun } from 'lucide-react';
5+
import { Button } from '@/components/ui/button';
6+
import { Input } from '@/components/ui/input';
7+
import { Label } from '@/components/ui/label';
8+
import { Checkbox } from '@/components/ui/checkbox';
9+
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
10+
import { Alert, AlertDescription } from '@/components/ui/alert';
11+
import { useRouter } from 'next/navigation';
12+
13+
interface FormData {
14+
email: string;
15+
password: string;
16+
rememberMe: boolean;
17+
}
18+
19+
const SignInPage = () => {
20+
const router = useRouter();
21+
const [showPassword, setShowPassword] = useState(false);
22+
const [isLoading, setIsLoading] = useState(false);
23+
const [error, setError] = useState('');
24+
const [darkMode, setDarkMode] = useState(true);
25+
const [formData, setFormData] = useState<FormData>({
26+
email: '',
27+
password: '',
28+
rememberMe: false
29+
});
30+
31+
useEffect(() => {
32+
// Check localStorage for theme preference on client side only
33+
if (typeof window !== 'undefined') {
34+
const savedTheme = localStorage.getItem('theme');
35+
36+
if (savedTheme) {
37+
const isDark = savedTheme === 'dark';
38+
setDarkMode(isDark);
39+
if (isDark) {
40+
document.documentElement.classList.add('dark');
41+
} else {
42+
document.documentElement.classList.remove('dark');
43+
}
44+
} else {
45+
// Default to dark mode
46+
setDarkMode(true);
47+
document.documentElement.classList.add('dark');
48+
localStorage.setItem('theme', 'dark');
49+
}
50+
}
51+
}, []);
52+
53+
const toggleTheme = () => {
54+
if (typeof window !== 'undefined') {
55+
const newDarkMode = !darkMode;
56+
setDarkMode(newDarkMode);
57+
58+
if (newDarkMode) {
59+
document.documentElement.classList.add('dark');
60+
localStorage.setItem('theme', 'dark');
61+
} else {
62+
document.documentElement.classList.remove('dark');
63+
localStorage.setItem('theme', 'light');
64+
}
65+
}
66+
};
67+
68+
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
69+
const { name, value, type, checked } = e.target;
70+
setFormData({
71+
...formData,
72+
[name]: type === 'checkbox' ? checked : value
73+
});
74+
if (error) setError('');
75+
};
76+
77+
const handleSubmit = async () => {
78+
if (!formData.email || !formData.password) {
79+
setError('Please fill in all required fields');
80+
return;
81+
}
82+
83+
setIsLoading(true);
84+
setError('');
85+
86+
try {
87+
await new Promise(resolve => setTimeout(resolve, 1500));
88+
console.log('Sign In Data:', formData);
89+
} catch {
90+
setError('Invalid email or password. Please try again.');
91+
} finally {
92+
setIsLoading(false);
93+
}
94+
};
95+
96+
const navigateToSignUp = () => {
97+
router.push('/signup');
98+
};
99+
100+
const togglePasswordVisibility = () => {
101+
setShowPassword(prev => !prev);
102+
};
103+
104+
return (
105+
<div className={`min-h-screen transition-colors duration-300 ${
106+
darkMode
107+
? 'bg-gradient-to-br from-black via-gray-900 to-gray-800'
108+
: 'bg-gradient-to-br from-gray-50 via-blue-50 to-gray-100'
109+
} flex items-center justify-center p-4 relative`}>
110+
<Button
111+
onClick={toggleTheme}
112+
variant="outline"
113+
size="sm"
114+
className={`absolute top-4 right-4 z-50 transition-all duration-300 ${
115+
darkMode
116+
? 'bg-gray-800 border-gray-700 text-white hover:bg-gray-700'
117+
: 'bg-white border-gray-300 text-gray-900 hover:bg-gray-50'
118+
}`}
119+
>
120+
{darkMode ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
121+
</Button>
122+
<div className={`absolute inset-0 opacity-30 ${
123+
darkMode
124+
? "bg-[url('data:image/svg+xml,%3Csvg width=\"60\" height=\"60\" viewBox=\"0 0 60 60\" xmlns=\"http://www.w3.org/2000/svg\"%3E%3Cg fill=\"none\" fill-rule=\"evenodd\"%3E%3Cg fill=\"%23ffffff\" fill-opacity=\"0.02\"%3E%3Ccircle cx=\"30\" cy=\"30\" r=\"2\"/%3E%3C/g%3E%3C/g%3E%3C/svg%3E')]"
125+
: "bg-[url('data:image/svg+xml,%3Csvg width=\"60\" height=\"60\" viewBox=\"0 0 60 60\" xmlns=\"http://www.w3.org/2000/svg\"%3E%3Cg fill=\"none\" fill-rule=\"evenodd\"%3E%3Cg fill=\"%23000000\" fill-opacity=\"0.02\"%3E%3Ccircle cx=\"30\" cy=\"30\" r=\"2\"/%3E%3C/g%3E%3C/g%3E%3C/svg%3E')]"
126+
}`}></div>
127+
128+
<div className={`w-full max-w-4xl flex rounded-2xl shadow-2xl overflow-hidden border transition-all duration-300 ${
129+
darkMode
130+
? 'bg-black/40 backdrop-blur-lg border-gray-800'
131+
: 'bg-white/80 backdrop-blur-lg border-gray-200'
132+
}`}>
133+
<div className={`hidden lg:flex lg:w-1/2 p-12 flex-col justify-between relative overflow-hidden transition-colors duration-300 ${
134+
darkMode
135+
? 'bg-gradient-to-br from-gray-900 to-black'
136+
: 'bg-gradient-to-br from-blue-600 to-blue-800'
137+
}`}>
138+
<div className={`absolute top-0 right-0 w-32 h-32 rounded-full -translate-y-16 translate-x-16 ${
139+
darkMode ? 'bg-white/5' : 'bg-white/10'
140+
}`}></div>
141+
<div className={`absolute bottom-0 left-0 w-24 h-24 rounded-full translate-y-12 -translate-x-12 ${
142+
darkMode ? 'bg-white/5' : 'bg-white/10'
143+
}`}></div>
144+
145+
<div className="relative z-10">
146+
<div className="flex items-center space-x-3 mb-8">
147+
<div className="flex items-center">
148+
<span className="text-white font-bold text-2xl tracking-wide">
149+
ROSTER<span className="text-red-500">RUMBLE</span>
150+
</span>
151+
</div>
152+
</div>
153+
154+
<h2 className="text-3xl font-bold text-white mb-4">
155+
Welcome Back, Champion
156+
</h2>
157+
<p className={`text-lg leading-relaxed ${
158+
darkMode ? 'text-gray-300' : 'text-blue-100'
159+
}`}>
160+
Sign in to continue your journey to fantasy sports greatness and compete for real cash prizes.
161+
</p>
162+
</div>
163+
164+
<div className="relative z-10">
165+
<div className="grid grid-cols-2 gap-6">
166+
<div className="text-center">
167+
<div className={`flex items-center justify-center w-12 h-12 rounded-lg mx-auto mb-3 ${
168+
darkMode ? 'bg-white/10' : 'bg-white/20'
169+
}`}>
170+
<Users className="w-6 h-6 text-white" />
171+
</div>
172+
<p className="text-white font-semibold">10M+</p>
173+
<p className={`text-sm ${darkMode ? 'text-gray-400' : 'text-blue-100'}`}>Active Players</p>
174+
</div>
175+
<div className="text-center">
176+
<div className={`flex items-center justify-center w-12 h-12 rounded-lg mx-auto mb-3 ${
177+
darkMode ? 'bg-white/10' : 'bg-white/20'
178+
}`}>
179+
<TrendingUp className="w-6 h-6 text-white" />
180+
</div>
181+
<p className="text-white font-semibold">₹5000Cr+</p>
182+
<p className={`text-sm ${darkMode ? 'text-gray-400' : 'text-blue-100'}`}>Prize Pool</p>
183+
</div>
184+
</div>
185+
</div>
186+
</div>
187+
188+
189+
<div className="w-full lg:w-1/2 p-2 lg:p-12 flex items-center justify-center">
190+
<div className="w-full max-w-md">
191+
192+
<div className="lg:hidden flex items-center justify-center mb-8">
193+
<div className="flex items-center">
194+
<span className={`font-bold text-2xl tracking-wide ${
195+
darkMode ? 'text-white' : 'text-gray-900'
196+
}`}>
197+
ROSTER<span className="text-red-500">RUMBLE</span>
198+
</span>
199+
</div>
200+
</div>
201+
202+
<Card className={`transition-colors duration-300 ${
203+
darkMode
204+
? 'bg-gray-900/50 border-gray-800 backdrop-blur-sm'
205+
: 'bg-white/70 border-gray-200 backdrop-blur-sm'
206+
}`}>
207+
<CardHeader className="text-center">
208+
<CardTitle className={`text-2xl font-bold ${darkMode ? 'text-white' : 'text-gray-900'}`}>
209+
Welcome Back
210+
</CardTitle>
211+
<CardDescription className={darkMode ? 'text-gray-400' : 'text-gray-600'}>
212+
Enter your credentials to access your account
213+
</CardDescription>
214+
</CardHeader>
215+
216+
<CardContent className="space-y-6">
217+
{error && (
218+
<Alert className={`${
219+
darkMode
220+
? 'bg-red-500/10 border-red-500/20'
221+
: 'bg-red-50 border-red-200'
222+
}`}>
223+
<AlertDescription className={darkMode ? 'text-red-400' : 'text-red-600'}>
224+
{error}
225+
</AlertDescription>
226+
</Alert>
227+
)}
228+
229+
<div className="space-y-2">
230+
<Label htmlFor="email" className={darkMode ? 'text-gray-300' : 'text-gray-700'}>
231+
Email Address
232+
</Label>
233+
<div className="relative">
234+
<Mail className={`absolute left-3 top-1/2 transform -translate-y-1/2 h-5 w-5 ${
235+
darkMode ? 'text-gray-500' : 'text-gray-400'
236+
}`} />
237+
<Input
238+
id="email"
239+
name="email"
240+
type="email"
241+
value={formData.email}
242+
onChange={handleInputChange}
243+
className={`pl-10 transition-colors duration-300 ${
244+
darkMode
245+
? 'bg-gray-800/50 border-gray-700 text-white placeholder-gray-500 focus:border-blue-500'
246+
: 'bg-white border-gray-300 text-gray-900 placeholder-gray-400 focus:border-blue-500'
247+
}`}
248+
placeholder="Enter your email"
249+
disabled={isLoading}
250+
/>
251+
</div>
252+
</div>
253+
254+
<div className="space-y-2">
255+
<Label htmlFor="password" className={darkMode ? 'text-gray-300' : 'text-gray-700'}>
256+
Password
257+
</Label>
258+
<div className="relative">
259+
<Lock className={`absolute left-3 top-1/2 transform -translate-y-1/2 h-5 w-5 ${
260+
darkMode ? 'text-gray-500' : 'text-gray-400'
261+
}`} />
262+
<Input
263+
id="password"
264+
name="password"
265+
type={showPassword ? "text" : "password"}
266+
value={formData.password}
267+
onChange={handleInputChange}
268+
className={`pl-10 pr-12 transition-colors duration-300 ${
269+
darkMode
270+
? 'bg-gray-800/50 border-gray-700 text-white placeholder-gray-500 focus:border-blue-500'
271+
: 'bg-white border-gray-300 text-gray-900 placeholder-gray-400 focus:border-blue-500'
272+
}`}
273+
placeholder="Enter your password"
274+
disabled={isLoading}
275+
/>
276+
<Button
277+
type="button"
278+
variant="ghost"
279+
size="sm"
280+
className="absolute right-0 top-0 h-full px-3 hover:bg-transparent"
281+
onClick={togglePasswordVisibility}
282+
tabIndex={-1}
283+
>
284+
{showPassword ? (
285+
<EyeOff className={`h-5 w-5 transition-colors ${
286+
darkMode ? 'text-gray-500 hover:text-gray-300' : 'text-gray-400 hover:text-gray-600'
287+
}`} />
288+
) : (
289+
<Eye className={`h-5 w-5 transition-colors ${
290+
darkMode ? 'text-gray-500 hover:text-gray-300' : 'text-gray-400 hover:text-gray-600'
291+
}`} />
292+
)}
293+
</Button>
294+
</div>
295+
</div>
296+
297+
<div className="flex items-center justify-between">
298+
<div className="flex items-center space-x-2">
299+
<Checkbox
300+
id="rememberMe"
301+
checked={formData.rememberMe}
302+
onCheckedChange={(checked) => {
303+
const isChecked = checked === true;
304+
setFormData(prev => ({ ...prev, rememberMe: isChecked }));
305+
}}
306+
className={`transition-colors ${
307+
darkMode
308+
? 'border-gray-600 data-[state=checked]:bg-blue-600 data-[state=checked]:border-blue-600'
309+
: 'border-gray-400 data-[state=checked]:bg-blue-600 data-[state=checked]:border-blue-600'
310+
}`}
311+
/>
312+
<Label
313+
htmlFor="rememberMe"
314+
className={`text-sm cursor-pointer transition-colors select-none ${
315+
darkMode ? 'text-gray-300 hover:text-white' : 'text-gray-700 hover:text-gray-900'
316+
}`}
317+
>
318+
Remember me
319+
</Label>
320+
</div>
321+
<Button
322+
variant="link"
323+
className={`p-0 h-auto transition-colors ${
324+
darkMode
325+
? 'text-blue-400 hover:text-blue-300'
326+
: 'text-blue-600 hover:text-blue-700'
327+
}`}
328+
>
329+
Forgot password?
330+
</Button>
331+
</div>
332+
333+
<Button
334+
onClick={handleSubmit}
335+
disabled={isLoading}
336+
className="w-full bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 hover:to-blue-800 text-white font-semibold transition-all duration-200 disabled:opacity-50"
337+
>
338+
{isLoading ? (
339+
<>
340+
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
341+
Signing In...
342+
</>
343+
) : (
344+
<>
345+
Sign In
346+
<ArrowRight className="ml-2 h-4 w-4" />
347+
</>
348+
)}
349+
</Button>
350+
</CardContent>
351+
352+
<CardFooter className="justify-center">
353+
<p className={`text-sm ${darkMode ? 'text-gray-400' : 'text-gray-600'}`}>
354+
Don&apos;t have an account?{' '}
355+
<Button
356+
variant="link"
357+
onClick={navigateToSignUp}
358+
className={`p-0 h-auto font-medium transition-colors ${
359+
darkMode
360+
? 'text-blue-400 hover:text-blue-300'
361+
: 'text-blue-600 hover:text-blue-700'
362+
}`}
363+
>
364+
Sign Up
365+
</Button>
366+
</p>
367+
</CardFooter>
368+
</Card>
369+
</div>
370+
</div>
371+
</div>
372+
</div>
373+
);
374+
};
375+
376+
export default SignInPage;

0 commit comments

Comments
 (0)