source: frontend/src/components/Navbar.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 6.6 KB
Line 
1import React, { useState, useEffect } from 'react';
2import { Link, useNavigate, useLocation } from 'react-router-dom';
3
4function Navbar() {
5 const [user, setUser] = useState(null);
6 const [showMenu, setShowMenu] = useState(false);
7 const navigate = useNavigate();
8 const location = useLocation();
9
10 useEffect(() => {
11 const loadUser = () => {
12 const userStr = localStorage.getItem('user');
13 if (userStr) {
14 setUser(JSON.parse(userStr));
15 } else {
16 setUser(null);
17 }
18 };
19
20 // Load user on mount
21 loadUser();
22
23 // Listen for storage changes (when user logs in/out)
24 window.addEventListener('storage', loadUser);
25 return () => window.removeEventListener('storage', loadUser);
26 }, []);
27
28 const handleLogout = () => {
29 localStorage.removeItem('token');
30 localStorage.removeItem('user');
31 setUser(null);
32
33 // Dispatch custom event to notify components on the same tab
34 window.dispatchEvent(new CustomEvent('userStorageChange', {
35 detail: { userData: null }
36 }));
37
38 navigate('/login');
39 };
40
41 const isActive = (path) => location.pathname === path;
42
43 const getInitials = () => {
44 if (!user) return '';
45 return `${user.firstName?.[0]}${user.lastName?.[0]}`.toUpperCase();
46 };
47
48 return (
49 <nav className="navbar">
50 <div className="navbar-brand">
51 <img src="/logo.png" alt="Medora Logo" style={{ height: '40px', width: 'auto' }} />
52 </div>
53
54 <div className="navbar-links">
55 <Link to="/" className={`navbar-link ${isActive('/') ? 'active' : ''}`}>
56 Overview
57 </Link>
58 {user?.role !== 'PATIENT' && user?.role !== 'LAB_TECHNICIAN' && user?.role !== 'BILLING_ADMIN' && (
59 <Link to="/patients" className={`navbar-link ${isActive('/patients') ? 'active' : ''}`}>
60 Patients
61 </Link>
62 )}
63 <Link to="/doctors" className={`navbar-link ${isActive('/doctors') ? 'active' : ''}`}>
64 Doctors
65 </Link>
66 <Link to="/departments" className={`navbar-link ${isActive('/departments') ? 'active' : ''}`}>
67 Departments
68 </Link>
69 {user?.role !== 'LAB_TECHNICIAN' && user?.role !== 'BILLING_ADMIN' && (
70 <>
71 <Link to="/appointments" className={`navbar-link ${isActive('/appointments') ? 'active' : ''}`}>
72 Appointments
73 </Link>
74 {user?.role === 'PATIENT' && (
75 <>
76 <Link to="/medical-records" className={`navbar-link ${isActive('/medical-records') ? 'active' : ''}`}>
77 Medical Records
78 </Link>
79 <Link to="/billing" className={`navbar-link ${isActive('/billing') ? 'active' : ''}`}>
80 Billing
81 </Link>
82 </>
83 )}
84 </>
85 )}
86 {(user?.role === 'ADMIN' || user?.role === 'LAB_TECHNICIAN' || user?.role === 'DOCTOR') && (
87 <Link to="/lab-tests" className={`navbar-link ${isActive('/lab-tests') ? 'active' : ''}`}>
88 Lab Tests
89 </Link>
90 )}
91 {!user?.role || user?.role === 'ADMIN' || user?.role === 'DOCTOR' ? (
92 <>
93 {user?.role !== 'LAB_TECHNICIAN' && user?.role !== 'BILLING_ADMIN' && (
94 <Link to="/medical-records" className={`navbar-link ${isActive('/medical-records') ? 'active' : ''}`}>
95 Medical Records
96 </Link>
97 )}
98 {user?.role !== 'PATIENT' && user?.role !== 'LAB_TECHNICIAN' && user?.role !== 'BILLING_ADMIN' && (
99 <>
100 <Link to="/medical-reports" className={`navbar-link ${isActive('/medical-reports') ? 'active' : ''}`}>
101 Medical Reports
102 </Link>
103 <Link to="/procedures" className={`navbar-link ${isActive('/procedures') ? 'active' : ''}`}>
104 Procedures
105 </Link>
106 <Link to="/referrals" className={`navbar-link ${isActive('/referrals') ? 'active' : ''}`}>
107 Referrals
108 </Link>
109 </>
110 )}
111 </>
112 ) : null}
113 {(user?.role === 'ADMIN' || user?.role === 'BILLING_ADMIN') && (
114 <Link to="/billing" className={`navbar-link ${isActive('/billing') ? 'active' : ''}`}>
115 Billing
116 </Link>
117 )}
118 </div>
119
120 <div className="navbar-right">
121 {user && (
122 <div className="navbar-avatar" style={{ position: 'relative' }}>
123 <div className="navbar-avatar-circle">{getInitials()}</div>
124 <div className="navbar-avatar-name">{user.firstName}</div>
125 <button
126 onClick={() => setShowMenu(!showMenu)}
127 style={{
128 background: 'none',
129 border: 'none',
130 cursor: 'pointer',
131 marginLeft: '4px',
132 color: 'var(--color-neutral-600)',
133 fontSize: '12px'
134 }}
135 >
136
137 </button>
138 {showMenu && (
139 <div style={{
140 position: 'absolute',
141 top: '100%',
142 right: 0,
143 background: 'white',
144 border: '1px solid var(--color-neutral-400)',
145 borderRadius: '6px',
146 minWidth: '150px',
147 marginTop: '4px',
148 boxShadow: '0 4px 6px rgba(0,0,0,0.1)',
149 zIndex: 1000
150 }}>
151 <div style={{
152 padding: '8px 0',
153 fontSize: '11px',
154 color: 'var(--color-neutral-600)',
155 borderBottom: '1px solid var(--color-neutral-400)',
156 paddingLeft: '12px',
157 paddingRight: '12px',
158 paddingTop: '8px',
159 paddingBottom: '8px'
160 }}>
161 {user.role}
162 </div>
163 <button
164 onClick={handleLogout}
165 style={{
166 width: '100%',
167 padding: '8px 12px',
168 background: 'none',
169 border: 'none',
170 textAlign: 'left',
171 cursor: 'pointer',
172 fontSize: '12px',
173 color: 'var(--color-status-red)',
174 transition: 'background 0.2s'
175 }}
176 onMouseEnter={(e) => e.target.style.background = 'var(--color-neutral-200)'}
177 onMouseLeave={(e) => e.target.style.background = 'none'}
178 >
179 Logout
180 </button>
181 </div>
182 )}
183 </div>
184 )}
185 </div>
186 </nav>
187 );
188}
189
190export default Navbar;
Note: See TracBrowser for help on using the repository browser.