2
0

feat(bot): 💄 Responsive rating input

This commit is contained in:
Baptiste Arnaud
2022-06-20 15:13:11 +02:00
parent 6938533126
commit 49bf178090
5 changed files with 32 additions and 52 deletions

View File

@ -7,6 +7,7 @@ type Props = {
export const RatingInputContent = ({ block }: Props) => (
<Text noOfLines={1} pr="6">
Rate from 1 to {block.options.length}
Rate from {block.options.buttonType === 'Icons' ? 1 : 0} to{' '}
{block.options.length}
</Text>
)

View File

@ -33,9 +33,6 @@ export const RatingInputSettings = ({
const handleLeftLabelChange = (left: string) =>
onOptionsChange({ ...options, labels: { ...options.labels, left } })
const handleMiddleLabelChange = (middle: string) =>
onOptionsChange({ ...options, labels: { ...options.labels, middle } })
const handleRightLabelChange = (right: string) =>
onOptionsChange({ ...options, labels: { ...options.labels, right } })
@ -92,7 +89,7 @@ export const RatingInputSettings = ({
)}
<Stack>
<FormLabel mb="0" htmlFor="button">
1 label:
{options.buttonType === 'Icons' ? '1' : '0'} label:
</FormLabel>
<Input
id="button"
@ -101,19 +98,6 @@ export const RatingInputSettings = ({
placeholder="Not likely at all"
/>
</Stack>
{options.length >= 4 && (
<Stack>
<FormLabel mb="0" htmlFor="button">
{Math.floor(options.length / 2)} label:
</FormLabel>
<Input
id="button"
defaultValue={options.labels.middle}
onChange={handleMiddleLabelChange}
placeholder="Neutral"
/>
</Stack>
)}
<Stack>
<FormLabel mb="0" htmlFor="button">
{options.length} label:

View File

@ -39,15 +39,14 @@ test('options should work', async ({ page }) => {
await typebotViewer(page).locator(`text=8`).click()
await typebotViewer(page).locator(`text=Send`).click()
await expect(typebotViewer(page).locator(`text=8`)).toBeVisible()
await page.click('text=Rate from 1 to 10')
await page.click('text=10')
await page.click('text=5')
await page.click('text=Rate from 0 to 10')
await page.click('text="10"')
await page.click('text="5"')
await page.click('text=Numbers')
await page.click('text=Icons')
await page.click('text="Custom icon?"')
await page.fill('[placeholder="<svg>...</svg>"]', boxSvg)
await page.fill('[placeholder="Not likely at all"]', 'Not likely at all')
await page.fill('[placeholder="Neutral"]', 'Neutral')
await page.fill('[placeholder="Extremely likely"]', 'Extremely likely')
await page.click('text="Restart"')
await expect(typebotViewer(page).locator(`text=8`)).toBeHidden()
@ -55,7 +54,6 @@ test('options should work', async ({ page }) => {
await expect(
typebotViewer(page).locator(`text=Not likely at all`)
).toBeVisible()
await expect(typebotViewer(page).locator(`text=Neutral`)).toBeVisible()
await expect(
typebotViewer(page).locator(`text=Extremely likely`)
).toBeVisible()

View File

@ -1,5 +1,5 @@
import { RatingInputOptions, RatingInputBlock } from 'models'
import React, { FormEvent, useRef, useState } from 'react'
import React, { FormEvent, useState } from 'react'
import { isDefined, isEmpty, isNotDefined } from 'utils'
import { InputSubmitContent } from '../InputChatBlock'
import { SendButton } from './SendButton'
@ -11,7 +11,6 @@ type Props = {
export const RatingForm = ({ block, onSubmit }: Props) => {
const [rating, setRating] = useState<number>()
const scaleElement = useRef<HTMLDivElement | null>(null)
const handleSubmit = (e: FormEvent) => {
e.preventDefault()
@ -23,33 +22,32 @@ export const RatingForm = ({ block, onSubmit }: Props) => {
return (
<form className="flex flex-col" onSubmit={handleSubmit}>
<div className="flex flex-col" ref={scaleElement}>
<div className="flex">
{Array.from(Array(block.options.length)).map((_, idx) => (
<RatingButton
{...block.options}
key={idx}
rating={rating}
idx={idx + 1}
onClick={handleClick}
/>
))}
</div>
<div className="flex justify-between mr-2 mb-2">
{<span className="text-sm w-full ">{block.options.labels.left}</span>}
{!isEmpty(block.options.labels.middle) && (
<span className="text-sm w-full text-center">
{block.options.labels.middle}
</span>
)}
{
<span className="text-sm w-full text-right">
{block.options.labels.right}
</span>
}
</div>
{block.options.labels.left && (
<span className="text-sm w-full mb-2 rating-label">
{block.options.labels.left}
</span>
)}
<div className="flex flex-wrap justify-center">
{Array.from(
Array(
block.options.length +
(block.options.buttonType === 'Numbers' ? 1 : 0)
)
).map((_, idx) => (
<RatingButton
{...block.options}
key={idx}
rating={rating}
idx={idx + (block.options.buttonType === 'Numbers' ? 0 : 1)}
onClick={handleClick}
/>
))}
</div>
{block.options.labels.right && (
<span className="text-sm w-full text-right mb-2 pr-2 rating-label">
{block.options.labels.right}
</span>
)}
<div className="flex justify-end mr-2">
{isDefined(rating) && (

View File

@ -20,7 +20,6 @@ export const ratingInputOptionsSchema = optionBaseSchema.and(
labels: z.object({
left: z.string().optional(),
right: z.string().optional(),
middle: z.string().optional(),
button: z.string(),
}),
customIcon: z.object({