@@ -33,6 +33,11 @@ import DialogTitle from '@mui/material/DialogTitle';
3333import DialogContent from '@mui/material/DialogContent' ;
3434import DialogContentText from '@mui/material/DialogContentText' ;
3535import DialogActions from '@mui/material/DialogActions' ;
36+ import FormControlLabel from '@mui/material/FormControlLabel' ;
37+ import Checkbox from '@mui/material/Checkbox' ;
38+ import Divider from '@mui/material/Divider' ;
39+ import BlockIcon from '@mui/icons-material/Block' ;
40+ import HowToRegIcon from '@mui/icons-material/HowToReg' ;
3641
3742export default function UserManagement ( ) {
3843 const { auth } = useAuth ( ) ;
@@ -45,9 +50,14 @@ export default function UserManagement() {
4550 const [ savingId , setSavingId ] = useState ( null ) ;
4651 const [ deletingId , setDeletingId ] = useState ( null ) ;
4752
53+ // Signup toggle state
54+ const [ signupEnabled , setSignupEnabled ] = useState ( true ) ;
55+ const [ signupToggleLoading , setSignupToggleLoading ] = useState ( false ) ;
56+
4857 // Confirmation dialog state
4958 const [ confirmOpen , setConfirmOpen ] = useState ( false ) ;
5059 const [ userToDelete , setUserToDelete ] = useState ( null ) ;
60+ const [ deleteForumPosts , setDeleteForumPosts ] = useState ( false ) ;
5161
5262 const isAuthorized = auth ?. JWT && ( auth . roles === 'Admin' || auth . roles === 'Vorstand' ) ;
5363
@@ -80,6 +90,10 @@ export default function UserManagement() {
8090 return ;
8191 }
8292 fetchUsers ( ) ;
93+ // Fetch initial signup status
94+ api . get ( '/user/signup-status' )
95+ . then ( res => setSignupEnabled ( res . data . signupEnabled ) )
96+ . catch ( err => console . error ( 'Failed to fetch signup status' , err ) ) ;
8397 } , [ auth , navigate ] ) ;
8498
8599 const handleRoleChange = ( userId , newRole ) => {
@@ -135,34 +149,75 @@ export default function UserManagement() {
135149
136150 const handleDeleteClick = ( user ) => {
137151 setUserToDelete ( user ) ;
152+ setDeleteForumPosts ( false ) ;
138153 setConfirmOpen ( true ) ;
139154 } ;
140155
141156 const handleDeleteCancel = ( ) => {
142157 setConfirmOpen ( false ) ;
143158 setUserToDelete ( null ) ;
159+ setDeleteForumPosts ( false ) ;
144160 } ;
145161
146162 const handleDeleteConfirm = ( ) => {
147163 if ( ! userToDelete ) return ;
148164 const user = userToDelete ;
165+ const shouldDeletePosts = deleteForumPosts ;
149166 setConfirmOpen ( false ) ;
150167 setUserToDelete ( null ) ;
168+ setDeleteForumPosts ( false ) ;
151169 setDeletingId ( user . id ) ;
152170
153- api . delete ( `/user/${ user . id } ` )
154- . then ( ( ) => {
155- setUsers ( prev => prev . filter ( u => u . id !== user . id ) ) ;
156- alertsManagerRef . current . showAlert ( 'success' , `Benutzer ${ user . userName } erfolgreich gelöscht.` ) ;
171+ const doDelete = ( ) =>
172+ api . delete ( `/user/${ user . id } ` )
173+ . then ( ( ) => {
174+ setUsers ( prev => prev . filter ( u => u . id !== user . id ) ) ;
175+ alertsManagerRef . current . showAlert ( 'success' , `Benutzer ${ user . userName } erfolgreich gelöscht.` ) ;
176+ } )
177+ . catch ( err => {
178+ console . error ( 'Error deleting user' , err ) ;
179+ const msg = err . response ?. data || 'Fehler beim Löschen.' ;
180+ alertsManagerRef . current . showAlert ( 'error' , `Löschen fehlgeschlagen: ${ msg } ` ) ;
181+ } )
182+ . finally ( ( ) => {
183+ setDeletingId ( null ) ;
184+ } ) ;
185+
186+ if ( shouldDeletePosts ) {
187+ api . delete ( `/user/${ user . id } /posts` )
188+ . then ( ( ) => {
189+ alertsManagerRef . current . showAlert ( 'info' , `Forumsbeiträge von ${ user . userName } gelöscht.` ) ;
190+ } )
191+ . catch ( err => {
192+ console . error ( 'Error deleting posts' , err ) ;
193+ alertsManagerRef . current . showAlert ( 'error' , 'Forumsbeiträge konnten nicht gelöscht werden.' ) ;
194+ } )
195+ . finally ( ( ) => {
196+ doDelete ( ) ;
197+ } ) ;
198+ } else {
199+ doDelete ( ) ;
200+ }
201+ } ;
202+
203+ const handleSignupToggle = ( ) => {
204+ setSignupToggleLoading ( true ) ;
205+ const newValue = ! signupEnabled ;
206+ api . post ( `/user/signup-enabled?enabled=${ newValue } ` )
207+ . then ( res => {
208+ setSignupEnabled ( res . data . signupEnabled ) ;
209+ alertsManagerRef . current . showAlert (
210+ 'success' ,
211+ res . data . signupEnabled
212+ ? 'Registrierung wurde wieder aktiviert.'
213+ : 'Registrierung wurde deaktiviert.'
214+ ) ;
157215 } )
158216 . catch ( err => {
159- console . error ( "Error deleting user" , err ) ;
160- const msg = err . response ?. data || 'Fehler beim Löschen.' ;
161- alertsManagerRef . current . showAlert ( 'error' , `Löschen fehlgeschlagen: ${ msg } ` ) ;
217+ console . error ( 'Failed to toggle signup' , err ) ;
218+ alertsManagerRef . current . showAlert ( 'error' , 'Fehler beim Ändern der Registrierungseinstellung.' ) ;
162219 } )
163- . finally ( ( ) => {
164- setDeletingId ( null ) ;
165- } ) ;
220+ . finally ( ( ) => setSignupToggleLoading ( false ) ) ;
166221 } ;
167222
168223 const getUserEventsCurrentYear = ( userName ) => {
@@ -214,6 +269,46 @@ export default function UserManagement() {
214269 </ Button >
215270 </ Stack >
216271
272+ { /* Signup Toggle Card */ }
273+ < Card sx = { { mb : 3 , border : '1px solid rgba(255, 255, 255, 0.08)' , bgcolor : 'background.paper' , borderRadius : 2 } } >
274+ < CardContent sx = { { display : 'flex' , alignItems : 'center' , justifyContent : 'space-between' , py : 2 , '&:last-child' : { pb : 2 } } } >
275+ < Box sx = { { display : 'flex' , alignItems : 'center' , gap : 2 } } >
276+ { signupEnabled
277+ ? < HowToRegIcon sx = { { color : 'success.main' , fontSize : 28 , flexShrink : 0 } } />
278+ : < BlockIcon sx = { { color : 'error.main' , fontSize : 28 , flexShrink : 0 } } /> }
279+ < Box >
280+ < Typography variant = "subtitle1" sx = { { fontWeight : 'bold' , lineHeight : 1.3 } } >
281+ Registrierung neuer Benutzer
282+ </ Typography >
283+ < Typography variant = "body2" color = "text.secondary" >
284+ { signupEnabled
285+ ? 'Neue Benutzer können sich derzeit registrieren.'
286+ : 'Die Registrierung ist derzeit deaktiviert.' }
287+ </ Typography >
288+ </ Box >
289+ </ Box >
290+ < Box sx = { { display : 'flex' , alignItems : 'center' , gap : 2 } } >
291+ < Chip
292+ label = { signupEnabled ? 'Aktiv' : 'Deaktiviert' }
293+ color = { signupEnabled ? 'success' : 'error' }
294+ variant = "outlined"
295+ size = "small"
296+ />
297+ < Tooltip title = { signupEnabled ? 'Registrierung deaktivieren' : 'Registrierung aktivieren' } >
298+ < span style = { { display : 'flex' , alignItems : 'center' } } >
299+ < Switch
300+ checked = { signupEnabled }
301+ onChange = { handleSignupToggle }
302+ disabled = { signupToggleLoading }
303+ color = { signupEnabled ? 'success' : 'error' }
304+ id = "signup-toggle"
305+ />
306+ </ span >
307+ </ Tooltip >
308+ </ Box >
309+ </ CardContent >
310+ </ Card >
311+
217312 < Card sx = { { border : '1px solid rgba(255, 255, 255, 0.08)' , bgcolor : 'background.paper' , borderRadius : 2 } } >
218313 < CardContent sx = { { p : 0 } } >
219314 { loading ? (
@@ -349,7 +444,7 @@ export default function UserManagement() {
349444 bgcolor : 'background.paper' ,
350445 border : '1px solid rgba(255,255,255,0.1)' ,
351446 borderRadius : 2 ,
352- minWidth : 360 ,
447+ minWidth : 400 ,
353448 }
354449 }
355450 } }
@@ -358,13 +453,34 @@ export default function UserManagement() {
358453 Benutzer löschen
359454 </ DialogTitle >
360455 < DialogContent >
361- < DialogContentText sx = { { color : 'text.secondary' } } >
456+ < DialogContentText sx = { { color : 'text.secondary' , mb : 2 } } >
362457 Bist du sicher, dass du den Benutzer{ ' ' }
363458 < Box component = "span" sx = { { fontWeight : 'bold' , color : 'text.primary' } } >
364459 { userToDelete ?. userName }
365460 </ Box > { ' ' }
366461 unwiderruflich löschen möchtest? Alle zugehörigen Daten werden entfernt.
367462 </ DialogContentText >
463+ < Divider sx = { { mb : 2 , borderColor : 'rgba(255,255,255,0.08)' } } />
464+ < FormControlLabel
465+ control = {
466+ < Checkbox
467+ checked = { deleteForumPosts }
468+ onChange = { e => setDeleteForumPosts ( e . target . checked ) }
469+ color = "error"
470+ id = "delete-forum-posts-checkbox"
471+ />
472+ }
473+ label = {
474+ < Box >
475+ < Typography variant = "body2" sx = { { fontWeight : 'bold' , color : deleteForumPosts ? 'error.main' : 'text.primary' } } >
476+ Alle Forumsbeiträge löschen
477+ </ Typography >
478+ < Typography variant = "caption" color = "text.secondary" >
479+ Entfernt sämtliche Posts dieses Benutzers im Forum (z.B. bei Spam-Accounts).
480+ </ Typography >
481+ </ Box >
482+ }
483+ />
368484 </ DialogContent >
369485 < DialogActions sx = { { px : 3 , pb : 2 , gap : 1 } } >
370486 < Button onClick = { handleDeleteCancel } variant = "outlined" color = "inherit" >
@@ -377,7 +493,7 @@ export default function UserManagement() {
377493 startIcon = { < DeleteIcon /> }
378494 autoFocus
379495 >
380- Endgültig löschen
496+ { deleteForumPosts ? 'Posts + Account löschen' : ' Endgültig löschen' }
381497 </ Button >
382498 </ DialogActions >
383499 </ Dialog >
0 commit comments