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

Created section for new category #1357

Merged
merged 15 commits into from
Nov 7, 2023
20 changes: 20 additions & 0 deletions src/constants/translations/en/course.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"addSectionBtn": "Add Section",
"courseSection": {
"defaultNewTitle": "Section 1",
"defaultNewDescription": "Description...",
"addResourceBtn": "Add Resource",
"resourcesMenu": {
"lessonMenuItem": "Lesson",
"quizMenuItem": "Quiz",
"attachmentMenuItem": "Attachment"
},
"sectionMenu": {
"deleteSection": "Delete"
}
},
"errorMessages": {
"title": "Please provide a title",
"description": "Please provide a description"
}
}
4 changes: 3 additions & 1 deletion src/constants/translations/en/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import myCoursesPage from './my-courses-page.json'
import chatPage from './chat.json'
import lesson from './lesson.json'
import questionPage from './question-page.json'
import course from './course.json'

const en = {
translations: {
Expand Down Expand Up @@ -76,7 +77,8 @@ const en = {
myCoursesPage,
chatPage,
lesson,
questionPage
questionPage,
course
}
}

Expand Down
20 changes: 20 additions & 0 deletions src/constants/translations/ua/course.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"addSectionBtn": "Новий курс",
"courseSection": {
"defaultNewTitle": "Розділ 1",
"defaultNewDescription": "Опис ...",
"addResourceBtn": "Додати матеріал",
"resourcesMenu": {
"lessonMenuItem": "Урок",
"quizMenuItem": "Тест",
"attachmentMenuItem": "Вкладення"
},
"sectionMenu": {
"deleteSection": "Видалити"
}
},
"errorMessages": {
"title": "Будь ласка, вкажіть заголовок.",
"description": "Будь ласка, надайте опис."
}
}
4 changes: 3 additions & 1 deletion src/constants/translations/ua/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import admin from './admin.json'
import cookiePolicyPage from './cookie-policy-page.json'
import guestHomePage from './guest-home-page.json'
import table from './table.json'
import course from './course.json'

