@@ -12,11 +12,13 @@ import {
1212 Course ,
1313 LocaleType ,
1414 LogoutParticipantDocument ,
15+ LogoutTemporaryParticipantDocument ,
1516 Participant ,
17+ SelfDocument ,
1618 StudentCourse ,
1719 UserRole ,
1820} from '@klicker-uzh/graphql/dist/ops'
19- import { Button , Dropdown , H1 , H2 } from '@uzh-bf/design-system'
21+ import { Button , Dropdown , H1 , H2 , toast } from '@uzh-bf/design-system'
2022import { useTranslations } from 'next-intl'
2123import Image from 'next/image'
2224import Link from 'next/link'
@@ -31,14 +33,14 @@ interface HeaderProps {
3133 course ?:
3234 | Partial < Course >
3335 | ( Omit < StudentCourse , 'owner' > & { owner : { shortname : string } } )
34- previewMode ?: boolean
36+ liveQuizId ?: string
3537}
3638
3739function Header ( {
3840 participant,
3941 title,
4042 course,
41- previewMode = false ,
43+ liveQuizId ,
4244} : HeaderProps ) : React . ReactElement {
4345 const router = useRouter ( )
4446 const { pathname, asPath, query } = router
@@ -50,6 +52,8 @@ function Header({
5052 const [ logoutParticipant , { loading : loggingOut } ] = useMutation (
5153 LogoutParticipantDocument
5254 )
55+ const [ logoutTemporaryParticipant , { loading : loggingOutTemporary } ] =
56+ useMutation ( LogoutTemporaryParticipantDocument )
5357
5458 const pageInFrame =
5559 global ?. window &&
@@ -144,6 +148,28 @@ function Header({
144148 </ div >
145149 }
146150 items = { [
151+ ...( participant
152+ ? [
153+ {
154+ id : 'loggedInAs' ,
155+ type : 'label' as 'label' ,
156+ label : (
157+ < div className = "" >
158+ < div > { t ( 'pwa.profile.loggedInAs' ) } </ div >
159+ < div className = "font-normal" >
160+ { `${ participant ?. username } ${ participant . role === UserRole . TemporaryParticipant ? ` (${ t ( 'pwa.profile.temporaryPseudonym' ) } )` : '' } ` }
161+ </ div >
162+ </ div >
163+ ) ,
164+ className : { item : '!h-max py-0.5' } ,
165+ } ,
166+ {
167+ id : 'separator' ,
168+ type : 'separator' as 'separator' ,
169+ className : { item : '!h-1.5' } ,
170+ } ,
171+ ]
172+ : [ ] ) ,
147173 ...( showProfileSetup
148174 ? [
149175 {
@@ -284,7 +310,60 @@ function Header({
284310 } ,
285311 ]
286312 : [ ] ) ,
287- // TODO: add functionality to log out of temporary account and delete corresponding temporary leaderboard entry
313+ ...( participant ?. role === UserRole . TemporaryParticipant &&
314+ liveQuizId
315+ ? [
316+ {
317+ id : 'logout' ,
318+ type : 'standard' as 'standard' ,
319+ disabled : loggingOutTemporary ,
320+ label : (
321+ < div className = "text-red-500" >
322+ < FontAwesomeIcon
323+ icon = { faRightFromBracket }
324+ className = "mr-2 w-4"
325+ />
326+ < span > { t ( 'shared.generic.logout' ) } </ span >
327+ </ div >
328+ ) ,
329+ onClick : async ( ) => {
330+ try {
331+ // log out temporary participant for this live quiz
332+ const { data } = await logoutTemporaryParticipant ( {
333+ variables : { liveQuizId } ,
334+ refetchQueries : [ { query : SelfDocument } ] ,
335+ } )
336+
337+ if ( data ?. logoutTemporaryParticipant ) {
338+ // remove local storage entry for temporary participant
339+ localStorage . removeItem ( `login-state-${ liveQuizId } ` )
340+
341+ router . reload ( )
342+ } else {
343+ toast ( {
344+ type : 'error' ,
345+ message : t (
346+ 'pwa.profile.errorLogoutTemporaryParticipant'
347+ ) ,
348+ } )
349+ }
350+ } catch ( e ) {
351+ console . error (
352+ 'Error logging out temporary participant:' ,
353+ e
354+ )
355+ toast ( {
356+ type : 'error' ,
357+ message : t (
358+ 'pwa.profile.errorLogoutTemporaryParticipant'
359+ ) ,
360+ } )
361+ }
362+ } ,
363+ data : { cy : 'logout' } ,
364+ } ,
365+ ]
366+ : [ ] ) ,
288367 ] }
289368 className = { { item : 'h-8 text-sm md:h-8 md:text-base' } }
290369 data = { { cy : 'header-avatar' } }
0 commit comments