Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…eToStudy-Client into develop
  • Loading branch information
Mav-Ivan committed Sep 28, 2023
2 parents 9e1c7a0 + 41e985c commit bde00dd
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 72 deletions.
39 changes: 24 additions & 15 deletions src/components/question/Question.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC } from 'react'
import { Dispatch, FC, SetStateAction } from 'react'
import { useTranslation } from 'react-i18next'
import { MenuItem, SxProps } from '@mui/material'
import Box from '@mui/material/Box'
Expand All @@ -7,7 +7,6 @@ import Typography from '@mui/material/Typography'
import FormControlLabel from '@mui/material/FormControlLabel'
import Checkbox from '@mui/material/Checkbox'
import CheckIcon from '@mui/icons-material/Check'
import appPallete from '~/styles/app-theme/app.pallete'
import DragIndicatorIcon from '@mui/icons-material/DragIndicator'
import IconButton from '@mui/material/IconButton'
import MoreVertIcon from '@mui/icons-material/MoreVert'
Expand All @@ -19,25 +18,38 @@ import useMenu from '~/hooks/use-menu'
import IconTitleDescription from '~/components/icon-title-description/IconTitleDescription'
import AppChip from '~/components/app-chip/AppChip'

import { ColorEnum, TableActionFunc } from '~/types'
import {
ColorEnum,
Question as QuestionInterface,
TableActionFunc
} from '~/types'
import { styles } from '~/components/question/Question.styles'
import { spliceSx } from '~/utils/helper-functions'
import { QuestionWithCategory } from '~/types/questions/questions.index'

