Skip to content

Commit

Permalink
Created filters with title and description for new course (#1356)
Browse files Browse the repository at this point in the history
* filters-for-new-course
fixed_conlicts

q

* fixed_some_conflicts

* second_fix

* next_commit

* final_commit

* comments_fixed

* refactored

* fixednewcomments
  • Loading branch information
mynotdoing authored Nov 21, 2023
1 parent f48ce0e commit b5ac280
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/constants/translations/en/filters.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"creationTime": "Creation time"
}
},
"filtersListTitle": "Filters"
"filtersListTitle": "Filters",
"filtersLevelsLable": "Levels"
}
5 changes: 5 additions & 0 deletions src/constants/translations/en/my-courses-page.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@
"newCourse": {
"bannerTitle": "Add Banner Image",
"addIconAlt": "Add image icon"
},
"filterLabel": {
"categories": "Choose the category of the course",
"subjects": "Choose the subject of the course",
"levels": "Choose suitable levels for the course"
}
}
3 changes: 2 additions & 1 deletion src/constants/translations/ua/filters.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"creationTime": "Часом створення"
}
},
"filtersListTitle": "Фільтри"
"filtersListTitle": "Фільтри",
"filtersLevelsLable": "Рівні"
}
5 changes: 5 additions & 0 deletions src/constants/translations/ua/my-courses-page.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@
"newCourse": {
"bannerTitle": "Додайте зображення банеру",
"addIcon": "Додати забраження"
},
"filterLabel": {
"categories": "Оберіть категорію курсу",
"subjects": "Оберіть предмет курсу",
"levels": "Оберіть відповідний рівень курсу"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { TypographyVariantEnum } from '~/types'
const commonStyle = {
fontSize: '14px',
position: 'absolute',
top: '-33px',
left: '-14px'
}

export const styles = {
container: {
minHeight: '110px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between'
},
autocomplete: {
width: '100%',
maxWidth: { md: '370px' },
mr: '30px',
'& .MuiOutlinedInput-root': {
padding: '5px 9px'
},
label: {
lineHeight: '20px'
},
position: 'relative',
'& .MuiFormHelperText-root': {
...commonStyle
}
},
drowlevel: {
width: '370px',
position: 'relative'
},
drowstyle: {
...commonStyle
},
otherToolbar: {
borderRadius: '10px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
backgroundColor: 'backgroundColor',
boxShadow: 'none'
},
menuProps: {
PaperProps: {
style: {
maxHeight: '224px',
width: '250px'
}
}
},
input: {
style: {
padding: 0
}
},
descriptionLabel: {
shrink: false,
sx: { typography: TypographyVariantEnum.Body1, top: -21 }
},
titleInput: {
disableUnderline: true,
style: {
fontSize: '35px',
fontWeight: 500,
maxHeight: '35px',
marginTop: 0
}
},
descriptionInput: {
disableUnderline: true,
style: { fontSize: '16px', maxHeight: '16px', marginTop: 0 }
},
titleLabel: {
shrink: false,
sx: { typography: TypographyVariantEnum.H4, top: -23 }
},
titleDescBox: {
width: '100%',
display: 'flex',
flexDirection: 'column',
marginBottom: '30px'
},
searchBoxes: {
width: '100%',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
my: '30px'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { useCallback, useState, SyntheticEvent, ChangeEvent } from 'react'
import { useTranslation } from 'react-i18next'
import FormControl from '@mui/material/FormControl'
import FormHelperText from '@mui/material/FormHelperText'
import Box from '@mui/material/Box'
import OutlinedInput from '@mui/material/OutlinedInput'
import InputLabel from '@mui/material/InputLabel'
import MenuItem from '@mui/material/MenuItem'
import ListItemText from '@mui/material/ListItemText'
import Select, { SelectChangeEvent } from '@mui/material/Select'
import Checkbox from '@mui/material/Checkbox'

import AppTextField from '~/components/app-text-field/AppTextField'
import { subjectService } from '~/services/subject-service'
import { categoryService } from '~/services/category-service'
import useBreakpoints from '~/hooks/use-breakpoints'
import AppToolbar from '~/components/app-toolbar/AppToolbar'
import AsyncAutocomplete from '~/components/async-autocomlete/AsyncAutocomplete'

import {
CategoryNameInterface,
FindOffersFilters,
FindOffersFiltersActions,
SubjectNameInterface,
ProficiencyLevelEnum,
TextFieldVariantEnum
} from '~/types'
import { styles } from '~/containers/my-courses/course-search-tool-bar/CourseSearchToolbar.style'

interface OfferSearchToolbarProps {
filters: FindOffersFilters
filterActions: FindOffersFiltersActions<FindOffersFilters>
resetPage: () => void
}
const levelLists = Object.values(ProficiencyLevelEnum)
const CourseSearchToolbar = ({
filters,
resetPage,
filterActions
}: OfferSearchToolbarProps) => {
const { t } = useTranslation()
const { isMobile } = useBreakpoints()
const { updateFilterInQuery } = filterActions
const [selectedLevel, setSelectedLevel] = useState<ProficiencyLevelEnum[]>([])
const [titleName, setTitleName] = useState<string>('')
const [decriptionName, setDecriptionName] = useState<string>('')
const getSubjectsNames = useCallback(
() => subjectService.getSubjectsNames(filters.categoryId),
[filters.categoryId]
)
const onChangeTitle = (e: ChangeEvent<HTMLInputElement>) => {
setTitleName(e.target.value)
}
const onChangeDescription = (e: ChangeEvent<HTMLInputElement>) => {
setDecriptionName(e.target.value)
}
const onCategoryChange = (
_: SyntheticEvent,
value: CategoryNameInterface | null
) => {
updateFilterInQuery(value?._id ?? '', 'categoryId')
updateFilterInQuery('', 'subjectId')
resetPage()
}
const onSubjectChange = (
_: SyntheticEvent,
value: SubjectNameInterface | null
) => {
updateFilterInQuery(value?._id ?? '', 'subjectId')
resetPage()
}
const onLevelChange = (event: SelectChangeEvent<ProficiencyLevelEnum[]>) => {
const {
target: { value }
} = event
setSelectedLevel(value as ProficiencyLevelEnum[])
updateFilterInQuery(value as ProficiencyLevelEnum[], 'proficiencyLevel')
resetPage()
}
const renderSelectedLevels = (selected: string[]) => {
return selected.join(', ')
}
const menuItems = levelLists.map((item) => (
<MenuItem key={item} value={item}>
<Checkbox checked={selectedLevel.indexOf(item) > -1} />
<ListItemText primary={item} />
</MenuItem>
))
const AppAutoCompleteList = (
<>
<AsyncAutocomplete
labelField='name'
onChange={onCategoryChange}
service={categoryService.getCategoriesNames}
sx={styles.autocomplete}
textFieldProps={{
label: t('breadCrumbs.categories'),
helperText: t('myCoursesPage.filterLabel.categories')
}}
value={filters.categoryId}
valueField='_id'
/>
<AsyncAutocomplete
disabled={!filters.categoryId}
labelField='name'
onChange={onSubjectChange}
service={getSubjectsNames}
sx={styles.autocomplete}
textFieldProps={{
label: t('breadCrumbs.subjects'),
helperText: t('myCoursesPage.filterLabel.subjects')
}}
value={filters.subjectId}
valueField='_id'
/>
<FormControl>
<InputLabel>{t('filters.filtersLevelsLable')}</InputLabel>
<Select
MenuProps={styles.menuProps}
id='demo-multiple-checkbox'
input={<OutlinedInput label='Level' />}
labelId='demo-multiple-checkbox-label'
multiple
onChange={onLevelChange}
renderValue={renderSelectedLevels}
sx={styles.drowlevel}
value={filters.proficiencyLevel}
>
{menuItems}
</Select>
<FormHelperText sx={styles.drowstyle}>
{t('myCoursesPage.filterLabel.levels')}
</FormHelperText>
</FormControl>
</>
)

return (
<Box sx={styles.container}>
{!isMobile && (
<AppToolbar sx={styles.otherToolbar}>
<Box sx={styles.titleDescBox}>
<AppTextField
InputLabelProps={styles.titleLabel}
InputProps={styles.titleInput}
fullWidth
inputProps={styles.input}
label={titleName ? ' ' : t('lesson.labels.title')}
onChange={onChangeTitle}
value={titleName}
variant={TextFieldVariantEnum.Standard}
/>
<AppTextField
InputLabelProps={styles.descriptionLabel}
InputProps={styles.descriptionInput}
fullWidth
inputProps={styles.input}
label={decriptionName ? ' ' : t('lesson.labels.description')}
onChange={onChangeDescription}
value={decriptionName}
variant={TextFieldVariantEnum.Standard}
/>
</Box>
<Box sx={styles.searchBoxes}>{AppAutoCompleteList}</Box>
</AppToolbar>
)}
{isMobile && AppAutoCompleteList}
</Box>
)
}

export default CourseSearchToolbar
28 changes: 25 additions & 3 deletions src/pages/create-course/CreateCourse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@ import Box from '@mui/material/Box'
import AddIcon from '@mui/icons-material/Add'

import PageWrapper from '~/components/page-wrapper/PageWrapper'
import AppButton from '~/components/app-button/AppButton'
import CourseSectionsList from '~/containers/course-sections-list/CourseSectionsList'

import { sectionInitialData } from '~/pages/create-course/CreateCourse.constants'
import AddCourseBanner from '~/containers/add-course-banner/AddCourseBanner'
import { authRoutes } from '~/router/constants/authRoutes'
import CourseSearchToolbar from '~/containers/my-courses/course-search-tool-bar/CourseSearchToolbar'
import { useFilterQuery } from '~/hooks/use-filter-query'
import AppButton from '~/components/app-button/AppButton'

import {
ButtonTypeEnum,
ButtonVariantEnum,
SizeEnum,
CourseSection
} from '~/types'

import { countActiveOfferFilters } from '~/utils/count-active-filters'
import { authRoutes } from '~/router/constants/authRoutes'
import { defaultFilters } from '~/pages/find-offers/FindOffers.constants'
import { UserRoleEnum } from '~/types'
import { styles } from '~/pages/create-course/CreateCourse.styles'

const CreateCourse = () => {
Expand All @@ -41,6 +46,16 @@ const CreateCourse = () => {
}

const formData = new FormData()
const { filters, filterQueryActions } = useFilterQuery({
defaultFilters: defaultFilters(UserRoleEnum.Tutor),
countActiveFilters: countActiveOfferFilters
})
const resetPage = () => {
filterQueryActions.updateFilterInQuery(
defaultFilters(UserRoleEnum.Tutor).page,
'page'
)
}

return (
<PageWrapper>
Expand All @@ -59,6 +74,13 @@ const CreateCourse = () => {
{t('course.addSectionBtn')}
</AppButton>
</Box>
<Box>
<CourseSearchToolbar
filterActions={filterQueryActions}
filters={filters}
resetPage={resetPage}
/>
</Box>
<Box sx={styles.buttons}>
<AppButton
onClick={() => navigate(authRoutes.myCourses.root.path)}
Expand Down

0 comments on commit b5ac280

Please sign in to comment.