@@ -8,22 +8,22 @@ import {
8
8
Toolbar ,
9
9
Menu ,
10
10
MenuItem ,
11
+ Divider ,
11
12
Typography ,
12
13
Button ,
13
14
IconButton ,
14
15
FormControl ,
15
16
InputLabel ,
16
17
TextField ,
17
18
Select ,
18
- Backdrop ,
19
19
Dialog ,
20
20
DialogActions ,
21
21
DialogContent ,
22
22
DialogTitle ,
23
- Fade ,
24
23
} from '@mui/material' ;
25
24
import { makeStyles } from '@mui/styles'
26
25
import AddIcon from '@mui/icons-material/Add' ;
26
+ import WidgetsIcon from '@mui/icons-material/Widgets' ;
27
27
import AccountCircleIcon from '@mui/icons-material/AccountCircle' ;
28
28
import { User } from '@firebase/auth' ;
29
29
import { ref , set , onValue , DataSnapshot } from '@firebase/database' ;
@@ -56,6 +56,9 @@ const useStyles = makeStyles((theme) => ({
56
56
title : {
57
57
flexGrow : 1 ,
58
58
} ,
59
+ profile : {
60
+ flexGrow : 1
61
+ } ,
59
62
} ) ) ;
60
63
61
64
type Widget = {
@@ -65,18 +68,15 @@ type Widget = {
65
68
66
69
type WidgetList = { [ key : string ] : Widget }
67
70
68
- const Widgets = ( ) => {
71
+ const Widgets = ( { profile } : { profile : string } ) => {
69
72
const [ widgets , setWidgets ] = useState < WidgetList > ( { } ) ;
70
- const profile = 'default' ;
71
73
72
74
useEffect ( ( ) => {
73
75
const widgetsRef = ref ( db , `/profiles/${ profile } /widgets` ) ;
74
76
onValue ( widgetsRef , ( snap : DataSnapshot ) => {
75
- if ( snap ?. val ( ) ) {
76
- setWidgets ( snap . val ( ) ) ;
77
- }
77
+ setWidgets ( snap . val ( ) || { } ) ;
78
78
} ) ;
79
- } , [ ] ) ;
79
+ } , [ profile ] ) ;
80
80
81
81
return (
82
82
< div >
@@ -91,8 +91,7 @@ const Widgets = () => {
91
91
) ;
92
92
} ;
93
93
94
- const AddWidgetModel = ( { open, onClose } : { open : boolean , onClose : ( ) => void } ) => {
95
- const profile = 'default' ;
94
+ const AddWidgetDialog = ( { profile, open, onClose } : { profile : string , open : boolean , onClose : ( ) => void } ) => {
96
95
const [ widgetId , setWidgetId ] = useState ( "" ) ;
97
96
const [ widgetType , setWidgetType ] = useState ( "text" ) ;
98
97
@@ -158,6 +157,34 @@ const AddWidgetModel = ({ open, onClose }: { open: boolean, onClose: () => void
158
157
name : widgetType ,
159
158
props : Editors [ widgetType ] . defaultProps
160
159
} ) ;
160
+
161
+ setWidgetId ( "" ) ;
162
+ setWidgetType ( "text" ) ;
163
+ onClose ( ) ;
164
+ } } > Add</ Button >
165
+ </ DialogActions >
166
+ </ Dialog >
167
+ ) ;
168
+ } ;
169
+
170
+ const AddProfileDialog = ( { open, onClose } : { open : boolean , onClose : ( ) => void } ) => {
171
+ const [ profileId , setProfileId ] = useState ( "" ) ;
172
+
173
+ return (
174
+ < Dialog open = { open } onClose = { onClose } >
175
+ < DialogTitle > Add Profile</ DialogTitle >
176
+ < DialogContent >
177
+ < FormControl variant = "standard" >
178
+ < TextField required autoFocus fullWidth label = "ID" value = { profileId } variant = "standard" onChange = { ( e ) => { setProfileId ( e . target . value ) ; } } />
179
+ </ FormControl >
180
+ </ DialogContent >
181
+ < DialogActions >
182
+ < Button color = "primary" variant = "contained" onClick = { ( ) => {
183
+ if ( profileId . length > 0 ) {
184
+ set ( ref ( db , `/profiles/${ profileId } /name` ) , profileId ) ;
185
+ setProfileId ( "" ) ;
186
+ onClose ( ) ;
187
+ }
161
188
} } > Add</ Button >
162
189
</ DialogActions >
163
190
</ Dialog >
@@ -167,18 +194,34 @@ const AddWidgetModel = ({ open, onClose }: { open: boolean, onClose: () => void
167
194
const AdminIndexPage = ( ) => {
168
195
const classes = useStyles ( ) ;
169
196
const [ currentUser , setCurrentUser ] = useState < User | null > ( null ) ;
170
- const [ anchorEl , setAnchorEl ] = useState < HTMLElement | null > ( null ) ;
171
- const [ addWidgetModalOpened , setAddWidgetModalOpened ] = useState ( false ) ;
172
- const isUserMenuOpen = Boolean ( anchorEl ) ;
197
+ const [ userAnchorEl , setUserAnchorEl ] = useState < HTMLElement | null > ( null ) ;
198
+ const [ profileAnchorEl , setProfileAnchorEl ] = useState < HTMLElement | null > ( null ) ;
199
+ const [ addProfileDialogOpened , setAddProfileDialogOpened ] = useState ( false ) ;
200
+ const [ addWidgetDialogOpened , setAddWidgetDialogOpened ] = useState ( false ) ;
201
+ const [ currentProfile , setCurrentProfile ] = useState ( 'default' ) ;
202
+ const [ profiles , setProfiles ] = useState < string [ ] > ( [ ] ) ;
203
+
204
+ const isUserMenuOpen = Boolean ( userAnchorEl ) ;
205
+ const isProfileMenuOpen = Boolean ( profileAnchorEl ) ;
173
206
174
207
useEffect ( ( ) => {
175
208
auth . onAuthStateChanged ( ( user ) => {
176
209
setCurrentUser ( user ) ;
177
210
} ) ;
178
211
} ) ;
179
212
213
+ useEffect ( ( ) => {
214
+ const profilesRef = ref ( db , `/profiles` ) ;
215
+ onValue ( profilesRef , ( snap : DataSnapshot ) => {
216
+ if ( snap ?. val ( ) ) {
217
+ setProfiles ( Object . keys ( snap . val ( ) ) ) ;
218
+ }
219
+ } ) ;
220
+ } , [ ] ) ;
221
+
180
222
const signout = async ( ) => {
181
- setAnchorEl ( null ) ;
223
+ setUserAnchorEl ( null ) ;
224
+ setProfileAnchorEl ( null ) ;
182
225
try {
183
226
await auth . signOut ( ) ;
184
227
} catch ( err ) {
@@ -188,10 +231,18 @@ const AdminIndexPage = () => {
188
231
189
232
const userMenuId = 'user-menu' ;
190
233
const handleUserMenuOpen = ( event : MouseEvent < HTMLElement > ) => {
191
- setAnchorEl ( event . currentTarget ) ;
234
+ setUserAnchorEl ( event . currentTarget ) ;
192
235
} ;
193
236
const handleUserMenuClose = ( ) => {
194
- setAnchorEl ( null ) ;
237
+ setUserAnchorEl ( null ) ;
238
+ } ;
239
+
240
+ const profileMenuId = 'profile-menu' ;
241
+ const handleProfileMenuOpen = ( event : MouseEvent < HTMLElement > ) => {
242
+ setProfileAnchorEl ( event . currentTarget ) ;
243
+ } ;
244
+ const handleProfileMenuClose = ( ) => {
245
+ setProfileAnchorEl ( null ) ;
195
246
} ;
196
247
197
248
return currentUser !== null ? (
@@ -203,12 +254,27 @@ const AdminIndexPage = () => {
203
254
< Typography variant = "h6" className = { classes . title } >
204
255
Admin
205
256
</ Typography >
257
+ < Typography variant = "h6" className = { classes . title } >
258
+ Profile:{ ' ' }
259
+ { currentProfile }
260
+ </ Typography >
206
261
< Box sx = { { flexGrow : 1 } } />
207
262
< Box sx = { { display : { xs : 'none' , md : 'flex' } } } >
208
263
< IconButton
209
264
size = "large"
210
265
color = "inherit"
211
- onClick = { ( ) => { setAddWidgetModalOpened ( true ) ; } }
266
+ edge = "end"
267
+ aria-controls = { profileMenuId }
268
+ aria-haspopup = "true"
269
+ aria-expanded = { isProfileMenuOpen ? 'true' : undefined }
270
+ onClick = { handleProfileMenuOpen }
271
+ >
272
+ < WidgetsIcon />
273
+ </ IconButton >
274
+ < IconButton
275
+ size = "large"
276
+ color = "inherit"
277
+ onClick = { ( ) => { setAddWidgetDialogOpened ( true ) ; } }
212
278
>
213
279
< AddIcon />
214
280
</ IconButton >
@@ -218,31 +284,51 @@ const AdminIndexPage = () => {
218
284
edge = "end"
219
285
aria-controls = { userMenuId }
220
286
aria-haspopup = "true"
287
+ aria-expanded = { isUserMenuOpen ? 'true' : undefined }
221
288
onClick = { handleUserMenuOpen }
222
289
>
223
290
< AccountCircleIcon />
224
291
</ IconButton >
225
292
</ Box >
226
293
</ Toolbar >
227
294
</ AppBar >
295
+ < Menu
296
+ id = { profileMenuId }
297
+ anchorEl = { profileAnchorEl }
298
+ open = { isProfileMenuOpen }
299
+ onClose = { handleProfileMenuClose }
300
+ >
301
+ { profiles . map ( ( profile ) => (
302
+ < MenuItem key = { profile } color = "inherit" onClick = { ( ) => { setCurrentProfile ( profile ) ; } } > { profile } </ MenuItem >
303
+ ) ) }
304
+ < Divider />
305
+ < MenuItem color = "inherit" onClick = { ( ) => { setAddProfileDialogOpened ( true ) ; } } > Add</ MenuItem >
306
+ </ Menu >
228
307
< Menu
229
308
id = { userMenuId }
230
- anchorEl = { anchorEl }
309
+ anchorEl = { userAnchorEl }
231
310
open = { isUserMenuOpen }
232
311
onClose = { handleUserMenuClose }
233
312
>
234
313
< MenuItem color = "inherit" onClick = { signout } > Logout</ MenuItem >
235
314
</ Menu >
236
- < AddWidgetModel
237
- open = { addWidgetModalOpened }
315
+ < AddProfileDialog
316
+ open = { addProfileDialogOpened }
317
+ onClose = { ( ) => {
318
+ setAddProfileDialogOpened ( false ) ;
319
+ } }
320
+ />
321
+ < AddWidgetDialog
322
+ profile = { currentProfile }
323
+ open = { addWidgetDialogOpened }
238
324
onClose = { ( ) => {
239
- setAddWidgetModalOpened ( false ) ;
325
+ setAddWidgetDialogOpened ( false ) ;
240
326
} }
241
327
/>
242
328
243
329
< Container className = { classes . content } >
244
330
< Box my = { 4 } >
245
- < Widgets />
331
+ < Widgets profile = { currentProfile } />
246
332
</ Box >
247
333
</ Container >
248
334
</ div >
0 commit comments