Skip to content

Commit ef12718

Browse files
Merge pull request #143 from Rehan959/bug/135
Fix Vite Development Server Crash in LoginPage Component
2 parents c194948 + af1abb1 commit ef12718

1 file changed

Lines changed: 62 additions & 245 deletions

File tree

LocalMind-Frontend/src/shared/component/v1/LoginPage.tsx

Lines changed: 62 additions & 245 deletions
Original file line numberDiff line numberDiff line change
@@ -1,266 +1,83 @@
11
import React, { useState } from 'react'
2-
import { Link, useNavigate } from 'react-router-dom'
3-
import robotImg from '../../../assets/login.png'
4-
import React, { useState, useEffect } from 'react'
5-
import { Link, useNavigate } from 'react-router-dom'
6-
import robotImg from '../../../assets/robot.png'
7-
import aiImg from '../../../assets/Artificial intelligence.png'
8-
import apiService from '../../../core/api.service'
2+
import { useNavigate } from 'react-router-dom'
93

10-
const LoginPage: React.FC = () => {
11-
const navigate = useNavigate()
12-
const glowStyles = `
13-
@keyframes glow {
14-
0%, 100% { filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.5)); }
15-
50% { filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.8)); }
16-
}
17-
.logo-glow {
18-
animation: glow 3s ease-in-out infinite;
19-
}
20-
`
4+
interface ApiService {
5+
login: (
6+
email: string,
7+
password: string
8+
) => Promise<{ success: boolean; data?: unknown; error?: string }>
9+
}
10+
11+
interface LoginPageProps {
12+
apiService: ApiService
13+
}
14+
15+
const LoginPage: React.FC<LoginPageProps> = ({ apiService }) => {
2116
const [email, setEmail] = useState('')
2217
const [password, setPassword] = useState('')
23-
const [rememberMe, setRememberMe] = useState(false)
24-
const [loading, setLoading] = useState(false)
25-
const [isLoading, setIsLoading] = useState(false)
2618
const [error, setError] = useState('')
27-
const [success, setSuccess] = useState('')
28-
29-
const handleSubmit = async (e: React.FormEvent) => {
30-
e.preventDefault()
31-
setError('')
32-
setSuccess('')
33-
setLoading(true)
34-
35-
try {
36-
const response = await fetch('/api/v1/user/login', {
37-
method: 'POST',
38-
headers: {
39-
'Content-Type': 'application/json',
40-
},
41-
body: JSON.stringify({ email, password }),
42-
})
43-
44-
const data = await response.json()
45-
46-
if (!response.ok) {
47-
setError(data.message || 'Login failed. Please try again.')
48-
setLoading(false)
49-
return
50-
}
51-
52-
// Store token in localStorage
53-
if (data.data?.token) {
54-
localStorage.setItem('token', data.data.token)
55-
localStorage.setItem('user', JSON.stringify(data.data.user || {}))
56-
57-
// Store remember me preference
58-
if (rememberMe) {
59-
localStorage.setItem('rememberMe', 'true')
60-
localStorage.setItem('savedEmail', email)
61-
}
62-
63-
setSuccess('Login successful! Redirecting...')
64-
65-
// Redirect after brief delay
66-
setTimeout(() => {
67-
navigate('/dashboard')
68-
}, 1000)
69-
}
70-
} catch (err) {
71-
setError('An error occurred. Please check your connection and try again.')
72-
console.error('Login error:', err)
73-
} finally {
74-
setLoading(false)
75-
}
76-
}
77-
setIsLoading(true)
19+
const navigate = useNavigate()
7820

21+
const handleLogin = async () => {
7922
try {
23+
setError('')
8024
const response = await apiService.login(email, password)
8125

82-
if (!response.success) {
83-
throw new Error(response.message || 'Login failed. Please try again.')
84-
}
85-
86-
setSuccess('Login successful! Redirecting...')
87-
88-
// Store token if provided
89-
if (response.data?.token) {
90-
localStorage.setItem('authToken', response.data.token)
91-
}
92-
93-
// Store user info if remember me is checked
94-
if (rememberMe) {
95-
localStorage.setItem('rememberedEmail', email)
26+
if (response.success) {
27+
navigate('/dashboard')
9628
} else {
97-
localStorage.removeItem('rememberedEmail')
29+
setError(response.error || 'Login failed')
9830
}
99-
100-
// Redirect to dashboard after a short delay
101-
setTimeout(() => {
102-
navigate('/dashboard')
103-
}, 1000)
104-
} catch (err: any) {
105-
setError(err.message || 'An error occurred during login. Please try again.')
106-
console.error('Login error:', err)
107-
} finally {
108-
setIsLoading(false)
31+
} catch (err) {
32+
setError('An error occurred during login')
33+
console.error(err)
10934
}
11035
}
11136

112-
// Load remembered email on component mount
113-
useEffect(() => {
114-
const rememberedEmail = localStorage.getItem('rememberedEmail')
115-
if (rememberedEmail) {
116-
setEmail(rememberedEmail)
117-
setRememberMe(true)
118-
}
119-
}, [])
120-
<img
121-
src={aiImg}
122-
alt="Artificial Intelligence Logo"
123-
className="logo-glow w-20 sm:w-24 h-20 sm:h-24 object-cover rounded-full shadow-2xl"
124-
/>
125-
</div>
126-
127-
<div className="w-full max-w-7xl bg-[#181818] rounded-3xl shadow-2xl overflow-hidden grid grid-cols-1 md:grid-cols-2">
128-
{/* Left Section */}
129-
<div className="bg-[#181818] p-6 sm:p-8 md:p-12 lg:p-16 xl:p-20 flex flex-col justify-center">
130-
<h1 className="text-2xl sm:text-3xl md:text-4xl font-bold text-white mb-1 sm:mb-2">
131-
Welcome Back
132-
</h1>
133-
<p className="text-gray-400 text-xs sm:text-sm md:text-base mb-6 md:mb-8">
134-
Sign in to your account to continue
135-
</p>
136-
137-
<form
138-
onSubmit={handleSubmit}
139-
className="space-y-3 sm:space-y-4 md:space-y-5 lg:space-y-6"
140-
>
141-
{/* Error Message */}
142-
{error && (
143-
<div className="p-3 sm:p-4 bg-red-900 bg-opacity-30 border border-red-500 rounded-lg">
144-
<p className="text-red-400 text-xs sm:text-sm">{error}</p>
145-
<div className="p-3 bg-red-900 border border-red-700 rounded-lg text-red-100 text-xs sm:text-sm">
146-
{error}
147-
</div>
148-
)}
149-
150-
{/* Success Message */}
151-
{success && (
152-
<div className="p-3 sm:p-4 bg-green-900 bg-opacity-30 border border-green-500 rounded-lg">
153-
<p className="text-green-400 text-xs sm:text-sm">{success}</p>
154-
<div className="p-3 bg-green-900 border border-green-700 rounded-lg text-green-100 text-xs sm:text-sm">
155-
{success}
156-
</div>
157-
)}
158-
159-
{/* Email Input */}
160-
<div>
161-
<label
162-
htmlFor="email"
163-
className="block text-gray-200 text-xs sm:text-sm font-semibold mb-2"
164-
>
165-
Email
166-
</label>
167-
<input
168-
id="email"
169-
type="email"
170-
value={email}
171-
onChange={e => setEmail(e.target.value)}
172-
placeholder="you@example.com"
173-
className="w-full px-4 py-2.5 bg-[#2a2a2a] border border-gray-600 rounded-lg text-sm sm:text-base text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:border-transparent transition disabled:opacity-50"
174-
required
175-
disabled={loading}
176-
disabled={isLoading}
177-
/>
178-
</div>
179-
180-
{/* Password Input */}
181-
<div>
182-
<label
183-
htmlFor="password"
184-
className="block text-gray-200 text-xs sm:text-sm font-semibold mb-2"
185-
>
186-
Password
187-
</label>
188-
<input
189-
id="password"
190-
type="password"
191-
value={password}
192-
onChange={e => setPassword(e.target.value)}
193-
placeholder="••••••••"
194-
className="w-full px-4 py-2.5 bg-[#2a2a2a] border border-gray-600 rounded-lg text-sm sm:text-base text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:border-transparent transition disabled:opacity-50"
195-
required
196-
disabled={loading}
197-
disabled={isLoading}
198-
/>
199-
200-
{/* Remember Me & Forgot Password */}
201-
<div className="flex flex-row items-center justify-between gap-2 mt-2 sm:mt-3">
202-
<label className="flex items-center gap-2 cursor-pointer">
203-
<input
204-
type="checkbox"
205-
checked={rememberMe}
206-
onChange={e => setRememberMe(e.target.checked)}
207-
className="w-4 h-4 bg-gray-700 border border-gray-600 rounded cursor-pointer accent-gray-500 disabled:opacity-50"
208-
disabled={loading}
209-
className="w-4 h-4 bg-gray-700 border border-gray-600 rounded cursor-pointer accent-gray-500"
210-
disabled={isLoading}
211-
/>
212-
<span className="text-gray-300 text-xs sm:text-sm">Remember me</span>
213-
</label>
214-
<Link
215-
to="/forgot-password"
216-
className="text-gray-300 hover:text-white hover:underline text-xs sm:text-sm transition-all duration-200"
217-
>
218-
Forgot password?
219-
</Link>
220-
</div>
221-
</div>
222-
223-
{/* Submit Button */}
224-
<button
225-
type="submit"
226-
disabled={loading}
227-
className="w-full bg-gray-400 hover:bg-gray-500 disabled:bg-gray-600 disabled:cursor-not-allowed text-black font-bold py-2.5 text-sm sm:text-base rounded-lg transition-colors duration-200 mt-6 sm:mt-7 md:mt-8 flex items-center justify-center gap-2"
228-
>
229-
{loading ? (
230-
<>
231-
<span className="inline-block w-4 h-4 border-2 border-black border-t-transparent rounded-full animate-spin"></span>
232-
Logging in...
233-
</>
234-
) : (
235-
'Log In'
236-
)}
237-
disabled={isLoading}
238-
className={`w-full font-bold py-2.5 text-sm sm:text-base rounded-lg transition-colors duration-200 mt-6 sm:mt-7 md:mt-8 ${
239-
isLoading
240-
? 'bg-gray-600 text-gray-300 cursor-not-allowed'
241-
: 'bg-gray-400 hover:bg-gray-500 text-black'
242-
}`}
243-
>
244-
{isLoading ? 'Logging in...' : 'Log In'}
245-
</button>
246-
</form>
37+
const handleSubmit = (e: React.FormEvent) => {
38+
e.preventDefault()
39+
handleLogin()
40+
}
24741

248-
<p className="text-gray-400 text-xs sm:text-sm mt-4 sm:mt-5 md:mt-6 text-center">
249-
Don't have an account?{' '}
250-
<Link
251-
to="/register"
252-
className="text-white hover:text-gray-300 hover:underline transition-all duration-200"
253-
>
254-
Create Account
255-
</Link>
256-
</p>
42+
return (
43+
<div className="min-h-screen flex items-center justify-center bg-zinc-900">
44+
<form
45+
onSubmit={handleSubmit}
46+
className="bg-zinc-800 p-8 rounded-lg border border-zinc-500/50"
47+
>
48+
<h2 className="text-2xl font-bold text-white mb-6">Login</h2>
49+
50+
{error && <div className="bg-red-500/20 text-red-400 p-3 rounded mb-4">{error}</div>}
51+
52+
<div className="mb-4">
53+
<label className="block text-white mb-2">Email</label>
54+
<input
55+
type="email"
56+
value={email}
57+
onChange={e => setEmail(e.target.value)}
58+
className="w-full bg-zinc-700 text-white px-4 py-2 rounded"
59+
required
60+
/>
25761
</div>
25862

259-
{/* Right Section */}
260-
<div className="bg-gradient-to-br from-gray-700 to-gray-900 p-0 items-center justify-center hidden md:flex overflow-hidden">
261-
<img src={robotImg} alt="Robot" className="w-full h-full object-cover" />
63+
<div className="mb-6">
64+
<label className="block text-white mb-2">Password</label>
65+
<input
66+
type="password"
67+
value={password}
68+
onChange={e => setPassword(e.target.value)}
69+
className="w-full bg-zinc-700 text-white px-4 py-2 rounded"
70+
required
71+
/>
26272
</div>
263-
</div>
73+
74+
<button
75+
type="submit"
76+
className="w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-700 transition-colors"
77+
>
78+
Login
79+
</button>
80+
</form>
26481
</div>
26582
)
26683
}

0 commit comments

Comments
 (0)