@@ -7,11 +7,14 @@ import { useNavigate } from 'react-router-dom';
7
7
const Home = ( ) => {
8
8
const [ message , setMessage ] = useState ( '' ) ;
9
9
const [ username , setUsername ] = useState ( '' ) ;
10
+ const [ role , setRole ] = useState ( '' ) ; // NEW: store role
10
11
const [ error , setError ] = useState ( '' ) ;
11
12
const [ announcements , setAnnouncements ] = useState ( [ ] ) ;
12
13
const [ isFriendsModalOpen , setFriendsModalOpen ] = useState ( false ) ;
13
14
const [ isMessagesModalOpen , setMessagesModalOpen ] = useState ( false ) ;
14
15
const [ isSignOutModalOpen , setSignOutModalOpen ] = useState ( false ) ;
16
+ const [ showStats , setShowStats ] = useState ( false ) ; // NEW: show/hide stats modal
17
+ const [ stats , setStats ] = useState ( null ) ; // NEW: store stats
15
18
const navigate = useNavigate ( ) ;
16
19
17
20
useEffect ( ( ) => {
@@ -25,6 +28,7 @@ const Home = () => {
25
28
. then ( ( data ) => {
26
29
setMessage ( data . message ) ;
27
30
setUsername ( data . user ) ;
31
+ setRole ( data . role ) ; // NEW: set role
28
32
} )
29
33
. catch ( ( err ) => setError ( err . message ) ) ;
30
34
@@ -45,15 +49,54 @@ const Home = () => {
45
49
navigate ( '/login' ) ;
46
50
} ;
47
51
52
+ // Fetch statistics when modal is opened
53
+ const handleShowStats = async ( ) => {
54
+ try {
55
+ const res = await fetch ( 'http://localhost:8081/api/admin/statistics' , { credentials : 'include' } ) ;
56
+ if ( ! res . ok ) throw new Error ( 'Failed to fetch statistics' ) ;
57
+ const data = await res . json ( ) ;
58
+ setStats ( data ) ;
59
+ } catch ( e ) {
60
+ setStats ( { error : 'Failed to fetch statistics' } ) ;
61
+ }
62
+ setShowStats ( true ) ;
63
+ } ;
64
+
48
65
return (
49
66
< div className = "auth-container" >
50
- { /* Top-left sign out button */ }
51
- < div className = "top-left-signout" >
52
- < button className = "signout-icon-button" onClick = { ( ) => setSignOutModalOpen ( true ) } title = "Sign Out" >
53
- ⬅️
54
- </ button >
67
+ { /* Top-left action bar */ }
68
+ < div style = { { position : 'fixed' , top : 24 , left : 32 , display : 'flex' , gap : 12 , zIndex : 2000 , background : '#fff' , borderRadius : 8 , boxShadow : '0 2px 8px rgba(0,0,0,0.10)' , padding : '6px 12px' } } >
69
+ { role === 'ROLE_ADMIN' && (
70
+ < >
71
+ < button onClick = { ( ) => navigate ( '/admin' ) } style = { { background : '#312e81' , color : '#fff' , border : 'none' , borderRadius : 8 , padding : '10px 20px' , fontWeight : 700 , fontSize : 16 , boxShadow : '0 2px 8px rgba(49,46,129,0.08)' , cursor : 'pointer' , transition : 'background 0.2s' } } onMouseOver = { e => e . currentTarget . style . background = '#4338ca' } onMouseOut = { e => e . currentTarget . style . background = '#312e81' } > Admin</ button >
72
+ < button onClick = { handleShowStats } style = { { background : '#0d9488' , color : '#fff' , border : 'none' , borderRadius : 8 , padding : '10px 20px' , fontWeight : 700 , fontSize : 16 , boxShadow : '0 2px 8px rgba(13,148,136,0.08)' , cursor : 'pointer' , transition : 'background 0.2s' } } onMouseOver = { e => e . currentTarget . style . background = '#14b8a6' } onMouseOut = { e => e . currentTarget . style . background = '#0d9488' } > Statistics</ button >
73
+ </ >
74
+ ) }
75
+ < button onClick = { ( ) => setMessagesModalOpen ( true ) } style = { { background : '#2563eb' , color : '#fff' , border : 'none' , borderRadius : 8 , padding : '10px 20px' , fontWeight : 700 , fontSize : 16 , boxShadow : '0 2px 8px rgba(37,99,235,0.08)' , cursor : 'pointer' , transition : 'background 0.2s' } } onMouseOver = { e => e . currentTarget . style . background = '#1d4ed8' } onMouseOut = { e => e . currentTarget . style . background = '#2563eb' } > Messages</ button >
76
+ < button onClick = { ( ) => setFriendsModalOpen ( true ) } style = { { background : '#059669' , color : '#fff' , border : 'none' , borderRadius : 8 , padding : '10px 20px' , fontWeight : 700 , fontSize : 16 , boxShadow : '0 2px 8px rgba(5,150,105,0.08)' , cursor : 'pointer' , transition : 'background 0.2s' } } onMouseOver = { e => e . currentTarget . style . background = '#10b981' } onMouseOut = { e => e . currentTarget . style . background = '#059669' } > Friends</ button >
77
+ < button onClick = { ( ) => setSignOutModalOpen ( true ) } style = { { background : '#e11d48' , color : '#fff' , border : 'none' , borderRadius : 8 , padding : '10px 20px' , fontWeight : 700 , fontSize : 16 , boxShadow : '0 2px 8px rgba(225,29,72,0.08)' , cursor : 'pointer' , transition : 'background 0.2s' } } onMouseOver = { e => e . currentTarget . style . background = '#be123c' } onMouseOut = { e => e . currentTarget . style . background = '#e11d48' } > Sign Out</ button >
55
78
</ div >
56
79
80
+ { /* Statistics Modal */ }
81
+ { showStats && (
82
+ < div style = { { position : 'fixed' , top : 0 , left : 0 , width : '100vw' , height : '100vh' , background : 'rgba(0,0,0,0.25)' , zIndex : 3000 , display : 'flex' , alignItems : 'center' , justifyContent : 'center' } } >
83
+ < div style = { { background : '#fff' , borderRadius : 12 , padding : 32 , minWidth : 320 , boxShadow : '0 4px 24px rgba(0,0,0,0.12)' , position : 'relative' } } >
84
+ < button onClick = { ( ) => setShowStats ( false ) } style = { { position : 'absolute' , top : 12 , right : 12 , background : 'none' , border : 'none' , fontSize : 22 , cursor : 'pointer' , color : '#888' } } > ×</ button >
85
+ < h2 style = { { color : '#4f46e5' , marginBottom : 18 } } > Site Statistics</ h2 >
86
+ { stats ? (
87
+ stats . error ? < div style = { { color : 'red' } } > { stats . error } </ div > :
88
+ < ul style = { { fontSize : 18 , lineHeight : 2 } } >
89
+ < li > < b > Users:</ b > { stats . users } </ li >
90
+ < li > < b > Quizzes:</ b > { stats . quizzes } </ li >
91
+ < li > < b > Quizzes Taken:</ b > { stats . quizzesTaken } </ li >
92
+ </ ul >
93
+ ) : (
94
+ < div > Loading...</ div >
95
+ ) }
96
+ </ div >
97
+ </ div >
98
+ ) }
99
+
57
100
{ /* Sign-out Modal */ }
58
101
{ isSignOutModalOpen && (
59
102
< div className = "signout-modal-overlay" >
@@ -89,7 +132,7 @@ const Home = () => {
89
132
< li key = { a . id } >
90
133
< strong > { a . title } </ strong > < br />
91
134
< span > { a . content } </ span > < br />
92
- < small > { new Date ( a . createdAt ) . toLocaleString ( ) } </ small >
135
+ < small > { new Date ( a . createdAt ) . toLocaleString ( undefined , { year : 'numeric' , month : '2-digit' , day : '2-digit' , hour : '2-digit' , minute : '2-digit' } ) } </ small >
93
136
< hr />
94
137
</ li >
95
138
) ) }
@@ -101,16 +144,6 @@ const Home = () => {
101
144
< button onClick = { ( ) => navigate ( '/quizzes' ) } style = { { marginTop : '20px' , marginRight : '10px' } } > Browse Quizzes</ button >
102
145
< button onClick = { ( ) => navigate ( '/create-quiz' ) } style = { { marginTop : '20px' } } > Create a Quiz</ button >
103
146
104
- { /* Top-right floating icons */ }
105
- < div className = "top-right-icons" >
106
- < button onClick = { ( ) => setMessagesModalOpen ( true ) } className = "messages-icon-button" title = "Messages" >
107
- 💬
108
- </ button >
109
- < button onClick = { ( ) => setFriendsModalOpen ( true ) } className = "friends-icon-button" title = "Friends" >
110
- 👥
111
- </ button >
112
- </ div >
113
-
114
147
{ /* Modals */ }
115
148
< FriendsModal
116
149
isOpen = { isFriendsModalOpen }
0 commit comments