✨(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:
@@ -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}' },
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
1
src/frontend/src/features/settings/index.ts
Normal file
1
src/frontend/src/features/settings/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { SettingsButton } from './components/SettingsButton'
|
||||
@@ -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"
|
||||
|
||||
@@ -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],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
15
src/frontend/src/locales/de/settings.json
Normal file
15
src/frontend/src/locales/de/settings.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"account": {
|
||||
"currentlyLoggedAs": "",
|
||||
"heading": "",
|
||||
"youAreNotLoggedIn": ""
|
||||
},
|
||||
"dialog": {
|
||||
"heading": ""
|
||||
},
|
||||
"language": {
|
||||
"heading": "",
|
||||
"label": ""
|
||||
},
|
||||
"settingsButtonLabel": ""
|
||||
}
|
||||
15
src/frontend/src/locales/en/settings.json
Normal file
15
src/frontend/src/locales/en/settings.json
Normal 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"
|
||||
}
|
||||
15
src/frontend/src/locales/fr/settings.json
Normal file
15
src/frontend/src/locales/fr/settings.json
Normal 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"
|
||||
}
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user