💄(frontend) refactor feedbacks screen
Enhance initial screen. Allow user returning to the meeting. Also, add basic and non-functional rating component to mock, what the form would be.
This commit is contained in:
committed by
aleb_the_flash
parent
b07e4c58b4
commit
fb8c0fd1b5
114
src/frontend/src/features/rooms/components/Rating.tsx
Normal file
114
src/frontend/src/features/rooms/components/Rating.tsx
Normal file
@@ -0,0 +1,114 @@
|
||||
import { Button, H, Text } from '@/primitives'
|
||||
import { useState } from 'react'
|
||||
import { cva } from '@/styled-system/css'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { styled } from '@/styled-system/jsx'
|
||||
|
||||
const Card = styled('div', {
|
||||
base: {
|
||||
border: '1px solid',
|
||||
borderColor: 'gray.300',
|
||||
padding: '1rem',
|
||||
marginTop: '1.5rem',
|
||||
borderRadius: '0.25rem',
|
||||
boxShadow: '',
|
||||
},
|
||||
})
|
||||
|
||||
const Bar = styled('div', {
|
||||
base: {
|
||||
display: 'flex',
|
||||
border: '2px solid',
|
||||
borderColor: 'gray.300',
|
||||
borderRadius: '8px',
|
||||
overflowY: 'hidden',
|
||||
scrollbar: 'hidden',
|
||||
},
|
||||
})
|
||||
|
||||
const ratingButtonRecipe = cva({
|
||||
base: {
|
||||
backgroundColor: 'white',
|
||||
color: 'initial',
|
||||
border: 'none',
|
||||
borderRadius: 0,
|
||||
padding: '0.5rem 0.85rem',
|
||||
flexGrow: '1',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
variants: {
|
||||
selected: {
|
||||
true: {
|
||||
backgroundColor: '#1d4ed8',
|
||||
color: 'white',
|
||||
},
|
||||
},
|
||||
borderLeft: {
|
||||
true: {
|
||||
borderLeft: '1px solid',
|
||||
borderColor: 'gray.300',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const labelRecipe = cva({
|
||||
base: {
|
||||
color: 'gray.600',
|
||||
paddingTop: '0.25rem',
|
||||
},
|
||||
})
|
||||
|
||||
export const Rating = ({ maxRating = 8, ...props }) => {
|
||||
const { t } = useTranslation('rooms', { keyPrefix: 'rating' })
|
||||
const [selectedRating, setSelectedRating] = useState<number | null>(null)
|
||||
|
||||
const handleRatingClick = (rating: number) => {
|
||||
setSelectedRating((prevRating) => (prevRating === rating ? null : rating))
|
||||
}
|
||||
|
||||
const minLabel = props?.minLabel ?? t('levels.min')
|
||||
const maxLabel = props?.maxLabel ?? t('levels.max')
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<H lvl={3}>{t('question')}</H>
|
||||
<Bar>
|
||||
{[...Array(maxRating)].map((_, index) => (
|
||||
<Button
|
||||
key={index}
|
||||
onPress={() => handleRatingClick(index + 1)}
|
||||
className={ratingButtonRecipe({
|
||||
selected: selectedRating === index + 1,
|
||||
borderLeft: index != 0,
|
||||
})}
|
||||
>
|
||||
{index + 1}
|
||||
</Button>
|
||||
))}
|
||||
</Bar>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: '1rem',
|
||||
}}
|
||||
>
|
||||
<Text variant="sm" className={labelRecipe()}>
|
||||
{minLabel}
|
||||
</Text>
|
||||
<Text variant="sm" className={labelRecipe()}>
|
||||
{maxLabel}
|
||||
</Text>
|
||||
</div>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
fullWidth
|
||||
isDisabled={!selectedRating}
|
||||
>
|
||||
{t('submit')}
|
||||
</Button>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,17 +1,47 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Text } from '@/primitives'
|
||||
import { Button } from '@/primitives'
|
||||
import { Screen } from '@/layout/Screen'
|
||||
import { CenteredContent } from '@/layout/CenteredContent'
|
||||
import { Center, HStack, styled, VStack } from '@/styled-system/jsx'
|
||||
import { Rating } from '@/features/rooms/components/Rating.tsx'
|
||||
import { useLocation } from 'wouter'
|
||||
|
||||
// fixme - duplicated with home, refactor in a proper style
|
||||
const Heading = styled('h1', {
|
||||
base: {
|
||||
fontWeight: '500',
|
||||
fontStyle: 'normal',
|
||||
fontStretch: 'normal',
|
||||
fontOpticalSizing: 'auto',
|
||||
fontSize: '2.3rem',
|
||||
lineHeight: '2.5rem',
|
||||
letterSpacing: '0',
|
||||
paddingBottom: '2rem',
|
||||
},
|
||||
})
|
||||
|
||||
export const FeedbackRoute = () => {
|
||||
const { t } = useTranslation('rooms')
|
||||
const [, setLocation] = useLocation()
|
||||
return (
|
||||
<Screen layout="centered">
|
||||
<CenteredContent title={t('feedback.heading')} withBackButton>
|
||||
<Text as="p" variant="h3" centered>
|
||||
{t('feedback.body')}
|
||||
</Text>
|
||||
</CenteredContent>
|
||||
<Center>
|
||||
<VStack>
|
||||
<Heading>{t('feedback.heading')}</Heading>
|
||||
<HStack>
|
||||
<Button
|
||||
outline
|
||||
variant="primary"
|
||||
onPress={() => window.history.back()}
|
||||
>
|
||||
{t('feedback.back')}
|
||||
</Button>
|
||||
<Button variant="primary" onPress={() => setLocation('/')}>
|
||||
{t('feedback.home')}
|
||||
</Button>
|
||||
</HStack>
|
||||
<Rating />
|
||||
</VStack>
|
||||
</Center>
|
||||
</Screen>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"feedback": {
|
||||
"body": "",
|
||||
"heading": ""
|
||||
"heading": "",
|
||||
"home": "",
|
||||
"back": ""
|
||||
},
|
||||
"join": {
|
||||
"videoinput": {
|
||||
@@ -109,6 +110,14 @@
|
||||
"chat": {
|
||||
"disclaimer": ""
|
||||
},
|
||||
"rating": {
|
||||
"submit": "",
|
||||
"question": "",
|
||||
"levels": {
|
||||
"min": "",
|
||||
"max": ""
|
||||
}
|
||||
},
|
||||
"participants": {
|
||||
"subheading": "",
|
||||
"contributors": "",
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"feedback": {
|
||||
"body": "Please fill out the form available in the header to give us your precious feedback! Thanks.",
|
||||
"heading": "Help us improve Visio"
|
||||
"heading": "You have left the meeting",
|
||||
"home": "Return to home",
|
||||
"back": "Rejoin the meeting"
|
||||
},
|
||||
"join": {
|
||||
"videoinput": {
|
||||
@@ -107,6 +108,14 @@
|
||||
"chat": {
|
||||
"disclaimer": "The messages are visible to participants only at the time they are sent. All messages are deleted at the end of the call."
|
||||
},
|
||||
"rating": {
|
||||
"submit": "Submit",
|
||||
"question": "What do you think about the quality of your call?",
|
||||
"levels": {
|
||||
"min": "very poor",
|
||||
"max": "excellent"
|
||||
}
|
||||
},
|
||||
"participants": {
|
||||
"subheading": "In room",
|
||||
"you": "You",
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"feedback": {
|
||||
"body": "Remplissez le formulaire disponible dans l'entête du site pour nous donner votre avis sur l'outil. Vos retours sont précieux ! Merci.",
|
||||
"heading": "Aidez-nous à améliorer Visio"
|
||||
"heading": "Vous avez quitté la réunion",
|
||||
"home": "Retourner à l'accueil",
|
||||
"back": "Réintégrer la réunion"
|
||||
},
|
||||
"join": {
|
||||
"videoinput": {
|
||||
@@ -107,6 +108,14 @@
|
||||
"chat": {
|
||||
"disclaimer": "Les messages sont visibles par les participants uniquement au moment de\nleur envoi. Tous les messages sont supprimés à la fin de l'appel."
|
||||
},
|
||||
"rating": {
|
||||
"submit": "Envoyer",
|
||||
"question": "Que pensez-vous de la qualité de votre appel ?",
|
||||
"levels": {
|
||||
"min": "très mauvaise",
|
||||
"max": "excellente"
|
||||
}
|
||||
},
|
||||
"participants": {
|
||||
"subheading": "Dans la réunion",
|
||||
"you": "Vous",
|
||||
|
||||
@@ -59,6 +59,9 @@ export const buttonRecipe = cva({
|
||||
},
|
||||
primary: {
|
||||
colorPalette: 'primary',
|
||||
'&[data-disabled]': {
|
||||
opacity: 0.3,
|
||||
},
|
||||
},
|
||||
// @TODO: better handling of colors… this is a mess
|
||||
success: {
|
||||
|
||||
Reference in New Issue
Block a user