Skip to content

Commit

Permalink
close cooperation process (#2900)
Browse files Browse the repository at this point in the history
* Add possibility for a student to close a cooperation

* add functionality to close cooperation

* add colors to palette

* add some tests

* add test for CooperationContainer

* one more test for CooperationContainer

* add one more test for CooperationCompletion

* removed onResponseError import

* add test for CooperationContainer

* implemented comments suggestions

* fixed test

* add test for handleCooperationStatusUpdate func

* delete unused test

* added useCallback and fixed translation

* changed || to ??

* fixed comments

* fixed tests
  • Loading branch information
nebby2105 authored Dec 4, 2024
1 parent 0999032 commit b2b6410
Show file tree
Hide file tree
Showing 21 changed files with 404 additions and 31 deletions.
3 changes: 2 additions & 1 deletion src/components/status-chip/StatusChip.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ const statusColors = {
[StatusEnum.Active]: palette.success[600],
[StatusEnum.Closed]: palette.primary[400],
[StatusEnum.Draft]: palette.basic.blue,
[StatusEnum.NeedAction]: palette.error[600]
[StatusEnum.NeedAction]: palette.error[600],
[StatusEnum.RequestToClose]: palette.warning[500]
}

export const styles = (status: StatusEnum) => ({
Expand Down
6 changes: 5 additions & 1 deletion src/constants/translations/en/cooperation-details.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,9 @@
"yourProgress": "Your progress",
"completed": "completed",
"needToComplete": "to complete"
}
},
"closingMessage1": " started a closing process for the current cooperation. You will have ",
"accessDuration": "1 month of access",
"closingMessage2": " to study materials after the cooperation has been closed.",
"acceptBtn": "Accept"
}
9 changes: 6 additions & 3 deletions src/constants/translations/en/cooperations-page.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@
"or": "or ",
"quizzes": "quizzes ",
"resourcesLibrary": "from resource library.",
"seems": "Looks like there’re",
"seems": "Looks like there’re",
"noActivities": " no activities added ",
"engageTutor": "yet. As a student, you're here to engage with the materials provided by your tutor."
},
"button": {
"create": "Create Activity",
"add":"Add Activity"
"add": "Add Activity"
},
"manyTypes": {
"courseTemplate": "Course template",
Expand All @@ -66,7 +66,7 @@
"closeCooperationDescription": "Start a closing process of current cooperation if your learning journey with the student is finished.",
"closeCooperationBtn": "Close cooperation",
"accessTitle": "Study materials access",
"accessDescription": "As a tutor, determine deadlines for student access to study materials after cooperation has finished.",
"accessDescription": "As a tutor, determine deadlines for student access to study materials after cooperation has finished.",
"noAccess": "No access",
"monthAccess": "month access",
"yearAccess": "year access",
Expand All @@ -83,5 +83,8 @@
"successUpdating": "Note was successfully updated",
"confirmDeletionMessage": "This action is permanent and will remove all related content. Please review your decision before proceeding.",
"confirmDeletionTitle": "Do you confirm note deletion?"
},
"closeCooperationModal": {
"message": "Are you sure you want to close this cooperation?"
}
}
4 changes: 3 additions & 1 deletion src/constants/translations/en/titles.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"confirmTitle": "Please Confirm",
"discardOffer": "Discard offer changes?",
"discardChanges": "Discard recent changes?"
"discardChanges": "Discard recent changes?",
"confirmCooperationClosing": "Confirmation of cooperation closing",
"acceptCooperationClosing": "Cooperation closing process"
}
6 changes: 5 additions & 1 deletion src/constants/translations/uk/cooperation-details.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,9 @@
"yourProgress": "Ваш прогрес",
"completed": "виконано",
"needToComplete": "до завершення"
}
},
"closingMessage1": " ініціював(-ла) процес припинення співпраці. У вас залишиться доступ до матеріалів поточної співпраці протягом ",
"accessDuration": "1 місяця",
"closingMessage2": " з моменту закриття.",
"acceptBtn": "Прийняти"
}
16 changes: 10 additions & 6 deletions src/constants/translations/uk/cooperations-page.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,24 @@
"or": "або ",
"quizzes": "тестами ",
"resourcesLibrary": "з бібліотеки ресурсів.",
"seems": "Схоже, що зараз тут ",
"seems": "Схоже, що зараз тут ",
"noActivities": " немає доданих активностей ",
"engageTutor": ". Як студента, Ваша задача - працювати з матеріалами, наданими Вашим викладачем." },
"engageTutor": ". Як студента, Ваша задача - працювати з матеріалами, наданими Вашим викладачем."
},
"button": {
"create": "Створення активності",
"add":"Додавання активності"
"add": "Додавання активності"
},
"manyTypes": {
"courseTemplate": "Шаблон курсу",
"scratch": "З нуля",
"module": "Модуль"
},
"cooperationDetails": {
"completionTitle": "Завершення кооперації",
"closeCooperationTitle": "Завершити кооперацію",
"completionTitle": "Завершення співпраці",
"closeCooperationTitle": "Завершити співпрацю",
"closeCooperationDescription": "Розпочніть процес завершення поточної співпраці, якщо ваше навчання зі студентом закінчилося.",
"closeCooperationBtn": "Завершити кооперацію",
"closeCooperationBtn": "Завершити співпрацю",
"accessTitle": "Доступ до навчальних матеріалів",
"accessDescription": "Визначте терміни доступу до навчальних матеріалів після завершення співпраці зі студентом.",
"noAccess": "Не має доступу",
Expand All @@ -83,5 +84,8 @@
"successUpdating": "Нотатку було успішно оновлено",
"confirmDeletionMessage": "Ця дія є постійною та призведе до видалення всього пов’язаного вмісту. Перш ніж продовжити, перегляньте своє рішення.",
"confirmDeletionTitle": "Ви підтверджуєте видалення нотатки?"
},
"closeCooperationModal": {
"message": "Ви впевнені, що хочете завершити співпрацю?"
}
}
4 changes: 3 additions & 1 deletion src/constants/translations/uk/titles.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"confirmTitle": "Підтвердіть вихід",
"discardOffer": "Відхилити зміни пропозиції?",
"discardChanges": "Зберегти останні зміни?"
"discardChanges": "Зберегти останні зміни?",
"confirmCooperationClosing": "Підтвердження припинення cпівпраці",
"acceptCooperationClosing": "Процес припинення співпраці"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import palette from '~/styles/app-theme/app.pallete'