interface QuestionProps extends QuestionWithCategory {
interface QuestionProps {
question: QuestionInterface
setQuestions: Dispatch<SetStateAction<QuestionInterface[]>>
sx?: SxProps
}

const Question: FC<QuestionProps> = ({ question, category, sx = {} }) => {
const Question: FC<QuestionProps> = ({ question, setQuestions, sx = {} }) => {
const { t } = useTranslation()
const { openMenu, renderMenu, closeMenu } = useMenu()

const onAction = async (actionFunc: TableActionFunc) => {
closeMenu()
await actionFunc(question._id)
}

const onDeleteQuestion = () => {
setQuestions((prev) => {
return prev.filter((item) => item._id !== question._id)
})
}

const rowActions = [
{
id: 1,
label: (
<Box sx={styles.editIconWrapper}>
<EditIcon sx={styles.editIcon} />
Expand All @@ -49,20 +61,19 @@ const Question: FC<QuestionProps> = ({ question, category, sx = {} }) => {
}
},
{
id: 2,
label: (
<Box sx={styles.deleteIconWrapper}>
<DeleteOutlineIcon color='primary' sx={styles.deleteIcon} />
{` ${t('common.delete')}`}
</Box>
),
func: (id: string) => {
console.log('Delete', id)
}
func: onDeleteQuestion
}
]

const menuItems = rowActions.map(({ label, func }) => (
<MenuItem key={label} onClick={() => void onAction(func)}>
const menuItems = rowActions.map(({ label, func, id }) => (
<MenuItem key={id} onClick={() => void onAction(func)}>
{label}
</MenuItem>
))
Expand All @@ -74,9 +85,7 @@ const Question: FC<QuestionProps> = ({ question, category, sx = {} }) => {
control={<Checkbox />}
label={answer.text}
/>
{answer.isCorrect && (
<CheckIcon sx={{ color: appPallete.basic.orientalHerbs }} />
)}
{answer.isCorrect && <CheckIcon sx={styles.checkIcon} />}
</Box>
))

Expand All @@ -101,7 +110,7 @@ const Question: FC<QuestionProps> = ({ question, category, sx = {} }) => {
{renderMenu(menuItems)}
</Box>
<AppChip labelSx={styles.categoryChipLabel} sx={styles.categoryChip}>
{category.name}
{question.category.name}
</AppChip>

<Divider />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import EditIcon from '@mui/icons-material/Edit'
import AddIcon from '@mui/icons-material/Add'

import { useModalContext } from '~/context/modal-context'
import QuestionsList from '~/containers/questions-list/QuestionsList'
import AddQuestions from '~/containers/my-resources/add-questions/AddQuestions'
import AppButton from '~/components/app-button/AppButton'
import AppTextField from '~/components/app-text-field/AppTextField'
Expand Down Expand Up @@ -76,6 +77,9 @@ const EditQuizContainer = () => {
variant={TextFieldVariantEnum.Standard}
/>
<Divider sx={styles.divider} />

<QuestionsList items={questions} setItems={setQuestions} />

<Box sx={styles.functionalButtons}>
<AppButton
size={SizeEnum.ExtraLarge}
Expand Down
20 changes: 8 additions & 12 deletions src/containers/questions-list/QuestionsList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC } from 'react'
import { FC, Dispatch, SetStateAction } from 'react'
import {
DragDropContext,
Droppable,
Expand All @@ -13,19 +13,19 @@ import Box from '@mui/material/Box'
import Question from '~/components/question/Question'

import { styles } from '~/containers/questions-list/QuestionsList.styles'
import { QuestionWithCategory } from '~/types'
import { Question as QuestionInterface } from '~/types'

interface QuestionsListProps {
items: QuestionWithCategory[]
setItems: (items: QuestionWithCategory[]) => void
items: QuestionInterface[]
setItems: Dispatch<SetStateAction<QuestionInterface[]>>
}

const QuestionsList: FC<QuestionsListProps> = ({ items, setItems }) => {
const reorder = (
list: QuestionWithCategory[],
list: QuestionInterface[],
startIndex: number,
endIndex: number
): QuestionWithCategory[] => {
): QuestionInterface[] => {
const result = Array.from(list)
const [removed] = result.splice(startIndex, 1)
result.splice(endIndex, 0, removed)
Expand All @@ -48,19 +48,15 @@ const QuestionsList: FC<QuestionsListProps> = ({ items, setItems }) => {
}

const questionsList = items.map((item, i) => (
<Draggable
draggableId={item.question._id}
index={i}
key={item.question._id}
>
<Draggable draggableId={item._id} index={i} key={item._id}>
{(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => (
<Box
ref={provided.innerRef}
sx={styles.question(snapshot.isDragging)}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<Question {...item} />
<Question question={item} setQuestions={setItems} />
</Box>
)}
</Draggable>
Expand Down
9 changes: 0 additions & 9 deletions src/types/questions/interfaces/questions.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,3 @@ export interface Question extends CommonEntityFields {
type: QuestionTypesEnum
category: Pick<CategoryInterface, '_id' | 'name'>
}
export interface QuestionCategory {
name: string
_id: string
}

export interface QuestionWithCategory {
question: Question
category: QuestionCategory
}
54 changes: 34 additions & 20 deletions tests/unit/components/question/Question.spec.jsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
import { screen, render } from '@testing-library/react'
import { screen, render, fireEvent } from '@testing-library/react'
import Question from '~/components/question/Question'

const mockedQuestion = {
question: {
title: 'About Philosophy',
answers: [
{
id: '1',
text: 'Buddha Shakyamuni',
isCorrect: true
},
{
id: '2',
text: 'Jordan Belfort',
isCorrect: false
}
],
text: 'Who created buddhism?',
id: '1'
},
id: '1',
title: 'About Philosophy',
answers: [
{
id: '1',
text: 'Buddha Shakyamuni',
isCorrect: true
},
{
id: '2',
text: 'Jordan Belfort',
isCorrect: false
}
],
text: 'Who created buddhism?',
category: {
_id: 'some-text-id-123',
name: 'Philosophy'
}
}

const setQuestionsMock = vi.fn()

describe('Question', () => {
beforeEach(() => {
render(<Question {...mockedQuestion} />)
render(
<Question question={mockedQuestion} setQuestions={setQuestionsMock} />
)
})

it('render question text', () => {
const questionText = screen.getByText(mockedQuestion.question.text)
const questionText = screen.getByText(mockedQuestion.text)

expect(questionText).toBeInTheDocument()
})
Expand All @@ -41,4 +43,16 @@ describe('Question', () => {

expect(category).toBeInTheDocument()
})

it('should delete chosen category', () => {
const moreIcon = screen.getByTestId('MoreVertIcon')

fireEvent.click(moreIcon)

const deleteIcon = screen.getByTestId('DeleteOutlineIcon')

fireEvent.click(deleteIcon)

expect(setQuestionsMock).toHaveBeenCalled()
})
})
31 changes: 15 additions & 16 deletions tests/unit/containers/questions-list/QuestionsList.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,20 @@ import { renderWithProviders } from '~tests/test-utils'

const mockedItems = [
{
question: {
title: 'React',
text: 'Does React have Virtual DOM?',
items: [
{
text: 'Yes',
isCorrect: true
},
{
text: 'No',
isCorrect: false
}
],
author: 'some-author-id'
},
title: 'React',
text: 'Does React have Virtual DOM?',
_id: 'some_id',
answers: [
{
text: 'Yes',
isCorrect: true
},
{
text: 'No',
isCorrect: false
}
],
author: 'some-author-id',
category: {
_id: 'some-category-id',
name: 'Philosophy'
Expand All @@ -37,7 +36,7 @@ describe('QuestionsList test', () => {
})

it('should render question', () => {
const text = screen.getByText(mockedItems[0].question.text)
const text = screen.getByText(mockedItems[0].text)

expect(text).toBeInTheDocument()
})
Expand Down

0 comments on commit bde00dd

Please sign in to comment.