🚸(frontend) follow antoine's remarks on homepage and header
- show the header on homepage. Not sure we want any header on this app actually but I guess he's right since we have one it feels more consistent to have it everywhere - show logged in email in header. ditched it because i didn't quite get the value of showing it all the time in this app but i guess it's better than nothing - remove user info from settings. Since they are back in the header, no need
This commit is contained in:
@@ -181,6 +181,7 @@ const config: Config = {
|
|||||||
active: { value: '{colors.gray.300}' },
|
active: { value: '{colors.gray.300}' },
|
||||||
text: { value: '{colors.default.text}' },
|
text: { value: '{colors.default.text}' },
|
||||||
border: { value: '{colors.gray.500}' },
|
border: { value: '{colors.gray.500}' },
|
||||||
|
subtle: { value: '{colors.gray.400}' },
|
||||||
},
|
},
|
||||||
primary: {
|
primary: {
|
||||||
DEFAULT: { value: '{colors.blue.700}' },
|
DEFAULT: { value: '{colors.blue.700}' },
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { Button, Div, Text, VerticallyOffCenter } from '@/primitives'
|
|||||||
import { HStack } from '@/styled-system/jsx'
|
import { HStack } from '@/styled-system/jsx'
|
||||||
import { authUrl, useUser } from '@/features/auth'
|
import { authUrl, useUser } from '@/features/auth'
|
||||||
import { navigateToNewRoom } from '@/features/rooms'
|
import { navigateToNewRoom } from '@/features/rooms'
|
||||||
import { SettingsButton } from '@/features/settings'
|
|
||||||
import { Screen } from '@/layout/Screen'
|
import { Screen } from '@/layout/Screen'
|
||||||
import { JoinMeetingDialog } from '../components/JoinMeetingDialog'
|
import { JoinMeetingDialog } from '../components/JoinMeetingDialog'
|
||||||
|
|
||||||
@@ -12,7 +11,7 @@ export const Home = () => {
|
|||||||
const { t } = useTranslation('home')
|
const { t } = useTranslation('home')
|
||||||
const { isLoggedIn } = useUser()
|
const { isLoggedIn } = useUser()
|
||||||
return (
|
return (
|
||||||
<Screen type="splash">
|
<Screen>
|
||||||
<VerticallyOffCenter>
|
<VerticallyOffCenter>
|
||||||
<Div margin="auto" width="fit-content">
|
<Div margin="auto" width="fit-content">
|
||||||
<Text as="h1" variant="display">
|
<Text as="h1" variant="display">
|
||||||
@@ -41,8 +40,6 @@ export const Home = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
<JoinMeetingDialog />
|
<JoinMeetingDialog />
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
||||||
<SettingsButton />
|
|
||||||
</HStack>
|
</HStack>
|
||||||
</Div>
|
</Div>
|
||||||
</VerticallyOffCenter>
|
</VerticallyOffCenter>
|
||||||
|
|||||||
@@ -11,7 +11,14 @@ export const Join = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box title={t('join.heading')} withBackButton>
|
<Box title={t('join.heading')} withBackButton>
|
||||||
<PreJoin persistUserChoices onSubmit={onSubmit} />
|
<PreJoin
|
||||||
|
persistUserChoices
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
micLabel={t('join.micLabel')}
|
||||||
|
camLabel={t('join.camlabel')}
|
||||||
|
joinLabel={t('join.joinLabel')}
|
||||||
|
userLabel={t('join.userLabel')}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1,12 @@
|
|||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useLanguageLabels } from '@/i18n/useLanguageLabels'
|
import { useLanguageLabels } from '@/i18n/useLanguageLabels'
|
||||||
import { A, Badge, Dialog, Field, H, P } from '@/primitives'
|
import { Dialog, Field, H } from '@/primitives'
|
||||||
import { authUrl, logoutUrl, useUser } from '@/features/auth'
|
|
||||||
|
|
||||||
export const SettingsDialog = () => {
|
export const SettingsDialog = () => {
|
||||||
const { t, i18n } = useTranslation('settings')
|
const { t, i18n } = useTranslation('settings')
|
||||||
const { user, isLoggedIn } = useUser()
|
|
||||||
const { languagesList, currentLanguage } = useLanguageLabels()
|
const { languagesList, currentLanguage } = useLanguageLabels()
|
||||||
return (
|
return (
|
||||||
<Dialog title={t('dialog.heading')}>
|
<Dialog 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>
|
<H lvl={2}>{t('language.heading')}</H>
|
||||||
<Field
|
<Field
|
||||||
type="select"
|
type="select"
|
||||||
|
|||||||
@@ -2,20 +2,23 @@ import { Link } from 'wouter'
|
|||||||
import { css } from '@/styled-system/css'
|
import { css } from '@/styled-system/css'
|
||||||
import { Stack } from '@/styled-system/jsx'
|
import { Stack } from '@/styled-system/jsx'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Text } from '@/primitives'
|
import { A, Button, Popover, PopoverList, Text } from '@/primitives'
|
||||||
import { SettingsButton } from '@/features/settings'
|
import { SettingsButton } from '@/features/settings'
|
||||||
|
import { authUrl, logoutUrl, useUser } from '@/features/auth'
|
||||||
|
|
||||||
export const Header = () => {
|
export const Header = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
const isHome = window.location.pathname === '/'
|
||||||
|
const { user, isLoggedIn } = useUser()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={css({
|
className={css({
|
||||||
backgroundColor: 'primary.text',
|
|
||||||
color: 'primary',
|
|
||||||
borderBottomColor: 'box.border',
|
borderBottomColor: 'box.border',
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
borderBottomStyle: 'solid',
|
borderBottomStyle: 'solid',
|
||||||
padding: 1,
|
paddingY: 1,
|
||||||
|
paddingX: 1,
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
@@ -26,7 +29,32 @@ export const Header = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
</header>
|
</header>
|
||||||
<nav>
|
<nav>
|
||||||
<SettingsButton />
|
<Stack gap={1} direction="row" align="center">
|
||||||
|
{isLoggedIn === false && !isHome && (
|
||||||
|
<A href={authUrl()}>{t('login')}</A>
|
||||||
|
)}
|
||||||
|
{!!user && (
|
||||||
|
<Popover aria-label={t('logout')}>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
invisible
|
||||||
|
tooltip={t('loggedInUserTooltip')}
|
||||||
|
tooltipType="delayed"
|
||||||
|
>
|
||||||
|
{user.email}
|
||||||
|
</Button>
|
||||||
|
<PopoverList
|
||||||
|
items={[{ value: 'logout', label: t('logout') }]}
|
||||||
|
onAction={(value) => {
|
||||||
|
if (value === 'logout') {
|
||||||
|
window.location.href = logoutUrl()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
)}
|
||||||
|
<SettingsButton />
|
||||||
|
</Stack>
|
||||||
</nav>
|
</nav>
|
||||||
</Stack>
|
</Stack>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import { BoxScreen } from './BoxScreen'
|
import { BoxScreen } from './BoxScreen'
|
||||||
import { Screen } from './Screen'
|
import { Screen } from './Screen'
|
||||||
import { VerticallyOffCenter } from '@/primitives'
|
import { VerticallyOffCenter } from '@/primitives'
|
||||||
import { Center, Container } from '@/styled-system/jsx'
|
import { Center } from '@/styled-system/jsx'
|
||||||
|
|
||||||
export const LoadingScreen = ({
|
export const LoadingScreen = ({
|
||||||
asBox = false,
|
asBox = false,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"popoverLabel": ""
|
"popoverLabel": ""
|
||||||
},
|
},
|
||||||
"loading": "",
|
"loading": "",
|
||||||
|
"loggedInUserTooltip": "",
|
||||||
"login": "Anmelden",
|
"login": "Anmelden",
|
||||||
"logout": "",
|
"logout": "",
|
||||||
"notFound": {
|
"notFound": {
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
{
|
{
|
||||||
"join": {
|
"join": {
|
||||||
"heading": ""
|
"camlabel": "",
|
||||||
|
"heading": "",
|
||||||
|
"joinLabel": "",
|
||||||
|
"micLabel": "",
|
||||||
|
"userLabel": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{
|
||||||
"account": {
|
|
||||||
"currentlyLoggedAs": "",
|
|
||||||
"heading": "",
|
|
||||||
"youAreNotLoggedIn": ""
|
|
||||||
},
|
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"heading": ""
|
"heading": ""
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"popoverLabel": "Choose language"
|
"popoverLabel": "Choose language"
|
||||||
},
|
},
|
||||||
"loading": "Loading…",
|
"loading": "Loading…",
|
||||||
|
"loggedInUserTooltip": "Logged in as…",
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
"logout": "Logout",
|
"logout": "Logout",
|
||||||
"notFound": {
|
"notFound": {
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
{
|
{
|
||||||
"join": {
|
"join": {
|
||||||
"heading": "Verify your settings before joining"
|
"camlabel": "Camera",
|
||||||
|
"heading": "Join the meeting",
|
||||||
|
"joinLabel": "Join",
|
||||||
|
"micLabel": "Microphone",
|
||||||
|
"userLabel": "Your name"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
{
|
{
|
||||||
"account": {
|
|
||||||
"currentlyLoggedAs": "You are currently logged in as <0>{{user}}</0>",
|
|
||||||
"heading": "Account",
|
|
||||||
"youAreNotLoggedIn": "You are not logged in."
|
|
||||||
},
|
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"heading": "Account and settings"
|
"heading": "Settings"
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"heading": "Language",
|
"heading": "Language",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"popoverLabel": "Choix de la langue"
|
"popoverLabel": "Choix de la langue"
|
||||||
},
|
},
|
||||||
"loading": "Chargement…",
|
"loading": "Chargement…",
|
||||||
|
"loggedInUserTooltip": "Connecté en tant que…",
|
||||||
"login": "Se connecter",
|
"login": "Se connecter",
|
||||||
"logout": "Se déconnecter",
|
"logout": "Se déconnecter",
|
||||||
"notFound": {
|
"notFound": {
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
{
|
{
|
||||||
"join": {
|
"join": {
|
||||||
"heading": "Vérifiez vos paramètres"
|
"camlabel": "Webcam",
|
||||||
|
"heading": "Rejoindre la réunion",
|
||||||
|
"joinLabel": "Rejoindre",
|
||||||
|
"micLabel": "Micro",
|
||||||
|
"userLabel": "Votre nom"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
{
|
{
|
||||||
"account": {
|
|
||||||
"currentlyLoggedAs": "Vous êtes actuellement connecté en tant que <0>{{user}}</0>",
|
|
||||||
"heading": "Compte",
|
|
||||||
"youAreNotLoggedIn": "Vous n'êtes pas connecté."
|
|
||||||
},
|
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"heading": "Compte et paramètres"
|
"heading": "Paramètres"
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"heading": "Langue",
|
"heading": "Langue",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const link = cva({
|
|||||||
textUnderlineOffset: '2',
|
textUnderlineOffset: '2',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
|
transition: 'all 0.2s',
|
||||||
'&[data-hovered]': {
|
'&[data-hovered]': {
|
||||||
textDecoration: 'none',
|
textDecoration: 'none',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
LinkProps,
|
LinkProps,
|
||||||
} from 'react-aria-components'
|
} from 'react-aria-components'
|
||||||
import { cva, type RecipeVariantProps } from '@/styled-system/css'
|
import { cva, type RecipeVariantProps } from '@/styled-system/css'
|
||||||
import { Tooltip, TooltipArrow } from './Tooltip'
|
import { Tooltip } from './Tooltip'
|
||||||
|
|
||||||
const button = cva({
|
const button = cva({
|
||||||
base: {
|
base: {
|
||||||
@@ -76,7 +76,7 @@ const button = cva({
|
|||||||
backgroundColor: 'none!',
|
backgroundColor: 'none!',
|
||||||
'&[data-hovered]': {
|
'&[data-hovered]': {
|
||||||
backgroundColor: 'none!',
|
backgroundColor: 'none!',
|
||||||
borderColor: 'currentcolor',
|
borderColor: 'colorPalette.active!',
|
||||||
},
|
},
|
||||||
'&[data-pressed]': {
|
'&[data-pressed]': {
|
||||||
borderColor: 'currentcolor',
|
borderColor: 'currentcolor',
|
||||||
@@ -93,6 +93,7 @@ const button = cva({
|
|||||||
|
|
||||||
type Tooltip = {
|
type Tooltip = {
|
||||||
tooltip?: string
|
tooltip?: string
|
||||||
|
tooltipType?: 'instant' | 'delayed'
|
||||||
}
|
}
|
||||||
export type ButtonProps = RecipeVariantProps<typeof button> &
|
export type ButtonProps = RecipeVariantProps<typeof button> &
|
||||||
RACButtonsProps &
|
RACButtonsProps &
|
||||||
@@ -102,17 +103,21 @@ type LinkButtonProps = RecipeVariantProps<typeof button> & LinkProps & Tooltip
|
|||||||
|
|
||||||
type ButtonOrLinkProps = ButtonProps | LinkButtonProps
|
type ButtonOrLinkProps = ButtonProps | LinkButtonProps
|
||||||
|
|
||||||
export const Button = ({ tooltip, ...props }: ButtonOrLinkProps) => {
|
export const Button = ({
|
||||||
|
tooltip,
|
||||||
|
tooltipType = 'instant',
|
||||||
|
...props
|
||||||
|
}: ButtonOrLinkProps) => {
|
||||||
const [variantProps, componentProps] = button.splitVariantProps(props)
|
const [variantProps, componentProps] = button.splitVariantProps(props)
|
||||||
if ((props as LinkButtonProps).href !== undefined) {
|
if ((props as LinkButtonProps).href !== undefined) {
|
||||||
return (
|
return (
|
||||||
<TooltipWrapper tooltip={tooltip}>
|
<TooltipWrapper tooltip={tooltip} tooltipType={tooltipType}>
|
||||||
<Link className={button(variantProps)} {...componentProps} />
|
<Link className={button(variantProps)} {...componentProps} />
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<TooltipWrapper tooltip={tooltip}>
|
<TooltipWrapper tooltip={tooltip} tooltipType={tooltipType}>
|
||||||
<RACButton
|
<RACButton
|
||||||
className={button(variantProps)}
|
className={button(variantProps)}
|
||||||
{...(componentProps as RACButtonsProps)}
|
{...(componentProps as RACButtonsProps)}
|
||||||
@@ -123,18 +128,15 @@ export const Button = ({ tooltip, ...props }: ButtonOrLinkProps) => {
|
|||||||
|
|
||||||
const TooltipWrapper = ({
|
const TooltipWrapper = ({
|
||||||
tooltip,
|
tooltip,
|
||||||
|
tooltipType,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
tooltip?: string
|
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
}) => {
|
} & Tooltip) => {
|
||||||
return tooltip ? (
|
return tooltip ? (
|
||||||
<TooltipTrigger delay={300}>
|
<TooltipTrigger delay={tooltipType === 'instant' ? 300 : 1000}>
|
||||||
{children}
|
{children}
|
||||||
<Tooltip>
|
<Tooltip>{tooltip}</Tooltip>
|
||||||
<TooltipArrow />
|
|
||||||
{tooltip}
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
) : (
|
) : (
|
||||||
children
|
children
|
||||||
|
|||||||
@@ -14,10 +14,20 @@ const ListItem = styled(Button, {
|
|||||||
width: 'full',
|
width: 'full',
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
color: 'primary',
|
color: 'box.text',
|
||||||
|
border: '1px solid transparent',
|
||||||
|
'&[data-selected]': {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
'&[data-focused]': {
|
||||||
|
color: 'primary.text',
|
||||||
|
backgroundColor: 'primary',
|
||||||
|
outline: 'none!',
|
||||||
|
},
|
||||||
'&[data-hovered]': {
|
'&[data-hovered]': {
|
||||||
color: 'primary.subtle-text',
|
color: 'primary.text',
|
||||||
backgroundColor: 'primary.subtle',
|
backgroundColor: 'primary',
|
||||||
|
outline: 'none!',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
import { OverlayArrow, Tooltip as RACTooltip } from 'react-aria-components'
|
import { type ReactNode } from 'react'
|
||||||
|
import {
|
||||||
|
OverlayArrow,
|
||||||
|
Tooltip as RACTooltip,
|
||||||
|
TooltipProps,
|
||||||
|
} from 'react-aria-components'
|
||||||
import { styled } from '@/styled-system/jsx'
|
import { styled } from '@/styled-system/jsx'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,7 +14,7 @@ import { styled } from '@/styled-system/jsx'
|
|||||||
*
|
*
|
||||||
* Style taken from example at https://react-spectrum.adobe.com/react-aria/Tooltip.html
|
* Style taken from example at https://react-spectrum.adobe.com/react-aria/Tooltip.html
|
||||||
*/
|
*/
|
||||||
export const Tooltip = styled(RACTooltip, {
|
const StyledTooltip = styled(RACTooltip, {
|
||||||
base: {
|
base: {
|
||||||
boxShadow: '0 8px 20px rgba(0 0 0 / 0.1)',
|
boxShadow: '0 8px 20px rgba(0 0 0 / 0.1)',
|
||||||
borderRadius: '4px',
|
borderRadius: '4px',
|
||||||
@@ -18,7 +23,9 @@ export const Tooltip = styled(RACTooltip, {
|
|||||||
forcedColorAdjust: 'none',
|
forcedColorAdjust: 'none',
|
||||||
outline: 'none',
|
outline: 'none',
|
||||||
padding: '2px 8px',
|
padding: '2px 8px',
|
||||||
maxWidth: '150px',
|
maxWidth: '200px',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: 14,
|
||||||
transform: 'translate3d(0, 0, 0)',
|
transform: 'translate3d(0, 0, 0)',
|
||||||
'&[data-placement=top]': {
|
'&[data-placement=top]': {
|
||||||
marginBottom: '8px',
|
marginBottom: '8px',
|
||||||
@@ -63,7 +70,7 @@ const StyledOverlayArrow = styled(OverlayArrow, {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const TooltipArrow = () => {
|
const TooltipArrow = () => {
|
||||||
return (
|
return (
|
||||||
<StyledOverlayArrow>
|
<StyledOverlayArrow>
|
||||||
<svg width={8} height={8} viewBox="0 0 8 8">
|
<svg width={8} height={8} viewBox="0 0 8 8">
|
||||||
@@ -72,3 +79,15 @@ export const TooltipArrow = () => {
|
|||||||
</StyledOverlayArrow>
|
</StyledOverlayArrow>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const Tooltip = ({
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: Omit<TooltipProps, 'children'> & { children: ReactNode }) => {
|
||||||
|
return (
|
||||||
|
<StyledTooltip {...props}>
|
||||||
|
<TooltipArrow />
|
||||||
|
{children}
|
||||||
|
</StyledTooltip>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user