export const styles = {
root: {
display: 'flex',
alignItems: 'center',
border: `1px solid ${palette.basic.pinkishRed}`,
backgroundColor: palette.basic.softGray,
borderRadius: '5px',
padding: '24px',
justifyContent: 'space-between',
gap: '16px'
},
span: {
fontWeight: '500'
},
title: {
color: palette.basic.mediumRed,
fontWeight: '500',
display: 'flex',
gap: '8px',
mb: '4px'
},
body: {
color: palette.basic.darkGray
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Box, styled, Typography } from '@mui/material'
import { FC } from 'react'
import { styles } from './AcceptCooperationClosing.styles'
import { ErrorOutlineRounded } from '@mui/icons-material'
import Button from '~/design-system/components/button/Button'
import { useTranslation } from 'react-i18next'

interface AcceptCooperationClosureProps {
user: string
onAccept: () => void
}

const BoldText = styled('span')({
fontWeight: 500
})

const AcceptCooperationClosing: FC<AcceptCooperationClosureProps> = ({
user,
onAccept
}) => {
const { t } = useTranslation()
return (
<Box sx={styles.root}>
<Box>
<Box sx={styles.title}>
<ErrorOutlineRounded />
<Typography>{t('titles.acceptCooperationClosing')}</Typography>
</Box>
<Typography sx={styles.body}>
<BoldText>{user}</BoldText>
{t('cooperationDetailsPage.closingMessage1')}
<BoldText>{t('cooperationDetailsPage.accessDuration')}</BoldText>
{t('cooperationDetailsPage.closingMessage2')}
</Typography>
</Box>
<Button color='tonal-error' onClick={onAccept} size='xs'>
{t('cooperationDetailsPage.acceptBtn')}
</Button>
</Box>
)
}

export default AcceptCooperationClosing
Original file line number Diff line number Diff line change
@@ -1,16 +1,38 @@
import { 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 SettingItem from '~/components/setting-item/SettingItem'
import AppButton from '~/components/app-button/AppButton'
import AppSelect from '~/components/app-select/AppSelect'

import { cooperationAccessValues } from '~/containers/my-cooperations/cooperation-completion/CooperationCompletion.constants'
import { styles } from '~/containers/my-cooperations/cooperation-completion/CooperationCompletion.styles'
import { ButtonVariantEnum, SizeEnum } from '~/types'
import {
ButtonVariantEnum,
SizeEnum,
CooperationMaterialsAccessEnum,
UserRoleEnum,
StatusEnum
} from '~/types'
interface CooperationCompletionProps {
cooperationStatus: StatusEnum
onCloseCooperation: () => void
userRole: UserRoleEnum | ''
}

const CooperationCompletion = () => {
const CooperationCompletion: React.FC<CooperationCompletionProps> = ({
cooperationStatus,
onCloseCooperation,
userRole
}) => {
const { t } = useTranslation()
const [materialsAccess, setMaterialsAccess] =
useState<CooperationMaterialsAccessEnum>(
CooperationMaterialsAccessEnum.OneMonthAccess
)

return (
<Box>
Expand All @@ -25,13 +47,29 @@ const CooperationCompletion = () => {
title={t('cooperationsPage.cooperationDetails.closeCooperationTitle')}
>
<AppButton
data-testid='close-cooperation-btn'
disabled={cooperationStatus !== StatusEnum.Active}
onClick={onCloseCooperation}
size={SizeEnum.Medium}
sx={styles.closeBtn}
variant={ButtonVariantEnum.Text}
>
{t('cooperationsPage.cooperationDetails.closeCooperationBtn')}
</AppButton>
</SettingItem>
{userRole === UserRoleEnum.Tutor && (
<SettingItem
subtitle={t('cooperationsPage.cooperationDetails.accessDescription')}
title={t('cooperationsPage.cooperationDetails.accessTitle')}
>
<AppSelect
fields={cooperationAccessValues(t)}
setValue={setMaterialsAccess}
sx={styles.dropdown}
value={materialsAccess}
/>
</SettingItem>
)}
</Box>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,16 @@ import {
PositionEnum,
Cooperation,
SizeEnum,
ButtonVariantEnum
ButtonVariantEnum,
StatusEnum
} from '~/types'
import {
cooperationsSelector,
setCooperationSections,
setCooperationStatus,
setIsActivityCreated
} from '~/redux/features/cooperationsSlice'
import AcceptCooperationClosing from '~/containers/my-cooperations/accept-cooperation-close/AcceptCooperationClosing'

const CooperationDetails = () => {
const dispatch = useAppDispatch()
Expand All @@ -54,6 +57,9 @@ const CooperationDetails = () => {
const { isActivityCreated } = useAppSelector(cooperationsSelector)
const [isNotesOpen, setIsNotesOpen] = useState<boolean>(false)
const [editMode, setEditMode] = useState<boolean>(false)
const [isClosed, setIsClosed] = useState<boolean>(false)
const { userRole } = useAppSelector((state) => state.appMain)
const cooperationStatus = useAppSelector((state) => state.cooperations.status)

const [searchParams, setSearchParams] = useSearchParams()

Expand Down Expand Up @@ -88,14 +94,28 @@ const CooperationDetails = () => {

useEffect(() => {
dispatch(setCooperationSections(response.sections))
dispatch(setCooperationStatus(response.status))
setEditMode(Boolean(response?.sections?.length))
}, [response.sections, dispatch])
}, [response.sections, response.status, dispatch])

const handleEditMode = useCallback(() => {
setEditMode((prev) => !prev)
dispatch(setIsActivityCreated(true))
}, [dispatch])

const handleCooperationStatusUpdate = useCallback(async () => {
await cooperationService.updateCooperation({
_id: id,
status: StatusEnum.Closed
})
setIsClosed(true)
dispatch(setCooperationStatus(StatusEnum.Closed))
}, [id, dispatch])

const handleCooperationCloseAccept = useCallback(() => {
void handleCooperationStatusUpdate()
}, [handleCooperationStatusUpdate])

if (loading) {
return <Loader pageLoad />
}
Expand Down Expand Up @@ -132,6 +152,22 @@ const CooperationDetails = () => {
return cooperationContent
}

const closeCooperationInitiator =
response.needAction === response.receiverRole
? response.initiator
: response.receiver

const acceptClosingProcess = !isClosed && (
<AcceptCooperationClosing
onAccept={handleCooperationCloseAccept}
user={closeCooperationInitiator.firstName}
/>
)

const isCooperationClosingRequestSend =
response.needAction === userRole &&
response.status === StatusEnum.RequestToClose

const iconConditionals = isNotesOpen ? (
<KeyboardDoubleArrowRightIcon />
) : (
Expand All @@ -141,7 +177,7 @@ const CooperationDetails = () => {
return (
<PageWrapper>
<Box sx={styles.header}>
<StatusChip status={response.status} />
<StatusChip status={cooperationStatus} />
<TitleWithDescription
key={crypto.randomUUID()}
style={styles.cooperationTitle}
Expand All @@ -167,6 +203,9 @@ const CooperationDetails = () => {
</AppButton>
</Box>
</Box>
{activeTab === CooperationTabsEnum.Activities &&
isCooperationClosingRequestSend &&
acceptClosingProcess}
<Box sx={styles.notesBlock}>
<Box sx={styles.pageContent}>{pageContent()}</Box>
{!isDesktop && isNotesOpen && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ const CooperationContainer: FC<CooperationContainerProps> = ({
/>
)
})
: item.status === StatusEnum.Active &&
navigate(`./${item._id}?tab=activities`)
: (item.status === StatusEnum.Active ||
item.status === StatusEnum.RequestToClose) &&
navigate(`./${item._id}`)
}

const cooperationGrid = (
Expand Down
Loading

0 comments on commit b2b6410

Please sign in to comment.