@@ -15,6 +15,7 @@ import TextField from '@mui/material/TextField';
1515import LoginIcon from '@mui/icons-material/Login' ;
1616import CloseIcon from '@mui/icons-material/Close' ;
1717import IconButton from '@mui/material/IconButton' ;
18+ import MarkEmailUnreadIcon from '@mui/icons-material/MarkEmailUnread' ;
1819
1920// Auth & OIDC
2021import useAuth from '../../context/useAuth' ;
@@ -72,6 +73,10 @@ const SignIn = React.forwardRef((props, ref) => {
7273
7374 const [ usernameOrEmail , setUsernameOrEmail ] = useState ( '' ) ;
7475 const [ password , setPassword ] = useState ( '' ) ;
76+ const [ canResendVerification , setCanResendVerification ] = useState ( false ) ;
77+ const [ resendingVerification , setResendingVerification ] = useState ( false ) ;
78+ const [ resendMessage , setResendMessage ] = useState ( '' ) ;
79+ const [ resendError , setResendError ] = useState ( '' ) ;
7580
7681 const from = location . state ?. from ?. pathname || "/" ;
7782 const [ blockedByAdmin , setBlockedByAdmin ] = useState ( false ) ;
@@ -163,6 +168,9 @@ const SignIn = React.forwardRef((props, ref) => {
163168 }
164169
165170 dispatch ( { type : 'LOGIN_START' } ) ;
171+ setCanResendVerification ( false ) ;
172+ setResendMessage ( '' ) ;
173+ setResendError ( '' ) ;
166174 try {
167175 const response = await api . post ( '/user/login' , {
168176 userName : usernameOrEmail ,
@@ -188,10 +196,41 @@ const SignIn = React.forwardRef((props, ref) => {
188196 } catch ( err ) {
189197 console . error ( "Local login failed" , err ) ;
190198 const errorMsg = extractErrorMessage ( err ) ;
199+ setCanResendVerification ( err ?. response ?. data ?. code === 'ACCOUNT_NOT_VERIFIED' ) ;
191200 dispatch ( { type : 'LOGIN_ERROR' , payload : errorMsg } ) ;
192201 }
193202 } ;
194203
204+ const handleResendVerification = async ( ) => {
205+ setResendingVerification ( true ) ;
206+ setResendMessage ( '' ) ;
207+ setResendError ( '' ) ;
208+ try {
209+ const response = await api . post ( '/user/resend-verification' , {
210+ userName : usernameOrEmail ,
211+ password
212+ } ) ;
213+ setResendMessage ( response . data ?. message || 'Ein neuer Verifizierungscode wurde gesendet.' ) ;
214+ } catch ( err ) {
215+ console . error ( 'Resending verification code failed' , err ) ;
216+ setResendError ( extractErrorMessage ( err ) ) ;
217+ if ( err ?. response ?. status === 401 ) {
218+ setCanResendVerification ( false ) ;
219+ }
220+ } finally {
221+ setResendingVerification ( false ) ;
222+ }
223+ } ;
224+
225+ const openVerificationPage = ( ) => {
226+ if ( props . callback ) {
227+ props . callback ( ) ;
228+ }
229+ navigate ( '/Regestrieren/Erfolgreich' , {
230+ state : { email : usernameOrEmail . includes ( '@' ) ? usernameOrEmail . trim ( ) : '' }
231+ } ) ;
232+ } ;
233+
195234 const cardContentInner = (
196235 < Box sx = { { display : 'flex' , flexDirection : 'column' , alignItems : 'center' , py : 2 } } >
197236 < Typography variant = "h5" component = "h1" gutterBottom sx = { { fontWeight : 'bold' , fontFamily : 'Outfit' } } >
@@ -214,7 +253,11 @@ const SignIn = React.forwardRef((props, ref) => {
214253 fullWidth
215254 label = "Benutzername oder E-Mail"
216255 value = { usernameOrEmail }
217- onChange = { ( e ) => setUsernameOrEmail ( e . target . value ) }
256+ onChange = { ( e ) => {
257+ setUsernameOrEmail ( e . target . value ) ;
258+ setCanResendVerification ( false ) ;
259+ setResendMessage ( '' ) ;
260+ } }
218261 autoComplete = "username"
219262 autoFocus
220263 />
@@ -226,7 +269,11 @@ const SignIn = React.forwardRef((props, ref) => {
226269 label = "Passwort"
227270 type = "password"
228271 value = { password }
229- onChange = { ( e ) => setPassword ( e . target . value ) }
272+ onChange = { ( e ) => {
273+ setPassword ( e . target . value ) ;
274+ setCanResendVerification ( false ) ;
275+ setResendMessage ( '' ) ;
276+ } }
230277 autoComplete = "current-password"
231278 />
232279 < Box sx = { { display : 'flex' , justifyContent : 'flex-end' , mt : 0.5 } } >
@@ -294,6 +341,36 @@ const SignIn = React.forwardRef((props, ref) => {
294341 { error }
295342 </ Alert >
296343 ) }
344+
345+ { canResendVerification && (
346+ < Box sx = { { width : '100%' , mt : 2 } } >
347+ < Button
348+ variant = "outlined"
349+ color = "primary"
350+ fullWidth
351+ startIcon = { resendingVerification ? < CircularProgress size = { 18 } color = "inherit" /> : < MarkEmailUnreadIcon /> }
352+ onClick = { handleResendVerification }
353+ disabled = { resendingVerification }
354+ >
355+ { resendingVerification ? 'Code wird gesendet...' : 'Verifizierungscode erneut senden' }
356+ </ Button >
357+ </ Box >
358+ ) }
359+
360+ { resendMessage && (
361+ < Alert severity = "success" sx = { { width : '100%' , mt : 2 } } >
362+ { resendMessage }
363+ < Button color = "inherit" size = "small" onClick = { openVerificationPage } sx = { { ml : 1 } } >
364+ Code eingeben
365+ </ Button >
366+ </ Alert >
367+ ) }
368+
369+ { resendError && (
370+ < Alert severity = "error" sx = { { width : '100%' , mt : 2 } } >
371+ { resendError }
372+ </ Alert >
373+ ) }
297374 </ Box >
298375 ) ;
299376
0 commit comments