source: frontend/src/pages/Login.js@ 84249b1

Last change on this file since 84249b1 was 84249b1, checked in by MBK <marija.karapandzova@…>, 4 months ago

Add authentication and role-based route protection and add Dashboard page

  • Property mode set to 100644
File size: 4.4 KB
Line 
1import React, { useState } from 'react';
2import { useNavigate } from 'react-router-dom';
3import ErrorAlert from '../components/ErrorAlert';
4import SuccessAlert from '../components/SuccessAlert';
5
6function Login() {
7 const [username, setUsername] = useState('');
8 const [password, setPassword] = useState('');
9 const [loading, setLoading] = useState(false);
10 const [error, setError] = useState(null);
11 const [success, setSuccess] = useState(null);
12 const navigate = useNavigate();
13
14 const handleLogin = async (e) => {
15 e.preventDefault();
16
17 if (!username.trim()) {
18 setError('Username is required');
19 return;
20 }
21 if (!password.trim()) {
22 setError('Password is required');
23 return;
24 }
25
26 try {
27 setLoading(true);
28 setError(null);
29
30 const response = await fetch('/api/auth/login', {
31 method: 'POST',
32 headers: {
33 'Content-Type': 'application/json',
34 },
35 body: JSON.stringify({
36 username,
37 password,
38 }),
39 });
40
41 if (!response.ok) {
42 const errorData = await response.json();
43 throw new Error(errorData.error || 'Login failed');
44 }
45
46 const data = await response.json();
47
48 localStorage.setItem('token', data.token);
49 localStorage.setItem('user', JSON.stringify({
50 userId: data.userId,
51 patientId: data.patientId,
52 doctorId: data.doctorId,
53 username: data.username,
54 role: data.role,
55 firstName: data.firstName,
56 lastName: data.lastName,
57 }));
58
59 setSuccess('Login successful! Redirecting...');
60 setTimeout(() => {
61 navigate('/');
62 }, 1000);
63 } catch (err) {
64 setError(err.message || 'Login failed');
65 } finally {
66 setLoading(false);
67 }
68 };
69
70 return (
71 <div className="min-h-screen bg-blue-200 flex items-center justify-center p-4">
72 <div className="bg-white rounded-lg shadow-2xl p-8 w-full max-w-md">
73 <div className="text-center mb-8">
74 <h1 className="text-5xl font-bold text-purple-600 mb-2">Medora</h1>
75 <p className="text-gray-600">Hospital Management System</p>
76 </div>
77
78 {error && <ErrorAlert message={error} onClose={() => setError(null)} />}
79 {success && <SuccessAlert message={success} onClose={() => setSuccess(null)} />}
80
81 <form onSubmit={handleLogin} className="space-y-6">
82 <div>
83 <label className="block text-sm font-normal text-gray-700 mb-2">
84 Username (EMBG for Patients)
85 </label>
86 <input
87 type="text"
88 value={username}
89 onChange={(e) => setUsername(e.target.value)}
90 placeholder="Enter your username or EMBG"
91 className="w-full px-4 py-3 border-2 border-gray-300 rounded-lg focus:outline-none focus:border-purple-500 transition"
92 disabled={loading}
93 />
94 </div>
95
96 <div>
97 <label className="block text-sm font-normal text-gray-700 mb-2">
98 Password
99 </label>
100 <input
101 type="password"
102 value={password}
103 onChange={(e) => setPassword(e.target.value)}
104 placeholder="Enter your password"
105 className="w-full px-4 py-3 border-2 border-gray-300 rounded-lg focus:outline-none focus:border-purple-500 transition"
106 disabled={loading}
107 />
108 </div>
109
110 <button
111 type="submit"
112 disabled={loading}
113 className="w-full bg-purple-600 text-white font-bold py-3 rounded-lg hover:bg-purple-700 transition disabled:opacity-50 disabled:cursor-not-allowed"
114 >
115 {loading ? 'Logging in...' : 'Login'}
116 </button>
117 </form>
118
119 <div className="mt-8 p-4 bg-purple-50 rounded-lg border border-purple-200">
120 <p className="text-sm text-gray-700 font-normal mb-2">Demo Credentials:</p>
121 <p className="text-sm text-gray-600 mb-2">
122 <strong>Admin:</strong> username: admin | password: admin123
123 </p>
124 <p className="text-sm text-gray-600 mb-2">
125 <strong>Doctor:</strong> username: ivan.stojanov@medora.com | password: doctor123
126 </p>
127 <p className="text-sm text-gray-600">
128 <strong>Patient:</strong> username: [EMBG] | password: password123
129 </p>
130 </div>
131 </div>
132 </div>
133 );
134}
135
136export default Login;
Note: See TracBrowser for help on using the repository browser.