🚸(frontend) add login hint for unauthenticated users in lobby
Add informational message suggesting authentication for users waiting in lobby without being logged in. Highlight that logging in could grant immediate access without admin approval when rooms have trusted access level enabled.
This commit is contained in:
committed by
aleb_the_flash
parent
00cd4fc92a
commit
aaf1163910
@@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import { usePreviewTracks } from '@livekit/components-react'
|
||||
import { css } from '@/styled-system/css'
|
||||
import { Screen } from '@/layout/Screen'
|
||||
import { useMemo, useEffect, useRef, useState, useCallback } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { LocalVideoTrack, Track } from 'livekit-client'
|
||||
import { H } from '@/primitives/H'
|
||||
import { SelectToggleDevice } from '../livekit/components/controls/SelectToggleDevice'
|
||||
@@ -26,6 +26,8 @@ import { useQuery } from '@tanstack/react-query'
|
||||
import { queryClient } from '@/api/queryClient'
|
||||
import { ApiLobbyStatus, ApiRequestEntry } from '../api/requestEntry'
|
||||
import { Spinner } from '@/primitives/Spinner'
|
||||
import { ApiAccessLevel } from '../api/ApiRoom'
|
||||
import { useLoginHint } from '@/hooks/useLoginHint'
|
||||
|
||||
const onError = (e: Error) => console.error('ERROR', e)
|
||||
|
||||
@@ -264,10 +266,16 @@ export const Join = ({
|
||||
onAccepted: handleAccepted,
|
||||
})
|
||||
|
||||
const { openLoginHint } = useLoginHint()
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const { data } = await refetchRoom()
|
||||
|
||||
if (!data?.livekit) {
|
||||
// Display a message to inform the user that by logging in, they won't have to wait for room entry approval.
|
||||
if (data?.access_level == ApiAccessLevel.TRUSTED) {
|
||||
openLoginHint()
|
||||
}
|
||||
startWaiting()
|
||||
return
|
||||
}
|
||||
|
||||
22
src/frontend/src/hooks/useLoginHint.ts
Normal file
22
src/frontend/src/hooks/useLoginHint.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { useSnapshot } from 'valtio'
|
||||
import { hintsStore } from '@/stores/hints'
|
||||
import { useUser } from '@/features/auth'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
export const useLoginHint = () => {
|
||||
const hintsSnap = useSnapshot(hintsStore)
|
||||
const { isLoggedIn } = useUser()
|
||||
|
||||
const openLoginHint = () => (hintsStore.showLoginHint = true)
|
||||
const closeLoginHint = () => (hintsStore.showLoginHint = false)
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoggedIn && hintsSnap.showLoginHint) closeLoginHint()
|
||||
}, [isLoggedIn, hintsSnap])
|
||||
|
||||
return {
|
||||
isVisible: hintsSnap.showLoginHint,
|
||||
openLoginHint,
|
||||
closeLoginHint,
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import { Link } from 'wouter'
|
||||
import { css } from '@/styled-system/css'
|
||||
import { HStack, Stack } from '@/styled-system/jsx'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Button } from '@/primitives'
|
||||
import { Button, Text } from '@/primitives'
|
||||
import { SettingsButton } from '@/features/settings'
|
||||
import { useUser } from '@/features/auth'
|
||||
import { useMatchesRoute } from '@/navigation/useMatchesRoute'
|
||||
@@ -12,6 +12,7 @@ import { MenuList } from '@/primitives/MenuList'
|
||||
import { ProConnectButton } from '@/components/ProConnectButton'
|
||||
|
||||
import LogoAsset from '@/assets/logo.svg'
|
||||
import { useLoginHint } from '@/hooks/useLoginHint'
|
||||
|
||||
const Marianne = () => {
|
||||
return (
|
||||
@@ -91,6 +92,64 @@ const Logo = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const LoginHint = () => {
|
||||
const { t } = useTranslation()
|
||||
const { isVisible, closeLoginHint } = useLoginHint()
|
||||
if (!isVisible) return null
|
||||
return (
|
||||
<div
|
||||
className={css({
|
||||
position: 'absolute',
|
||||
top: '103px',
|
||||
right: '110px',
|
||||
zIndex: '100',
|
||||
outline: 'none',
|
||||
padding: '1.25rem',
|
||||
maxWidth: '350px',
|
||||
boxShadow: '0 2px 5px rgba(0 0 0 / 0.1)',
|
||||
borderRadius: '1rem',
|
||||
backgroundColor: 'primary.200',
|
||||
display: 'none',
|
||||
xsm: {
|
||||
display: 'block',
|
||||
},
|
||||
sm: {
|
||||
top: '131px',
|
||||
right: '100px',
|
||||
zIndex: '100',
|
||||
},
|
||||
_after: {
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: '-10px',
|
||||
right: '20%',
|
||||
marginLeft: '-10px',
|
||||
borderWidth: '0 10px 10px 10px',
|
||||
borderStyle: 'solid',
|
||||
borderColor: 'transparent transparent #E3E3FB transparent',
|
||||
},
|
||||
})}
|
||||
>
|
||||
<Text variant="h3" margin={false} bold>
|
||||
{t('loginHint.title')}
|
||||
</Text>
|
||||
<Text variant="paragraph" margin={false}>
|
||||
{t('loginHint.body')}
|
||||
</Text>
|
||||
<Button
|
||||
aria-label={t('loginHint.button.ariaLabel')}
|
||||
size="sm"
|
||||
className={css({
|
||||
marginLeft: 'auto',
|
||||
})}
|
||||
onPress={() => closeLoginHint()}
|
||||
>
|
||||
{t('loginHint.button.label')}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const Header = () => {
|
||||
const { t } = useTranslation()
|
||||
const isHome = useMatchesRoute('home')
|
||||
@@ -144,7 +203,10 @@ export const Header = () => {
|
||||
<nav>
|
||||
<Stack gap={1} direction="row" align="center">
|
||||
{isLoggedIn === false && !isHome && (
|
||||
<ProConnectButton hint={false} />
|
||||
<>
|
||||
<ProConnectButton hint={false} />
|
||||
<LoginHint />
|
||||
</>
|
||||
)}
|
||||
{!!user && (
|
||||
<Menu>
|
||||
|
||||
@@ -41,5 +41,13 @@
|
||||
},
|
||||
"mentions": "",
|
||||
"license": ""
|
||||
},
|
||||
"loginHint": {
|
||||
"title": "",
|
||||
"body": "",
|
||||
"button": {
|
||||
"ariaLabel": "",
|
||||
"label": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,5 +41,13 @@
|
||||
},
|
||||
"mentions": "Unless otherwise stated, the contents of this site are available under",
|
||||
"license": "etalab 2.0 license"
|
||||
},
|
||||
"loginHint": {
|
||||
"title": "Log in with your ProConnect account",
|
||||
"body": "Instead of waiting, log in with your ProConnect account.",
|
||||
"button": {
|
||||
"ariaLabel": "Close the suggestion",
|
||||
"label": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,5 +41,13 @@
|
||||
},
|
||||
"mentions": "Sauf mention contraire, les contenus de ce site sont disponibles sous",
|
||||
"license": "licence etalab 2.0"
|
||||
},
|
||||
"loginHint": {
|
||||
"title": "Connectez-vous avec votre compte ProConnect",
|
||||
"body": "Au lieu de patienter, connectez-vous avec votre compte ProConnect.",
|
||||
"button": {
|
||||
"ariaLabel": "Fermer la suggestion",
|
||||
"label": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
src/frontend/src/stores/hints.ts
Normal file
9
src/frontend/src/stores/hints.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { proxy } from 'valtio'
|
||||
|
||||
type State = {
|
||||
showLoginHint: boolean
|
||||
}
|
||||
|
||||
export const hintsStore = proxy<State>({
|
||||
showLoginHint: false,
|
||||
})
|
||||
Reference in New Issue
Block a user