(frontend) new settings dialog to handle user account/language

add a settings button directly in the homepage to change language or see
user account settings
This commit is contained in:
Emmanuel Pelletier
2024-07-24 16:51:35 +02:00
parent 0707ac2cd4
commit 41ad15e20b
11 changed files with 139 additions and 6 deletions

View File

@@ -231,7 +231,7 @@ const config: Config = {
DEFAULT: { value: '{spacing.1}' },
lg: { value: '{spacing.2}' },
},
paragraph: { value: '{spacing.1}' },
paragraph: { value: '{spacing.0.5}' },
heading: { value: '{spacing.1}' },
gutter: { value: '{spacing.1}' },
textfield: { value: '{spacing.1}' },

View File

@@ -5,6 +5,7 @@ import { authUrl, useUser } from '@/features/auth'
import { navigateToNewRoom } from '@/features/rooms'
import { Screen } from '@/layout/Screen'
import { JoinMeetingDialogContent } from '../components/JoinMeetingDialogContent'
import { SettingsButton } from '@/features/settings'
export const Home = () => {
const { t } = useTranslation('home')
@@ -39,6 +40,8 @@ export const Home = () => {
</Button>
<JoinMeetingDialogContent />
</Dialog>
<SettingsButton />
</HStack>
</Div>
</VerticallyOffCenter>

View File

@@ -0,0 +1,16 @@
import { useTranslation } from 'react-i18next'
import { RiSettings3Line } from '@remixicon/react'
import { Dialog, Button } from '@/primitives'
import { SettingsDialog } from './SettingsDialog'
export const SettingsButton = () => {
const { t } = useTranslation('settings')
return (
<Dialog>
<Button square invisible aria-label={t('settingsButtonLabel')}>
<RiSettings3Line />
</Button>
<SettingsDialog />
</Dialog>
)
}

View File

@@ -0,0 +1,46 @@
import { Trans, useTranslation } from 'react-i18next'
import { useLanguageLabels } from '@/i18n/useLanguageLabels'
import { A, Badge, DialogContent, Field, H, P } from '@/primitives'
import { authUrl, logoutUrl, useUser } from '@/features/auth'
export const SettingsDialog = () => {
const { t, i18n } = useTranslation('settings')
const { user, isLoggedIn } = useUser()
const { languagesList, currentLanguage } = useLanguageLabels()
return (
<DialogContent title={t('dialog.heading')}>
<H lvl={2}>{t('account.heading')}</H>
{isLoggedIn ? (
<>
<P>
<Trans
i18nKey="settings:account.currentlyLoggedAs"
values={{ user: user?.email }}
components={[<Badge />]}
/>
</P>
<P>
<A href={logoutUrl()}>{t('logout', { ns: 'global' })}</A>
</P>
</>
) : (
<>
<P>{t('account.youAreNotLoggedIn')}</P>
<P>
<A href={authUrl()}>{t('login', { ns: 'global' })}</A>
</P>
</>
)}
<H lvl={2}>{t('language.heading')}</H>
<Field
type="select"
label={t('language.label')}
items={languagesList}
defaultSelectedKey={currentLanguage.key}
onSelectionChange={(lang) => {
i18n.changeLanguage(lang as string)
}}
/>
</DialogContent>
)
}

View File

@@ -0,0 +1 @@
export { SettingsButton } from './components/SettingsButton'

View File

@@ -9,7 +9,7 @@ export const LanguageSelector = () => {
<Popover aria-label={t('languageSelector.popoverLabel')}>
<Button
aria-label={t('languageSelector.buttonLabel', {
currentLanguage,
currentLanguage: currentLanguage.label,
})}
size="sm"
variant="primary"

View File

@@ -16,5 +16,11 @@ export const useLanguageLabels = () => {
value: lang,
label: langageLabels[lang],
}))
return { languagesList, currentLanguage: langageLabels[i18n.language] }
return {
languagesList,
currentLanguage: {
key: i18n.language,
label: langageLabels[i18n.language],
},
}
}

View File

@@ -0,0 +1,15 @@
{
"account": {
"currentlyLoggedAs": "",
"heading": "",
"youAreNotLoggedIn": ""
},
"dialog": {
"heading": ""
},
"language": {
"heading": "",
"label": ""
},
"settingsButtonLabel": ""
}

View File

@@ -0,0 +1,15 @@
{
"account": {
"currentlyLoggedAs": "You are currently logged in as <0>{{user}}</0>",
"heading": "Account",
"youAreNotLoggedIn": "You are not logged in."
},
"dialog": {
"heading": "Account and settings"
},
"language": {
"heading": "Language",
"label": "Language"
},
"settingsButtonLabel": "Settings"
}

View File

@@ -0,0 +1,15 @@
{
"account": {
"currentlyLoggedAs": "Vous êtes actuellement connecté en tant que <0>{{user}}</0>",
"heading": "Compte",
"youAreNotLoggedIn": "Vous n'êtes pas connecté."
},
"dialog": {
"heading": "Compte et paramètres"
},
"language": {
"heading": "Langue",
"label": "Langue de l'application"
},
"settingsButtonLabel": "Paramètres"
}

View File

@@ -9,7 +9,7 @@ import { cva, type RecipeVariantProps } from '@/styled-system/css'
const button = cva({
base: {
display: 'inline-block',
transition: 'background 200ms, outline 200ms',
transition: 'background 200ms, outline 200ms, border-color 200ms',
cursor: 'pointer',
border: '1px solid transparent',
color: 'colorPalette.text',
@@ -27,14 +27,23 @@ const button = cva({
borderRadius: 8,
paddingX: '1',
paddingY: '0.625',
'--square-padding': '{spacing.0.625}',
},
sm: {
borderRadius: 4,
paddingX: '0.5',
paddingY: '0.25',
'--square-padding': '{spacing.0.25}',
},
xs: {
borderRadius: 4,
'--square-padding': '0',
},
},
square: {
true: {
paddingX: 'var(--square-padding)',
paddingY: 'var(--square-padding)',
},
},
variant: {
@@ -50,10 +59,10 @@ const button = cva({
color: 'colorPalette',
backgroundColor: 'transparent!',
borderColor: 'currentcolor!',
'_ra-hover': {
'&[data-hovered]': {
backgroundColor: 'colorPalette.subtle!',
},
'_ra-pressed': {
'&[data-pressed]': {
backgroundColor: 'colorPalette.subtle!',
},
},
@@ -62,6 +71,13 @@ const button = cva({
true: {
borderColor: 'none!',
backgroundColor: 'none!',
'&[data-hovered]': {
backgroundColor: 'none!',
borderColor: 'currentcolor',
},
'&[data-pressed]': {
borderColor: 'currentcolor',
},
},
},
},