@@ -4,74 +4,86 @@ import { Line } from 'react-chartjs-2';
44import { Chart as ChartJS , LineElement , CategoryScale , LinearScale , Tooltip , Legend , PointElement } from 'chart.js' ;
55import logoutIcon from '../logout.png' ;
66import { useNavigate } from 'react-router-dom' ;
7+ import { Eye , EyeOff } from 'lucide-react' ;
78
89ChartJS . register ( LineElement , CategoryScale , LinearScale , Tooltip , Legend , PointElement ) ;
910
1011const reportData = {
11- labels : [ 'Total Reports' , 'Monthly Reports' , 'Active Users' ] ,
12- datasets : [
13- {
14- label : 'Total Reports' ,
15- data : [ 24 , 22 , 20 , 18 , 16 ] ,
16- borderColor : '#1e88e5' ,
17- borderWidth : 2 ,
18- pointBackgroundColor : '#1e88e5' ,
19- fill : false ,
20- } ,
21- {
22- label : 'Monthly Reports' ,
23- data : [ 12 , 10 , 8 , 6 , 4 ] ,
24- borderColor : '#43a047' ,
25- borderWidth : 2 ,
26- pointBackgroundColor : '#43a047' ,
27- fill : false ,
28- } ,
29- {
30- label : 'Active Users' ,
31- data : [ 8 , 7 , 6 , 5 , 4 ] ,
32- borderColor : '#fbc02d' ,
33- borderWidth : 2 ,
34- pointBackgroundColor : '#fbc02d' ,
35- fill : false ,
36- } ,
37- ] ,
12+ labels : [ 'Total Reports' , 'Monthly Reports' , 'Active Users' ] ,
13+ datasets : [
14+ {
15+ label : 'Total Reports' ,
16+ data : [ 24 , 22 , 20 , 18 , 16 ] ,
17+ borderColor : '#1e88e5' ,
18+ borderWidth : 2 ,
19+ pointBackgroundColor : '#1e88e5' ,
20+ fill : false ,
21+ } ,
22+ {
23+ label : 'Monthly Reports' ,
24+ data : [ 12 , 10 , 8 , 6 , 4 ] ,
25+ borderColor : '#43a047' ,
26+ borderWidth : 2 ,
27+ pointBackgroundColor : '#43a047' ,
28+ fill : false ,
29+ } ,
30+ {
31+ label : 'Active Users' ,
32+ data : [ 8 , 7 , 6 , 5 , 4 ] ,
33+ borderColor : '#fbc02d' ,
34+ borderWidth : 2 ,
35+ pointBackgroundColor : '#fbc02d' ,
36+ fill : false ,
37+ } ,
38+ ] ,
3839} ;
3940
4041const reportOptions = {
41- responsive : true ,
42- plugins : {
43- legend : {
44- position : 'top' ,
45- } ,
46- tooltip : {
47- enabled : true ,
42+ responsive : true ,
43+ plugins : {
44+ legend : {
45+ position : 'top' ,
46+ } ,
47+ tooltip : {
48+ enabled : true ,
49+ } ,
4850 } ,
49- } ,
50- scales : {
51- y : {
52- beginAtZero : true ,
51+ scales : {
52+ y : {
53+ beginAtZero : true ,
54+ } ,
5355 } ,
54- } ,
5556} ;
5657
5758const Admin = ( ) => {
5859 const [ activeTab , setActiveTab ] = useState ( 'dashboard' ) ;
5960 const [ users , setUsers ] = useState ( [ ] ) ;
61+ const [ admins , setAdmins ] = useState ( [ ] ) ;
6062 const [ adminUsername , setAdminUsername ] = useState ( '' ) ;
63+ const [ showPassword , setShowPassword ] = useState ( { } ) ;
6164 const navigate = useNavigate ( ) ;
6265
6366 useEffect ( ( ) => {
6467 const storedUsername = localStorage . getItem ( 'username' ) ;
6568 setAdminUsername ( storedUsername || '' ) ;
6669 } , [ ] ) ;
67-
70+
6871 useEffect ( ( ) => {
6972 fetch ( 'http://localhost:5000/api/users' )
7073 . then ( response => response . json ( ) )
7174 . then ( data => setUsers ( data ) )
7275 . catch ( error => console . error ( 'Error fetching users:' , error ) ) ;
7376 } , [ ] ) ;
7477
78+ useEffect ( ( ) => {
79+ if ( activeTab === 'admins' ) {
80+ fetch ( 'http://localhost:5000/api/admins' )
81+ . then ( response => response . json ( ) )
82+ . then ( data => setAdmins ( data ) )
83+ . catch ( error => console . error ( 'Error fetching admins:' , error ) ) ;
84+ }
85+ } , [ activeTab ] ) ;
86+
7587 useEffect ( ( ) => {
7688 const isUser = localStorage . getItem ( 'is_user' ) ;
7789 if ( isUser === 'true' ) {
@@ -96,6 +108,12 @@ const Admin = () => {
96108 >
97109 Users
98110 </ button >
111+ < button
112+ className = { activeTab === 'admins' ? 'active' : '' }
113+ onClick = { ( ) => setActiveTab ( 'admins' ) }
114+ >
115+ Admins
116+ </ button >
99117 < button
100118 className = { activeTab === 'settings' ? 'active' : '' }
101119 onClick = { ( ) => setActiveTab ( 'settings' ) }
@@ -149,32 +167,98 @@ const Admin = () => {
149167 </ div >
150168 </ div >
151169 < div style = { { marginTop : '32px' , background : 'linear-gradient(135deg, #0a0821, #1a103d)' , borderRadius : '18px' , padding : '24px' , color : '#e0e0e0' , textAlign : 'center' , boxShadow : '0 4px 16px rgba(0, 0, 0, 0.4)' } } >
152- < h3 style = { { color : '#e0e0e0' , marginBottom : '16px' , textShadow : '0 2px 4px rgba(0, 0, 0, 0.6)' } } > Recent Activities</ h3 >
153- < ul style = { { listStyleType : 'circle' , padding : '0 20px' , textAlign : 'left' } } >
154- < li style = { { marginBottom : '12px' , color : '#7c3aed' } } > User John updated profile</ li >
155- < li style = { { marginBottom : '12px' , color : '#388e3c' } } > Admin added a new user</ li >
156- < li style = { { marginBottom : '12px' , color : '#f9a825' } } > System alert resolved</ li >
157- </ ul >
170+ < h3 style = { { color : '#e0e0e0' , marginBottom : '16px' , textShadow : '0 2px 4px rgba(0, 0, 0, 0.6)' } } > Recent Activities</ h3 >
171+ < ul style = { { listStyleType : 'circle' , padding : '0 20px' , textAlign : 'left' } } >
172+ < li style = { { marginBottom : '12px' , color : '#7c3aed' } } > User John updated profile</ li >
173+ < li style = { { marginBottom : '12px' , color : '#388e3c' } } > Admin added a new user</ li >
174+ < li style = { { marginBottom : '12px' , color : '#f9a825' } } > System alert resolved</ li >
175+ </ ul >
158176 </ div >
159177 </ div >
160178 ) }
161179 { activeTab === 'users' && (
162180 < div >
163181 < h2 > User Management</ h2 >
164- < div className = "posts-list" >
165- { users . map ( user => (
166- < div className = "post-item" key = { user [ 0 ] } >
167- < h4 > { user [ 1 ] } </ h4 >
168- < div className = "post-meta" >
169- < span > { user [ 2 ] } </ span >
170- < span > Joined: { user [ 3 ] } </ span >
171- </ div >
172- < div className = "post-actions" >
173- < button className = "edit-btn" > Edit</ button >
174- < button className = "delete-btn" > Remove</ button >
175- </ div >
176- </ div >
177- ) ) }
182+ < div className = "user-table-container" style = { { overflowX : 'auto' , marginTop : '24px' } } >
183+ < table className = "user-table" style = { { width : '100%' , borderCollapse : 'collapse' , background : 'rgba(23,18,41,0.7)' , borderRadius : '12px' , boxShadow : '0 2px 8px rgba(0,0,0,0.08)' } } >
184+ < thead >
185+ < tr style = { { background : '#1a103d' , color : '#a78bfa' } } >
186+ < th style = { { padding : '12px 16px' , textAlign : 'left' } } > Username</ th >
187+ < th style = { { padding : '12px 16px' , textAlign : 'left' } } > Email</ th >
188+ < th style = { { padding : '12px 16px' , textAlign : 'left' } } > Role</ th >
189+ < th style = { { padding : '12px 16px' , textAlign : 'left' } } > Password</ th >
190+ < th style = { { padding : '12px 16px' , textAlign : 'left' } } > Actions</ th >
191+ </ tr >
192+ </ thead >
193+ < tbody >
194+ { users . map ( user => (
195+ < tr key = { user . id } style = { { borderBottom : '1px solid #2d225a' } } >
196+ < td style = { { padding : '10px 16px' , color : '#f8fafc' } } > { user . username } </ td >
197+ < td style = { { padding : '10px 16px' , color : '#f8fafc' } } > { user . email } </ td >
198+ < td style = { { padding : '10px 16px' , color : user . is_user ? '#43a047' : '#e10600' , fontWeight : 600 } } >
199+ { user . is_user ? 'User' : 'Admin' }
200+ </ td >
201+ < td style = { { padding : '10px 16px' , color : '#f8fafc' } } >
202+ < span style = { { marginRight : 42 } } > { showPassword [ user . id ] ? user . password : '••••••••••••' } </ span >
203+ < button
204+ style = { { background : 'none' , border : 'none' , color : '#7c3aed' , cursor : 'pointer' , fontWeight : 600 } }
205+ onClick = { ( ) => setShowPassword ( prev => ( { ...prev , [ user . id ] : ! prev [ user . id ] } ) ) }
206+ title = { showPassword [ user . id ] ? 'Hide password' : 'Show password' }
207+ type = "button"
208+ >
209+ { showPassword [ user . id ] ? < EyeOff size = { 18 } /> : < Eye size = { 18 } /> }
210+ </ button >
211+ </ td >
212+ < td style = { { padding : '10px 16px' } } >
213+ < button className = "edit-btn" style = { { marginRight : '8px' } } > Edit</ button >
214+ < button className = "delete-btn" > Remove</ button >
215+ </ td >
216+ </ tr >
217+ ) ) }
218+ </ tbody >
219+ </ table >
220+ </ div >
221+ </ div >
222+ ) }
223+ { activeTab === 'admins' && (
224+ < div >
225+ < h2 > Admin Management</ h2 >
226+ < div className = "user-table-container" style = { { overflowX : 'auto' , marginTop : '24px' } } >
227+ < table className = "user-table" style = { { width : '100%' , borderCollapse : 'collapse' , background : 'rgba(23,18,41,0.7)' , borderRadius : '12px' , boxShadow : '0 2px 8px rgba(0,0,0,0.08)' } } >
228+ < thead >
229+ < tr style = { { background : '#1a103d' , color : '#a78bfa' } } >
230+ < th style = { { padding : '12px 16px' , textAlign : 'left' } } > Username</ th >
231+ < th style = { { padding : '12px 16px' , textAlign : 'left' } } > Email</ th >
232+ < th style = { { padding : '12px 16px' , textAlign : 'left' } } > Role</ th >
233+ < th style = { { padding : '12px 16px' , textAlign : 'left' } } > Password</ th >
234+ < th style = { { padding : '12px 16px' , textAlign : 'left' } } > Actions</ th >
235+ </ tr >
236+ </ thead >
237+ < tbody >
238+ { admins . map ( admin => (
239+ < tr key = { admin . id } style = { { borderBottom : '1px solid #2d225a' } } >
240+ < td style = { { padding : '10px 16px' , color : '#f8fafc' } } > { admin . username } </ td >
241+ < td style = { { padding : '10px 16px' , color : '#f8fafc' } } > { admin . email } </ td >
242+ < td style = { { padding : '10px 16px' , color : '#e10600' , fontWeight : 600 } } > Admin</ td >
243+ < td style = { { padding : '10px 16px' , color : '#f8fafc' } } >
244+ < span style = { { marginRight : 42 } } > { showPassword [ 'admin-' + admin . id ] ? ( admin . password || '••••••••••••' ) : '••••••••••••' } </ span >
245+ < button
246+ style = { { background : 'none' , border : 'none' , color : '#7c3aed' , cursor : 'pointer' , fontWeight : 600 } }
247+ onClick = { ( ) => setShowPassword ( prev => ( { ...prev , [ 'admin-' + admin . id ] : ! prev [ 'admin-' + admin . id ] } ) ) }
248+ title = { showPassword [ 'admin-' + admin . id ] ? 'Hide password' : 'Show password' }
249+ type = "button"
250+ >
251+ { showPassword [ 'admin-' + admin . id ] ? < EyeOff size = { 18 } /> : < Eye size = { 18 } /> }
252+ </ button >
253+ </ td >
254+ < td style = { { padding : '10px 16px' } } >
255+ < button className = "edit-btn" style = { { marginRight : '8px' } } > Edit</ button >
256+ < button className = "delete-btn" > Remove</ button >
257+ </ td >
258+ </ tr >
259+ ) ) }
260+ </ tbody >
261+ </ table >
178262 </ div >
179263 </ div >
180264 ) }
@@ -303,4 +387,4 @@ const Admin = () => {
303387 ) ;
304388} ;
305389
306- export default Admin ;
390+ export default Admin ;
0 commit comments