Skip to content

Commit

Permalink
[#30] Fill the data into the Question page
Browse files Browse the repository at this point in the history
  • Loading branch information
manh-t committed Jul 21, 2023
1 parent c832741 commit d174586
Show file tree
Hide file tree
Showing 22 changed files with 495 additions and 63 deletions.
176 changes: 176 additions & 0 deletions src/components/Answer/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import React from 'react';

import { render, screen } from '@testing-library/react';

import { Question } from 'types/question';

import Answer from '.';

describe('Answer', () => {
describe('given the display type is star', () => {
it('renders Rating component', () => {
const question: Question = {
id: 'id',
resourceType: 'question',
displayType: 'star',
answers: [],
};
const dataTestId = 'answer';
render(<Answer question={question} data-test-id={dataTestId} />);

const star = screen.getByTestId(dataTestId);

expect(star).toBeVisible();
expect(star).toHaveAttribute('id', 'rating-id');
});
});

describe('given the display type is choice', () => {
it('renders MultiChoice component', () => {
const question: Question = {
id: 'id',
resourceType: 'question',
displayType: 'choice',
answers: [],
};
const dataTestId = 'answer';
render(<Answer question={question} data-test-id={dataTestId} />);

const multiChoice = screen.getByTestId(dataTestId);

expect(multiChoice).toBeVisible();
expect(multiChoice).toHaveAttribute('id', 'multi-choice-id');
});
});

describe('given the display type is nps', () => {
it('renders Nps component', () => {
const question: Question = {
id: 'id',
resourceType: 'question',
displayType: 'nps',
answers: [],
};
const dataTestId = 'answer';
render(<Answer question={question} data-test-id={dataTestId} />);

const nps = screen.getByTestId(dataTestId);

expect(nps).toBeVisible();
expect(nps).toHaveAttribute('id', 'nps-id');
});
});

describe('given the display type is textarea', () => {
it('renders TextArea component', () => {
const question: Question = {
id: 'id',
resourceType: 'question',
displayType: 'textarea',
answers: [
{
id: 'id',
resourceType: 'answer',
text: '',
},
],
};
const dataTestId = 'answer';
render(<Answer question={question} data-test-id={dataTestId} />);

const textArea = screen.getByTestId(dataTestId);

expect(textArea).toBeVisible();
expect(textArea).toHaveAttribute('id', 'text-area-id');
});
});

describe('given the display type is textfield', () => {
it('renders MultiInputs component', () => {
const question: Question = {
id: 'id',
resourceType: 'question',
displayType: 'textfield',
answers: [
{
id: 'id',
resourceType: 'answer',
text: '',
},
],
};
const dataTestId = 'answer';
render(<Answer question={question} data-test-id={dataTestId} />);

const multiInputs = screen.getByTestId(dataTestId);

expect(multiInputs).toBeVisible();
expect(multiInputs).toHaveAttribute('id', 'multi-inputs-id');
});
});

describe('given the display type is dropdown', () => {
it('renders Dropdown component', () => {
const question: Question = {
id: 'id',
resourceType: 'question',
displayType: 'dropdown',
answers: [
{
id: 'id',
resourceType: 'answer',
text: '',
},
],
};
const dataTestId = 'answer';
render(<Answer question={question} data-test-id={dataTestId} />);

const dropdown = screen.getByTestId(dataTestId);

expect(dropdown).toBeVisible();
expect(dropdown).toHaveAttribute('id', 'dropdown-id');
});
});

describe('given the display type is slider', () => {
it('renders Dropdown component', () => {
const question: Question = {
id: 'id',
resourceType: 'question',
displayType: 'slider',
answers: [
{
id: 'id',
resourceType: 'answer',
text: '',
},
],
};
const dataTestId = 'answer';
render(<Answer question={question} data-test-id={dataTestId} />);

const slider = screen.getByTestId(dataTestId);

expect(slider).toBeVisible();
expect(slider).toHaveAttribute('id', 'slider-id');
});
});

describe('given the display type is intro', () => {
it('renders Dropdown component', () => {
const question: Question = {
id: 'id',
resourceType: 'question',
displayType: 'intro',
answers: [],
};
const dataTestId = 'answer';
render(<Answer question={question} data-test-id={dataTestId} />);

const intro = screen.getByTestId(dataTestId);

expect(intro).toBeVisible();
});
});
});
59 changes: 59 additions & 0 deletions src/components/Answer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';

import AppSlider from 'components/AppSlider';
import Dropdown from 'components/Dropdown';
import MultiChoice from 'components/MultiChoice';
import MultiInputs from 'components/MultiInputs';
import Nps from 'components/Nps';
import Rating from 'components/Rating';
import TextArea from 'components/TextArea';
import { DisplayType, Question, getDisplayTypeEnum } from 'types/question';

interface AnswerProps {
question: Question;
'data-test-id'?: string;
}
const Answer = ({ question, ...rest }: AnswerProps): JSX.Element => {
const displayTypeEnum = getDisplayTypeEnum(question);

switch (displayTypeEnum) {
case DisplayType.Heart:
case DisplayType.Smiley:
case DisplayType.Thumbs:
case DisplayType.Star:
return (
<Rating
questionId={question.id}
items={question.answers}
displayType={displayTypeEnum}
data-test-id={rest['data-test-id']}
/>
);
case DisplayType.Choice:
return (
<MultiChoice
questionId={question.id}
items={question.answers}
isPickOne={question?.pick === 'one'}
data-test-id={rest['data-test-id']}
/>
);
case DisplayType.Nps:
return <Nps questionId={question.id} items={question.answers} data-test-id={rest['data-test-id']} />;
case DisplayType.Textarea:
return <TextArea questionId={question.id} items={question.answers} data-test-id={rest['data-test-id']} />;
case DisplayType.Textfield:
return <MultiInputs questionId={question.id} items={question.answers} data-test-id={rest['data-test-id']} />;
case DisplayType.Dropdown:
return <Dropdown questionId={question.id} items={question.answers} data-test-id={rest['data-test-id']} />;
case DisplayType.Slider:
return <AppSlider questionId={question.id} items={question.answers} data-test-id={rest['data-test-id']} />;
case DisplayType.Unknown:
case DisplayType.Intro:
case DisplayType.Outro:
default:
return <div {...rest}></div>;
}
};

export default Answer;
2 changes: 1 addition & 1 deletion src/components/AppSlider/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('AppSlider', () => {
it('renders AppSlider component', () => {
const dataTestId = 'appSlider';
// eslint-disable-next-line react/react-in-jsx-scope, @typescript-eslint/no-empty-function
render(<AppSlider data-test-id={dataTestId} onValueChanged={jest.fn()} />);
render(<AppSlider questionId="question id" items={[]} data-test-id={dataTestId} onValueChanged={jest.fn()} />);

const appSlider = screen.getByTestId(dataTestId);

Expand Down
27 changes: 16 additions & 11 deletions src/components/AppSlider/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
import React from 'react';
import React, { useEffect } from 'react';

import Slider from 'rc-slider';

import 'rc-slider/assets/index.css';
import { Answer } from 'types/answer';

interface SliderProps {
min?: number;
max?: number;
step?: number;
onValueChanged: (position: number) => void;
questionId: string;
items: Answer[];
onValueChanged?: (answer: Answer) => void;
'data-test-id'?: string;
}

const AppSlider = ({ min = 1, max = 100, step = 1, onValueChanged, ...rest }: SliderProps): JSX.Element => {
const AppSlider = ({ questionId, items, onValueChanged, ...rest }: SliderProps): JSX.Element => {
const handleOnChange = (value: number) => {
onValueChanged(value);
onValueChanged?.(items[value - 1]);
};

useEffect(() => {
onValueChanged?.(items[0]);
}, [questionId, items, onValueChanged]);

return (
<div className="flex w-full h-[56px] justify-center items-center" {...rest}>
<div id={`slider-${questionId}`} className="flex w-full h-[56px] justify-center items-center" {...rest}>
<Slider
trackStyle={{
background: 'rgba(255, 255, 255, 1)',
Expand All @@ -40,9 +45,9 @@ const AppSlider = ({ min = 1, max = 100, step = 1, onValueChanged, ...rest }: Sl
boxShadow:
'0px 3px 1px 0px rgba(0, 0, 0, 0.10), 0px 1px 1px 0px rgba(0, 0, 0, 0.16), 0px 3px 8px 0px rgba(0, 0, 0, 0.15)',
}}
min={min}
max={max}
step={step}
min={1}
max={items.length}
step={1}
onChange={(value) => handleOnChange(value as number)}
/>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/Dropdown/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('Dropdown', () => {
],
'data-test-id': dropdownDataTestId,
};
render(<Dropdown {...dropdownProps} />);
render(<Dropdown questionId="question id" {...dropdownProps} />);

const dropdown = screen.getByTestId(dropdownDataTestId);

Expand All @@ -44,7 +44,7 @@ describe('Dropdown', () => {
onValueChanged: onValueChanged,
'data-test-id': dropdownDataTestId,
};
render(<Dropdown {...dropdownProps} />);
render(<Dropdown questionId="question id" {...dropdownProps} />);

const dropdown = screen.getByTestId(dropdownDataTestId);

Expand Down
11 changes: 8 additions & 3 deletions src/components/Dropdown/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';

import { ReactComponent as ArrowDropdown } from 'assets/images/icons/arrow-dropdown.svg';
import { Answer } from 'types/answer';

interface DropdownProps {
questionId: string;
items: Answer[];
onValueChanged?: (value: Answer) => void;
'data-test-id'?: string;
}
const Dropdown = ({ items, onValueChanged, ...rest }: DropdownProps): JSX.Element => {
const Dropdown = ({ questionId, items, onValueChanged, ...rest }: DropdownProps): JSX.Element => {
const [isOpen, setIsOpen] = useState(false);
const [selectedValue, setSelectedValue] = useState(items[0].text);

Expand All @@ -22,8 +23,12 @@ const Dropdown = ({ items, onValueChanged, ...rest }: DropdownProps): JSX.Elemen
toggleDropdown();
};

useEffect(() => {
setSelectedValue(items[0].text);
}, [questionId, items]);

return (
<div className="relative flex flex-col items-center w-full rounded-lg" {...rest}>
<div id={`dropdown-${questionId}`} className="relative flex flex-col items-center w-full rounded-lg" {...rest}>
<button
onClick={() => toggleDropdown()}
className="w-full h-14 flex items-center justify-between appearance-none bg-white bg-opacity-[.18] rounded-[12px] hover:outline-none hover:ring-transparent px-3 text-white text-regular tracking-survey-tight hover:bg-opacity-30"
Expand Down
6 changes: 5 additions & 1 deletion src/components/ElevatedButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ const ElevatedButton = ({ children, isFullWidth, ...attributes }: ElevatedButton
'bg-white text-black-chinese font-bold text-regular tracking-survey-tight rounded-[10px] focus:outline-none focus:shadow-outline h-14';

return (
<button type="button" className={classNames(DEFAULT_CLASS_NAMES, { 'w-full': isFullWidth })} {...attributes}>
<button
type="button"
className={classNames(DEFAULT_CLASS_NAMES, { 'w-full': isFullWidth, 'px-8': !isFullWidth })}
{...attributes}
>
{children}
</button>
);
Expand Down
4 changes: 3 additions & 1 deletion src/components/MultiChoice/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('MultiChoice', () => {
{ id: '2', resourceType: 'answer', text: 'Test 2' },
{ id: '3', resourceType: 'answer', text: 'Test 3' },
];
render(<MultiChoice items={answers} isPickOne={false} data-test-id={multiChoiceDataTestId} />);
render(<MultiChoice questionId="question id" items={answers} isPickOne={false} data-test-id={multiChoiceDataTestId} />);

const multiChoice = screen.getByTestId(multiChoiceDataTestId);

Expand All @@ -38,6 +38,7 @@ describe('MultiChoice', () => {
];
render(
<MultiChoice
questionId="question id"
items={answers}
isPickOne={false}
onValuesChanged={(answers) => handleValuesChanged(answers)}
Expand Down Expand Up @@ -77,6 +78,7 @@ describe('MultiChoice', () => {
];
render(
<MultiChoice
questionId="question id"
items={answers}
isPickOne={true}
onValuesChanged={(answers) => handleValuesChanged(answers)}
Expand Down
Loading

0 comments on commit d174586

Please sign in to comment.