💩(frontend) introduce multistep form
Add an open feedback form step, to allow people giving us some feedbacks on what's wrong with our product.
This commit is contained in:
committed by
aleb_the_flash
parent
4ffef3f94a
commit
200e2d3c2f
@@ -1,9 +1,10 @@
|
|||||||
import { Button, H, Text } from '@/primitives'
|
import { Button, H, Text, TextArea } from '@/primitives'
|
||||||
import { useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { cva } from '@/styled-system/css'
|
import { cva } from '@/styled-system/css'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { styled } from '@/styled-system/jsx'
|
import { styled, VStack } from '@/styled-system/jsx'
|
||||||
import { usePostHog } from 'posthog-js/react'
|
import { usePostHog } from 'posthog-js/react'
|
||||||
|
import { PostHog } from 'posthog-js'
|
||||||
|
|
||||||
const Card = styled('div', {
|
const Card = styled('div', {
|
||||||
base: {
|
base: {
|
||||||
@@ -13,6 +14,8 @@ const Card = styled('div', {
|
|||||||
marginTop: '1.5rem',
|
marginTop: '1.5rem',
|
||||||
borderRadius: '0.25rem',
|
borderRadius: '0.25rem',
|
||||||
boxShadow: '',
|
boxShadow: '',
|
||||||
|
minWidth: '380px',
|
||||||
|
minHeight: '196px',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -65,8 +68,76 @@ const labelRecipe = cva({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const Rating = ({ maxRating = 7, ...props }) => {
|
const OpenFeedback = ({
|
||||||
const posthog = usePostHog()
|
posthog,
|
||||||
|
onNext,
|
||||||
|
}: {
|
||||||
|
posthog: PostHog
|
||||||
|
onNext: () => void
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation('rooms', { keyPrefix: 'openFeedback' })
|
||||||
|
const [feedback, setFeedback] = useState('')
|
||||||
|
|
||||||
|
const onContinue = () => {
|
||||||
|
setFeedback('')
|
||||||
|
onNext()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSubmit = () => {
|
||||||
|
try {
|
||||||
|
posthog.capture('survey sent', {
|
||||||
|
$survey_id: '01933c5a-5a1d-0000-ada8-e39f5918c2d4',
|
||||||
|
$survey_response: feedback,
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e)
|
||||||
|
} finally {
|
||||||
|
onContinue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<H lvl={3}>{t('question')}</H>
|
||||||
|
<TextArea
|
||||||
|
id="feedbackInput"
|
||||||
|
name="feedback"
|
||||||
|
placeholder={t('placeholder')}
|
||||||
|
required
|
||||||
|
value={feedback}
|
||||||
|
onChange={(e) => setFeedback(e.target.value)}
|
||||||
|
style={{
|
||||||
|
minHeight: '150px',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<VStack gap="0.5">
|
||||||
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
size="sm"
|
||||||
|
fullWidth
|
||||||
|
isDisabled={!feedback}
|
||||||
|
onPress={onSubmit}
|
||||||
|
>
|
||||||
|
{t('submit')}
|
||||||
|
</Button>
|
||||||
|
<Button invisible size="sm" fullWidth onPress={onNext}>
|
||||||
|
{t('skip')}
|
||||||
|
</Button>
|
||||||
|
</VStack>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const RateQuality = ({
|
||||||
|
posthog,
|
||||||
|
onNext,
|
||||||
|
maxRating = 7,
|
||||||
|
}: {
|
||||||
|
posthog: PostHog
|
||||||
|
onNext: () => void
|
||||||
|
maxRating?: number
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation('rooms', { keyPrefix: 'rating' })
|
const { t } = useTranslation('rooms', { keyPrefix: 'rating' })
|
||||||
const [selectedRating, setSelectedRating] = useState<number | null>(null)
|
const [selectedRating, setSelectedRating] = useState<number | null>(null)
|
||||||
|
|
||||||
@@ -74,26 +145,20 @@ export const Rating = ({ maxRating = 7, ...props }) => {
|
|||||||
setSelectedRating((prevRating) => (prevRating === rating ? null : rating))
|
setSelectedRating((prevRating) => (prevRating === rating ? null : rating))
|
||||||
}
|
}
|
||||||
|
|
||||||
const minLabel = props?.minLabel ?? t('levels.min')
|
|
||||||
const maxLabel = props?.maxLabel ?? t('levels.max')
|
|
||||||
|
|
||||||
const onSubmit = () => {
|
const onSubmit = () => {
|
||||||
try {
|
try {
|
||||||
posthog.capture('survey sent', {
|
posthog.capture('survey sent', {
|
||||||
$survey_id: '01933c22-d005-0000-b623-20b752171e2e',
|
$survey_id: '01933c22-d005-0000-b623-20b752171e2e',
|
||||||
$survey_response: `${selectedRating}`,
|
$survey_response: `${selectedRating}`,
|
||||||
})
|
})
|
||||||
setSelectedRating(null)
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(e)
|
console.warn(e)
|
||||||
|
} finally {
|
||||||
setSelectedRating(null)
|
setSelectedRating(null)
|
||||||
|
onNext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!posthog.__loaded) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<H lvl={3}>{t('question')}</H>
|
<H lvl={3}>{t('question')}</H>
|
||||||
@@ -119,10 +184,10 @@ export const Rating = ({ maxRating = 7, ...props }) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text variant="sm" className={labelRecipe()}>
|
<Text variant="sm" className={labelRecipe()}>
|
||||||
{minLabel}
|
{t('levels.min')}
|
||||||
</Text>
|
</Text>
|
||||||
<Text variant="sm" className={labelRecipe()}>
|
<Text variant="sm" className={labelRecipe()}>
|
||||||
{maxLabel}
|
{t('levels.max')}
|
||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
@@ -137,3 +202,48 @@ export const Rating = ({ maxRating = 7, ...props }) => {
|
|||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ConfirmationMessage = ({ onNext }: { onNext: () => void }) => {
|
||||||
|
const { t } = useTranslation('rooms', { keyPrefix: 'confirmationMessage' })
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
onNext()
|
||||||
|
}, 10000)
|
||||||
|
return () => clearTimeout(timer)
|
||||||
|
}, [onNext])
|
||||||
|
return (
|
||||||
|
<Card
|
||||||
|
style={{
|
||||||
|
maxWidth: '380px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<VStack gap={0}>
|
||||||
|
<H lvl={3}>{t('heading')}</H>
|
||||||
|
<Text as="p" variant="paragraph" centered>
|
||||||
|
{t('body')}
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Rating = () => {
|
||||||
|
const posthog = usePostHog()
|
||||||
|
|
||||||
|
const [step, setStep] = useState(0)
|
||||||
|
|
||||||
|
if (step == 0) {
|
||||||
|
return <RateQuality posthog={posthog} onNext={() => setStep(step + 1)} />
|
||||||
|
}
|
||||||
|
|
||||||
|
if (step == 1) {
|
||||||
|
return <OpenFeedback posthog={posthog} onNext={() => setStep(step + 1)} />
|
||||||
|
}
|
||||||
|
|
||||||
|
if (step == 2) {
|
||||||
|
return <ConfirmationMessage onNext={() => setStep(0)} />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -118,6 +118,16 @@
|
|||||||
"max": ""
|
"max": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"openFeedback": {
|
||||||
|
"question": "",
|
||||||
|
"placeholder": "",
|
||||||
|
"submit": "",
|
||||||
|
"skip": ""
|
||||||
|
},
|
||||||
|
"confirmationMessage": {
|
||||||
|
"heading": "",
|
||||||
|
"body": ""
|
||||||
|
},
|
||||||
"participants": {
|
"participants": {
|
||||||
"subheading": "",
|
"subheading": "",
|
||||||
"contributors": "",
|
"contributors": "",
|
||||||
|
|||||||
@@ -116,6 +116,16 @@
|
|||||||
"max": "excellent"
|
"max": "excellent"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"openFeedback": {
|
||||||
|
"question": "What can we do to improve Visio?",
|
||||||
|
"placeholder": "Describe your bugs or share your suggestions…",
|
||||||
|
"submit": "Submit",
|
||||||
|
"skip": "Skip"
|
||||||
|
},
|
||||||
|
"confirmationMessage": {
|
||||||
|
"heading": "Thank you for your submission",
|
||||||
|
"body": "Our product team takes the time to carefully review your feedback. We will get back to you as soon as possible."
|
||||||
|
},
|
||||||
"participants": {
|
"participants": {
|
||||||
"subheading": "In room",
|
"subheading": "In room",
|
||||||
"you": "You",
|
"you": "You",
|
||||||
|
|||||||
@@ -116,6 +116,16 @@
|
|||||||
"max": "excellente"
|
"max": "excellente"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"openFeedback": {
|
||||||
|
"question": "Que pouvons-nous faire pour améliorer Visio ?",
|
||||||
|
"placeholder": "Décrivez vos bugs ou partagez vos suggestions …",
|
||||||
|
"submit": "Envoyer",
|
||||||
|
"skip": "Passer"
|
||||||
|
},
|
||||||
|
"confirmationMessage": {
|
||||||
|
"heading": "Merci pour votre submission",
|
||||||
|
"body": "Notre équipe produit prend le temps d'analyser attentivement vos réponses. Nous reviendrons vers vous dans les plus brefs délais."
|
||||||
|
},
|
||||||
"participants": {
|
"participants": {
|
||||||
"subheading": "Dans la réunion",
|
"subheading": "Dans la réunion",
|
||||||
"you": "Vous",
|
"you": "Vous",
|
||||||
|
|||||||
Reference in New Issue
Block a user