💄(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 { SettingsButton } from '@/features/settings'
|
||||||
import { logoutUrl, useUser } from '@/features/auth'
|
import { logoutUrl, useUser } from '@/features/auth'
|
||||||
import { useMatchesRoute } from '@/navigation/useMatchesRoute'
|
import { useMatchesRoute } from '@/navigation/useMatchesRoute'
|
||||||
import { Feedback } from '@/components/Feedback'
|
import { FeedbackBanner } from '@/components/FeedbackBanner.tsx'
|
||||||
import { Menu } from '@/primitives/Menu'
|
import { Menu } from '@/primitives/Menu'
|
||||||
import { MenuList } from '@/primitives/MenuList'
|
import { MenuList } from '@/primitives/MenuList'
|
||||||
import { ProConnectButton } from '@/components/ProConnectButton'
|
import { ProConnectButton } from '@/components/ProConnectButton'
|
||||||
@@ -20,77 +20,79 @@ export const Header = () => {
|
|||||||
const { user, isLoggedIn } = useUser()
|
const { user, isLoggedIn } = useUser()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<>
|
||||||
className={css({
|
<FeedbackBanner />
|
||||||
paddingY: 1,
|
|
||||||
paddingX: 1,
|
|
||||||
flexShrink: 0,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
className={css({
|
className={css({
|
||||||
display: 'flex',
|
paddingY: 1,
|
||||||
flexDirection: 'column',
|
paddingX: 1,
|
||||||
rowGap: 1,
|
flexShrink: 0,
|
||||||
md: {
|
|
||||||
rowGap: 0,
|
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
alignItems: 'center',
|
|
||||||
},
|
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<header>
|
<div
|
||||||
<Stack gap={2.25} direction="row" align="center">
|
className={css({
|
||||||
<Text bold variant="h1" margin={false}>
|
display: 'flex',
|
||||||
<Link
|
flexDirection: 'column',
|
||||||
onClick={(event) => {
|
rowGap: 1,
|
||||||
if (
|
md: {
|
||||||
isRoom &&
|
rowGap: 0,
|
||||||
!window.confirm(t('leaveRoomPrompt', { ns: 'rooms' }))
|
flexDirection: 'row',
|
||||||
) {
|
justifyContent: 'space-between',
|
||||||
event.preventDefault()
|
alignItems: 'center',
|
||||||
}
|
},
|
||||||
}}
|
})}
|
||||||
to="/"
|
>
|
||||||
>
|
<header>
|
||||||
{t('app')}
|
<Stack gap={2.25} direction="row" align="center">
|
||||||
</Link>
|
<Text bold variant="h1" margin={false}>
|
||||||
</Text>
|
<Link
|
||||||
<Feedback />
|
onClick={(event) => {
|
||||||
</Stack>
|
if (
|
||||||
</header>
|
isRoom &&
|
||||||
<nav>
|
!window.confirm(t('leaveRoomPrompt', { ns: 'rooms' }))
|
||||||
<Stack gap={1} direction="row" align="center">
|
) {
|
||||||
{isLoggedIn === false && !isHome && (
|
event.preventDefault()
|
||||||
<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()
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
to="/"
|
||||||
</Menu>
|
>
|
||||||
)}
|
{t('app')}
|
||||||
<SettingsButton />
|
</Link>
|
||||||
</Stack>
|
</Text>
|
||||||
</nav>
|
</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>
|
||||||
</div>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
"error": {
|
"error": {
|
||||||
"heading": ""
|
"heading": ""
|
||||||
},
|
},
|
||||||
"feedbackAlert": "",
|
"feedback": {
|
||||||
|
"context": "",
|
||||||
|
"cta": ""
|
||||||
|
},
|
||||||
"forbidden": {
|
"forbidden": {
|
||||||
"heading": ""
|
"heading": ""
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
"error": {
|
"error": {
|
||||||
"heading": "An error occurred while loading the page"
|
"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": {
|
"forbidden": {
|
||||||
"heading": "You don't have the permission to view this page"
|
"heading": "You don't have the permission to view this page"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
"error": {
|
"error": {
|
||||||
"heading": "Une erreur est survenue lors du chargement de la page"
|
"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": {
|
"forbidden": {
|
||||||
"heading": "Accès interdit"
|
"heading": "Accès interdit"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user