💄(frontend) update feedback button to banner with context
Refactored the feedback alert button into a more discreet and polished banner. The banner provides additional context about Visio being under construction. Also updated the link to the feedback form.
This commit is contained in:
committed by
aleb_the_flash
parent
24e819a533
commit
061f12e7e2
@@ -1,25 +0,0 @@
|
||||
import { css } from '@/styled-system/css'
|
||||
import { RiExternalLinkLine } from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { LinkButton } from '@/primitives'
|
||||
|
||||
export const Feedback = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<LinkButton
|
||||
href="https://grist.incubateur.net/o/docs/forms/1YrfNP1QSSy8p2gCxMFnSf/4"
|
||||
variant="success"
|
||||
target="_blank"
|
||||
>
|
||||
<span className={css({ marginRight: 0.5 })} aria-hidden="true">
|
||||
💡
|
||||
</span>
|
||||
{t('feedbackAlert')}
|
||||
<RiExternalLinkLine
|
||||
size={16}
|
||||
className={css({ marginLeft: 0.5 })}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</LinkButton>
|
||||
)
|
||||
}
|
||||
46
src/frontend/src/components/FeedbackBanner.tsx
Normal file
46
src/frontend/src/components/FeedbackBanner.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { css } from '@/styled-system/css'
|
||||
import { RiErrorWarningLine, RiExternalLinkLine } from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Text, A } from '@/primitives'
|
||||
|
||||
const GRIST_FORM =
|
||||
'https://grist.numerique.gouv.fr/o/docs/forms/1YrfNP1QSSy8p2gCxMFnSf/4'
|
||||
|
||||
export const FeedbackBanner = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div
|
||||
className={css({
|
||||
width: '100%',
|
||||
backgroundColor: '#E8EDFF',
|
||||
color: '#0063CB',
|
||||
display: { base: 'none', sm: 'flex' },
|
||||
justifyContent: 'center',
|
||||
padding: '0.5rem 0',
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className={css({
|
||||
display: 'inline-flex',
|
||||
gap: '0.5rem',
|
||||
alignItems: 'center',
|
||||
})}
|
||||
>
|
||||
<RiErrorWarningLine size={20} />
|
||||
<Text as="p">{t('feedback.context')}</Text>
|
||||
<div
|
||||
className={css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 0.25,
|
||||
})}
|
||||
>
|
||||
<A href={GRIST_FORM} target="_blank">
|
||||
{t('feedback.cta')}
|
||||
</A>
|
||||
<RiExternalLinkLine size={16} aria-hidden="true" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import { Text, Button } from '@/primitives'
|
||||
import { SettingsButton } from '@/features/settings'
|
||||
import { logoutUrl, useUser } from '@/features/auth'
|
||||
import { useMatchesRoute } from '@/navigation/useMatchesRoute'
|
||||
import { Feedback } from '@/components/Feedback'
|
||||
import { FeedbackBanner } from '@/components/FeedbackBanner.tsx'
|
||||
import { Menu } from '@/primitives/Menu'
|
||||
import { MenuList } from '@/primitives/MenuList'
|
||||
import { ProConnectButton } from '@/components/ProConnectButton'
|
||||
@@ -20,77 +20,79 @@ export const Header = () => {
|
||||
const { user, isLoggedIn } = useUser()
|
||||
|
||||
return (
|
||||
<div
|
||||
className={css({
|
||||
paddingY: 1,
|
||||
paddingX: 1,
|
||||
flexShrink: 0,
|
||||
})}
|
||||
>
|
||||
<>
|
||||
<FeedbackBanner />
|
||||
<div
|
||||
className={css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
rowGap: 1,
|
||||
md: {
|
||||
rowGap: 0,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
},
|
||||
paddingY: 1,
|
||||
paddingX: 1,
|
||||
flexShrink: 0,
|
||||
})}
|
||||
>
|
||||
<header>
|
||||
<Stack gap={2.25} direction="row" align="center">
|
||||
<Text bold variant="h1" margin={false}>
|
||||
<Link
|
||||
onClick={(event) => {
|
||||
if (
|
||||
isRoom &&
|
||||
!window.confirm(t('leaveRoomPrompt', { ns: 'rooms' }))
|
||||
) {
|
||||
event.preventDefault()
|
||||
}
|
||||
}}
|
||||
to="/"
|
||||
>
|
||||
{t('app')}
|
||||
</Link>
|
||||
</Text>
|
||||
<Feedback />
|
||||
</Stack>
|
||||
</header>
|
||||
<nav>
|
||||
<Stack gap={1} direction="row" align="center">
|
||||
{isLoggedIn === false && !isHome && (
|
||||
<ProConnectButton hint={false} />
|
||||
)}
|
||||
{!!user && (
|
||||
<Menu>
|
||||
<Button
|
||||
size="sm"
|
||||
invisible
|
||||
tooltip={t('loggedInUserTooltip')}
|
||||
tooltipType="delayed"
|
||||
>
|
||||
{user?.full_name || user?.email}
|
||||
</Button>
|
||||
<MenuList
|
||||
items={[{ value: 'logout', label: t('logout') }]}
|
||||
onAction={(value) => {
|
||||
if (value === 'logout') {
|
||||
terminateAnalyticsSession()
|
||||
terminateSupportSession()
|
||||
window.location.href = logoutUrl()
|
||||
<div
|
||||
className={css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
rowGap: 1,
|
||||
md: {
|
||||
rowGap: 0,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
},
|
||||
})}
|
||||
>
|
||||
<header>
|
||||
<Stack gap={2.25} direction="row" align="center">
|
||||
<Text bold variant="h1" margin={false}>
|
||||
<Link
|
||||
onClick={(event) => {
|
||||
if (
|
||||
isRoom &&
|
||||
!window.confirm(t('leaveRoomPrompt', { ns: 'rooms' }))
|
||||
) {
|
||||
event.preventDefault()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Menu>
|
||||
)}
|
||||
<SettingsButton />
|
||||
</Stack>
|
||||
</nav>
|
||||
to="/"
|
||||
>
|
||||
{t('app')}
|
||||
</Link>
|
||||
</Text>
|
||||
</Stack>
|
||||
</header>
|
||||
<nav>
|
||||
<Stack gap={1} direction="row" align="center">
|
||||
{isLoggedIn === false && !isHome && (
|
||||
<ProConnectButton hint={false} />
|
||||
)}
|
||||
{!!user && (
|
||||
<Menu>
|
||||
<Button
|
||||
size="sm"
|
||||
invisible
|
||||
tooltip={t('loggedInUserTooltip')}
|
||||
tooltipType="delayed"
|
||||
>
|
||||
{user?.full_name || user?.email}
|
||||
</Button>
|
||||
<MenuList
|
||||
items={[{ value: 'logout', label: t('logout') }]}
|
||||
onAction={(value) => {
|
||||
if (value === 'logout') {
|
||||
terminateAnalyticsSession()
|
||||
terminateSupportSession()
|
||||
window.location.href = logoutUrl()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Menu>
|
||||
)}
|
||||
<SettingsButton />
|
||||
</Stack>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
"error": {
|
||||
"heading": ""
|
||||
},
|
||||
"feedbackAlert": "",
|
||||
"feedback": {
|
||||
"context": "",
|
||||
"cta": ""
|
||||
},
|
||||
"forbidden": {
|
||||
"heading": ""
|
||||
},
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
"error": {
|
||||
"heading": "An error occurred while loading the page"
|
||||
},
|
||||
"feedbackAlert": "Give us feedback",
|
||||
"feedback": {
|
||||
"context": "Visio is still evolving—your input matters!",
|
||||
"cta": "Share your feedback"
|
||||
},
|
||||
"forbidden": {
|
||||
"heading": "You don't have the permission to view this page"
|
||||
},
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
"error": {
|
||||
"heading": "Une erreur est survenue lors du chargement de la page"
|
||||
},
|
||||
"feedbackAlert": "Donnez-nous votre avis",
|
||||
"feedback": {
|
||||
"context": "Visio est en pleine construction — votre avis compte !",
|
||||
"cta": "Partagez votre avis"
|
||||
},
|
||||
"forbidden": {
|
||||
"heading": "Accès interdit"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user