Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added category autocomplete to the lesson page #1420

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/constants/translations/en/my-resources-page.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
"emptyItems": "You have no categories yet",
"successCreation": "«{{category}}» category was created successfully",
"successDeletion": "Category was deleted successfully",
"confirmDeletionTitle": "Do you confirm category deletion?"
"confirmDeletionTitle": "Do you confirm category deletion?",
"categoryDropdown": "Category..."
},
"confirmDeletionMessage": "This action is permanent and will remove all related content. Please review your decision before proceeding."
}
18 changes: 18 additions & 0 deletions src/containers/category-dropdown/CategoryDropdown.styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const styles = {
addButton: {
justifyContent: 'flex-start',
pl: '10px',
gap: '5px'
},
labelCategory: {
color: 'primary.600',
maxWidth: '464px',
width: '100%',
display: 'flex',
flexDirection: 'column',
gap: '4px'
},
divider: {
color: 'primary.300'
}
}
150 changes: 150 additions & 0 deletions src/containers/category-dropdown/CategoryDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import { HTMLAttributes, SyntheticEvent, useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Box from '@mui/material/Box'
import Typography from '@mui/material/Typography'
import Divider from '@mui/material/Divider'
import AddIcon from '@mui/icons-material/Add'

import useAxios from '~/hooks/use-axios'
import { useModalContext } from '~/context/modal-context'
import { useSnackBarContext } from '~/context/snackbar-context'
import { ResourceService } from '~/services/resource-service'
import AsyncAutocomplete from '~/components/async-autocomlete/AsyncAutocomplete'
import AppButton from '~/components/app-button/AppButton'
import AddCategoriesModal from '~/containers/my-resources/add-categories-modal/AddCategoriesModal'

import { snackbarVariants } from '~/constants'
import {
ButtonVariantEnum,
Categories,
CategoryNameInterface,
ComponentEnum,
CreateCategoriesParams,
ErrorResponse,
SizeEnum,
TypographyVariantEnum
} from '~/types'
import { styles } from '~/containers/category-dropdown/CategoryDropdown.styles'

interface CategoryDropdownInterface {
category: string | null
onCategoryChange: (
_: SyntheticEvent,
value: CategoryNameInterface | null
) => void
}

const CategoryDropdown = ({
category,
onCategoryChange
}: CategoryDropdownInterface) => {
const { t } = useTranslation()
const { setAlert } = useSnackBarContext()
const { openModal, closeModal } = useModalContext()
const [isFetched, setIsFetched] = useState<boolean>(false)

const handleResponseError = (error: ErrorResponse) => {
setAlert({
severity: snackbarVariants.error,
message: error ? `errors.${error.code}` : ''
})
}

const getCategories = useCallback(() => {
setIsFetched(true)
return ResourceService.getResourcesCategoriesNames()
}, [setIsFetched])

const onCreateCategory = () => {
openModal({
component: (
<AddCategoriesModal
closeModal={closeModal}
createCategories={handleCreateCategory}
/>
)
})
}

const createCategory = useCallback(
(params?: CreateCategoriesParams) =>
ResourceService.createResourceCategory(params),
[]
)

const onResponseCategory = useCallback(
(response: Categories | null) => {
const categoryName = response ? response.name : ''

setAlert({
severity: snackbarVariants.success,
message: t('myResourcesPage.categories.successCreation', {
category: categoryName
})
})

setIsFetched(false)
},
[setAlert, t]
)

const { fetchData: handleCreateCategory } = useAxios({
service: createCategory,
defaultResponse: null,
fetchOnMount: false,
onResponse: onResponseCategory,
onResponseError: handleResponseError
})

const optionsList = (
props: HTMLAttributes<HTMLLIElement>,
option: string,
index: number
) => (
<Box key={index}>
{index === 0 && (
<Box>
<AppButton
disableRipple
fullWidth
onClick={onCreateCategory}
size={SizeEnum.Medium}
sx={styles.addButton}
variant={ButtonVariantEnum.Text}
>
<AddIcon />
{t('myResourcesPage.categories.addBtn')}
</AppButton>
<Divider sx={styles.divider} />
</Box>
)}
<Box component={ComponentEnum.Li} {...(props as [])}>
{option}
</Box>
</Box>
)
return (
<Box sx={styles.labelCategory}>
<Typography variant={TypographyVariantEnum.Body2}>
{t('questionPage.chooseCategory')}
</Typography>
<AsyncAutocomplete<CategoryNameInterface>
fetchCondition={!isFetched}
fetchOnFocus
labelField='name'
onChange={onCategoryChange}
renderOption={(props, option, state) =>
optionsList(props, option.name, state.index)
}
service={getCategories}
textFieldProps={{
label: t('myResourcesPage.categories.categoryDropdown')
}}
value={category}
valueField='_id'
/>
</Box>
)
}

export default CategoryDropdown
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export const initialValues = {
title: '',
description: '',
content: '',
attachments: []
attachments: [],
category: null
}

export const defaultResponse = {
Expand Down
13 changes: 13 additions & 0 deletions src/pages/create-or-edit-lesson/CreateOrEditLesson.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ export const styles = {
gap: { xs: '24px', sm: '30px' },
justifyContent: 'space-between'
},
addButton: {
justifyContent: 'flex-start',
pl: '10px',
gap: '5px'
},
labelCategory: {
color: 'primary.600',
maxWidth: '464px',
width: '100%',
display: 'flex',
flexDirection: 'column',
gap: '4px'
},
attachmentList: {
container: {
background: palette.basic.grey,
Expand Down
20 changes: 16 additions & 4 deletions src/pages/create-or-edit-lesson/CreateOrEditLesson.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect } from 'react'
import { SyntheticEvent, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { Link, useNavigate, useParams } from 'react-router-dom'
import { AxiosResponse } from 'axios'
Expand All @@ -11,12 +11,12 @@ import IconButton from '@mui/material/IconButton'
import Loader from '~/components/loader/Loader'
import AddResources from '~/containers/add-resources/AddResources'
import IconExtensionWithTitle from '~/components/icon-extension-with-title/IconExtensionWithTitle'

import { useModalContext } from '~/context/modal-context'
import AppButton from '~/components/app-button/AppButton'
import AppTextField from '~/components/app-text-field/AppTextField'
import FileEditor from '~/components/file-editor/FileEditor'
import PageWrapper from '~/components/page-wrapper/PageWrapper'
import CategoryDropdown from '~/containers/category-dropdown/CategoryDropdown'
import { useSnackBarContext } from '~/context/snackbar-context'
import useAxios from '~/hooks/use-axios'
import useForm from '~/hooks/use-form'
Expand Down Expand Up @@ -45,7 +45,8 @@ import {
SizeEnum,
TextFieldVariantEnum,
Attachment,
ResourcesTabsEnum
ResourcesTabsEnum,
CategoryNameInterface
} from '~/types'

const CreateOrEditLesson = () => {
Expand Down Expand Up @@ -129,6 +130,13 @@ const CreateOrEditLesson = () => {
onResponseError: handleResponseError
})

const onCategoryChange = (
_: SyntheticEvent,
value: CategoryNameInterface | null
) => {
handleNonInputValueChange('category', value?._id ?? null)
}

const {
data,
errors,
Expand All @@ -154,7 +162,7 @@ const CreateOrEditLesson = () => {
}

const { loading: getLessonLoading, fetchData: fetchDataLesson } = useAxios<
Lesson,
LessonData,
string
>({
service: getLesson,
Expand Down Expand Up @@ -216,6 +224,10 @@ const CreateOrEditLesson = () => {
value={data.description}
variant={TextFieldVariantEnum.Standard}
/>
<CategoryDropdown
category={data.category}
onCategoryChange={onCategoryChange}
/>
<Divider sx={styles.divider} />
<AppButton
onClick={handleOpenAddAttachmentsModal}
Expand Down
Loading