const ua = {
translations: {
Expand Down Expand Up @@ -68,7 +69,8 @@ const ua = {
admin,
cookiePolicyPage,
guestHomePage,
table
table,
course
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const menuTypes = {
resourcesMenu: 'resources',
sectionMenu: 'section'
}
62 changes: 62 additions & 0 deletions src/containers/course-section/CourseSectionContainer.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { TypographyVariantEnum } from '~/types'

export const styles = {
root: {
backgroundColor: 'basic.white',
borderRadius: '6px',
p: '24px'
},
header: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'baseline'
},
dragIconWrapper: {
display: 'flex',
justifyContent: 'center'
},
dragIcon: {
fontSize: '30px',
transform: 'rotate(90deg)',
color: 'primary.400',
cursor: 'pointer'
},
input: {
style: { padding: 0, margin: 0 }
},
titleInput: {
disableUnderline: true,
style: {
marginTop: 0,
fontSize: '20px',
maxHeight: '20px',
fontWeight: 500
}
},
headerIconWrapper: {
marginRight: '20px'
},
headerIcon: {
fontSize: '24px'
},
descriptionInput: {
style: {
marginTop: 0
},
disableUnderline: true
},
titleLabel: {
shrink: false,
sx: { typography: TypographyVariantEnum.H6, top: -23 }
},
descriptionLabel: {
sx: { typography: TypographyVariantEnum.Body1, top: -20 },
shrink: false
},
menuItem: {
minWidth: '300px',
pl: '30px',
py: '15px',
typography: TypographyVariantEnum.MidTitle
}
}
187 changes: 187 additions & 0 deletions src/containers/course-section/CourseSectionContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import { useState, ChangeEvent, FC, Dispatch, SetStateAction } from 'react'
import { useTranslation } from 'react-i18next'
import { MenuItem } from '@mui/material'
import Box from '@mui/material/Box'
import DragIndicatorIcon from '@mui/icons-material/DragIndicator'
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'
import IconButton from '@mui/material/IconButton'
import MoreVertIcon from '@mui/icons-material/MoreVert'
import AddIcon from '@mui/icons-material/Add'
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'

import AppTextField from '~/components/app-text-field/AppTextField'
import AppButton from '~/components/app-button/AppButton'

import useMenu from '~/hooks/use-menu'

import { styles } from '~/containers/course-section/CourseSectionContainer.styles'
import { menuTypes } from '~/containers/course-section/CourseSectionContainer.constants'
import {
TextFieldVariantEnum,
SizeEnum,
ColorEnum,
ButtonVariantEnum,
CourseSection
} from '~/types'

interface SectionProps {
sectionData: CourseSection
setSectionsItems: Dispatch<SetStateAction<CourseSection[]>>
}

type openModalFunc = () => void

const CourseSectionContainer: FC<SectionProps> = ({
sectionData,
setSectionsItems
}) => {
const { t } = useTranslation()
const { openMenu, renderMenu, closeMenu } = useMenu()

const [activeMenu, setActiveMenu] = useState<string>('')
const [isVisible, setIsVisible] = useState<boolean>(true)
const [titleInput, setTitleInput] = useState<string>(sectionData.title)
const [descriptionInput, setDescriptionInput] = useState(
sectionData.description
)

const onShowHide = () => {
setIsVisible((isVisible) => !isVisible)
}

const onAction = (actionFunc: openModalFunc) => {
actionFunc()
}

const onTitleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
setTitleInput(event.target.value)
}

const onDescriptionInputChange = (event: ChangeEvent<HTMLInputElement>) => {
setDescriptionInput(event.target.value)
}

const onDeleteSection = () => {
setSectionsItems((prev) => {
return prev.filter((item) => item.id !== sectionData.id)
})
}

const sectionActions = [
{
id: 1,
label: <Box>{t('course.courseSection.sectionMenu.deleteSection')}</Box>,
func: onDeleteSection
}
]

const sectionMenuItems = sectionActions.map(({ label, func, id }) => (
<MenuItem key={id} onClick={func}>
{label}
</MenuItem>
))

const addResourceActions = [
{
id: 1,
label: (
<Box>{t('course.courseSection.resourcesMenu.lessonMenuItem')}</Box>
),
func: closeMenu
},
{
id: 2,
label: <Box>{t('course.courseSection.resourcesMenu.quizMenuItem')}</Box>,
func: closeMenu
},
{
id: 3,
label: (
<Box>{t('course.courseSection.resourcesMenu.attachmentMenuItem')}</Box>
),
func: closeMenu
}
]

const resourcesMenuItems = addResourceActions.map(({ label, func, id }) => (
<MenuItem key={id} onClick={() => onAction(func)} sx={styles.menuItem}>
{label}
</MenuItem>
))

return (
<Box sx={styles.root}>
<Box sx={styles.dragIconWrapper}>
<DragIndicatorIcon sx={styles.dragIcon} />
</Box>
<Box sx={styles.header}>
<IconButton onClick={onShowHide} sx={styles.headerIconWrapper}>
{isVisible ? (
<KeyboardArrowUpIcon
color={ColorEnum.Primary}
sx={styles.headerIcon}
/>
) : (
<KeyboardArrowDownIcon
color={ColorEnum.Primary}
sx={styles.headerIcon}
/>
)}
</IconButton>
<AppTextField
InputLabelProps={styles.titleLabel}
InputProps={styles.titleInput}
fullWidth
inputProps={styles.input}
label={titleInput ? '' : t('course.courseSection.defaultNewTitle')}
onChange={onTitleInputChange}
value={titleInput}
variant={TextFieldVariantEnum.Standard}
/>
<IconButton
onClick={(event) => {
setActiveMenu(menuTypes.sectionMenu)
openMenu(event)
}}
>
<MoreVertIcon color={ColorEnum.Primary} sx={styles.headerIcon} />
</IconButton>
{activeMenu === menuTypes.sectionMenu && renderMenu(sectionMenuItems)}
</Box>
{isVisible && (
<Box>
<AppTextField
InputLabelProps={styles.descriptionLabel}
InputProps={styles.descriptionInput}
fullWidth
inputProps={styles.input}
label={
descriptionInput
? ''
: t('course.courseSection.defaultNewDescription')
}
onChange={onDescriptionInputChange}
value={descriptionInput}
variant={TextFieldVariantEnum.Standard}
/>
<AppButton
endIcon={<KeyboardArrowDownIcon fontSize={SizeEnum.Small} />}
onClick={(event) => {
setActiveMenu(menuTypes.resourcesMenu)
openMenu(event)
}}
size={SizeEnum.Large}
startIcon={<AddIcon fontSize={SizeEnum.Small} />}
variant={ButtonVariantEnum.Contained}
>
{t('course.courseSection.addResourceBtn')}
</AppButton>
{activeMenu === menuTypes.resourcesMenu &&
renderMenu(resourcesMenuItems)}
</Box>
)}
</Box>
)
}

export default CourseSectionContainer
16 changes: 16 additions & 0 deletions src/containers/course-sections-list/CourseSectionsList.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import palette from '~/styles/app-theme/app.pallete'

export const styles = {
root: {
marginTop: '32px'
},
section: (isDragging: boolean) => ({
mb: '32px',
backgroundColor: 'basic.white',
borderRadius: '6px',
...(isDragging && {
boxShadow: `0px 3px 16px 2px ${palette.primary[300]}`,
border: `2px solid ${palette.primary[300]}`
})
})
}
Loading