Skip to content

Commit

Permalink
Merge branch 'v3' into course-deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
sjschlapbach authored Oct 2, 2024
2 parents f6279f5 + 7c84a59 commit b02b5d4
Show file tree
Hide file tree
Showing 20 changed files with 637 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { useMutation } from '@apollo/client'
import { faHandPointer, faTrashCan } from '@fortawesome/free-regular-svg-icons'
import {
faCalendar,
faHandPointer,
faTrashCan,
} from '@fortawesome/free-regular-svg-icons'
import {
faArrowsRotate,
faCheck,
Expand All @@ -25,11 +29,12 @@ import dayjs from 'dayjs'
import { useTranslations } from 'next-intl'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useState } from 'react'
import React, { useState } from 'react'
import { WizardMode } from '../sessions/creation/ElementCreation'
import StatusTag from './StatusTag'
import PublishGroupActivityButton from './actions/PublishGroupActivityButton'
import DeletionModal from './modals/DeletionModal'
import ExtensionModal from './modals/ExtensionModal'

interface GroupActivityElementProps {
groupActivity: Partial<GroupActivity> & Pick<GroupActivity, 'id' | 'name'>
Expand All @@ -44,6 +49,7 @@ function GroupActivityElement({
const router = useRouter()

const [deletionModal, setDeletionModal] = useState(false)
const [extensionModal, setExtensionModal] = useState(false)
const isFuture = dayjs(groupActivity.scheduledStartAt).isAfter(dayjs())
const isPast = dayjs(groupActivity.scheduledEndAt).isBefore(dayjs())

Expand Down Expand Up @@ -267,6 +273,20 @@ function GroupActivityElement({
</div>
</Button>
)}
{!isPast && !isFuture && (
<Button
onClick={() => setExtensionModal(true)}
data={{
cy: `extend-groupActivity-${groupActivity.name}`,
}}
basic
>
<div className="text-primary-100 flex cursor-pointer flex-row items-center gap-1">
<FontAwesomeIcon icon={faCalendar} className="w-[1.1rem]" />
<div>{t('manage.course.extendGroupActivity')}</div>
</div>
</Button>
)}
</>
)}
</div>
Expand All @@ -286,6 +306,16 @@ function GroupActivityElement({
primaryData={{ cy: 'confirm-delete-groupActivity' }}
secondaryData={{ cy: 'cancel-delete-groupActivity' }}
/>
<ExtensionModal
type="groupActivity"
id={groupActivity.id}
currentEndDate={groupActivity.scheduledEndAt}
courseId={courseId}
title={t('manage.course.extendGroupActivity')}
description={t('manage.course.extendGroupActivityDescription')}
open={extensionModal}
setOpen={setExtensionModal}
/>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { useMutation, useQuery } from '@apollo/client'
import { faClock, faTrashCan } from '@fortawesome/free-regular-svg-icons'
import {
faCalendar,
faClock,
faTrashCan,
} from '@fortawesome/free-regular-svg-icons'
import {
faArrowsRotate,
faCheck,
Expand All @@ -24,7 +28,7 @@ import { Dropdown } from '@uzh-bf/design-system'
import dayjs from 'dayjs'
import { useTranslations } from 'next-intl'
import { useRouter } from 'next/router'
import { useState } from 'react'
import React, { useState } from 'react'
import { WizardMode } from '../sessions/creation/ElementCreation'
import CopyConfirmationToast from '../toasts/CopyConfirmationToast'
import { getAccessLink, getLTIAccessLink } from './PracticeQuizElement'
Expand All @@ -34,6 +38,7 @@ import MicroLearningEvaluationLink from './actions/MicroLearningEvaluationLink'
import PublishMicroLearningButton from './actions/PublishMicroLearningButton'
import getActivityDuplicationAction from './actions/getActivityDuplicationAction'
import DeletionModal from './modals/DeletionModal'
import ExtensionModal from './modals/ExtensionModal'

interface MicroLearningElementProps {
microLearning: Pick<
Expand All @@ -56,6 +61,7 @@ function MicroLearningElement({
const router = useRouter()
const [copyToast, setCopyToast] = useState(false)
const [deletionModal, setDeletionModal] = useState(false)
const [extensionModal, setExtensionModal] = useState(false)

const { data: dataUser } = useQuery(UserProfileDocument, {
fetchPolicy: 'cache-only',
Expand All @@ -65,6 +71,7 @@ function MicroLearningElement({
const evaluationHref = `/microLearning/${microLearning.id}/evaluation`
const isFuture = dayjs(microLearning.scheduledStartAt).isAfter(dayjs())
const isPast = dayjs(microLearning.scheduledEndAt).isBefore(dayjs())
const isActive = !isFuture && !isPast

const [unpublishMicroLearning] = useMutation(UnpublishMicroLearningDocument, {
variables: { id: microLearning.id },
Expand Down Expand Up @@ -206,10 +213,7 @@ function MicroLearningElement({
{
label: (
<div className="flex cursor-pointer flex-row items-center gap-1 text-red-600">
<FontAwesomeIcon
icon={faTrashCan}
className="w-[1.1rem]"
/>
<FontAwesomeIcon icon={faTrashCan} className="w-4" />
<div>{t('manage.course.deleteMicrolearning')}</div>
</div>
),
Expand Down Expand Up @@ -271,16 +275,33 @@ function MicroLearningElement({
cy: `duplicate-microlearning-${microLearning.name}`,
},
}),
...(isFuture
...(isActive
? [
{
label: (
<div className="flex cursor-pointer flex-row items-center gap-1 text-red-600">
<div className="text-primary-100 flex cursor-pointer flex-row items-center gap-1">
<FontAwesomeIcon
icon={faLock}
className="w-[1.1rem]"
icon={faCalendar}
className="w-4"
/>

<div>
{t('manage.course.extendMicroLearning')}
</div>
</div>
),
onClick: () => setExtensionModal(true),
data: {
cy: `extend-microlearning-${microLearning.name}`,
},
},
]
: []),
...(isFuture
? [
{
label: (
<div className="flex cursor-pointer flex-row items-center gap-1 text-red-600">
<FontAwesomeIcon icon={faLock} className="w-4" />
<div>
{t('manage.course.unpublishMicrolearning')}
</div>
Expand Down Expand Up @@ -343,6 +364,16 @@ function MicroLearningElement({
primaryData={{ cy: 'confirm-delete-microlearning' }}
secondaryData={{ cy: 'cancel-delete-microlearning' }}
/>
<ExtensionModal
type="microLearning"
id={microLearning.id}
currentEndDate={microLearning.scheduledEndAt}
courseId={courseId}
title={t('manage.course.extendMicroLearning')}
description={t('manage.course.extendMicroLearningDescription')}
open={extensionModal}
setOpen={setExtensionModal}
/>
</div>
)
}
Expand Down
148 changes: 148 additions & 0 deletions apps/frontend-manage/src/components/courses/modals/ExtensionModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { useMutation } from '@apollo/client'
import {
ExtendGroupActivityDocument,
ExtendMicroLearningDocument,
GetSingleCourseDocument,
} from '@klicker-uzh/graphql/dist/ops'
import { Button, FormikDateField, Modal } from '@uzh-bf/design-system'
import dayjs from 'dayjs'
import { Form, Formik } from 'formik'
import { useTranslations } from 'next-intl'
import { twMerge } from 'tailwind-merge'
import * as Yup from 'yup'

interface ExtensionModalProps {
type: 'microLearning' | 'groupActivity'
id: string
currentEndDate: Date
courseId: string
title: string
description: string
open: boolean
setOpen: (value: boolean) => void
}

function ExtensionModal({
type,
id,
currentEndDate,
courseId,
title,
description,
open,
setOpen,
}: ExtensionModalProps) {
const t = useTranslations()
const [extendMicroLearning] = useMutation(ExtendMicroLearningDocument, {
refetchQueries: [
{ query: GetSingleCourseDocument, variables: { courseId: courseId } },
],
})
const [extendGroupActivity] = useMutation(ExtendGroupActivityDocument, {
refetchQueries: [
{ query: GetSingleCourseDocument, variables: { courseId: courseId } },
],
})

return (
<Modal
onClose={(): void => setOpen(false)}
open={open}
hideCloseButton={true}
title={title}
className={{
content: 'h-max min-h-max w-[40rem] self-center !pb-0',
title: 'text-xl',
}}
>
<div className="space-y-3" data-cy="activity-extension-modal">
<div>{description}</div>
<Formik
initialValues={{
endDate: dayjs(currentEndDate).local().format('YYYY-MM-DDTHH:mm'),
}}
validationSchema={Yup.object().shape({
endDate: Yup.date()
.required()
.min(new Date(), t('manage.course.futureEndDateRequired')),
})}
onSubmit={async (values, { setSubmitting }) => {
const utcEndDate = dayjs(values.endDate).utc().format()
setSubmitting(true)

if (type === 'microLearning') {
await extendMicroLearning({
variables: {
id,
endDate: utcEndDate,
},
optimisticResponse: {
__typename: 'Mutation',
extendMicroLearning: {
__typename: 'MicroLearning',
id,
scheduledEndAt: utcEndDate,
},
},
})
} else if (type === 'groupActivity') {
await extendGroupActivity({
variables: {
id,
endDate: utcEndDate,
},
optimisticResponse: {
__typename: 'Mutation',
extendGroupActivity: {
__typename: 'GroupActivity',
id,
scheduledEndAt: utcEndDate,
},
},
})
}

setSubmitting(false)
setOpen(false)
}}
>
{({ isValid, isSubmitting }) => (
<Form>
<FormikDateField
required
name="endDate"
label={t('manage.course.newEndDate')}
labelType="large"
data={{ cy: 'extend-activity-date' }}
/>
<div className="mt-3 flex flex-row justify-between">
<Button
onClick={(): void => setOpen(false)}
data={{ cy: 'extend-activity-cancel' }}
>
{t('shared.generic.cancel')}
</Button>
<Button
type="submit"
loading={isSubmitting}
disabled={!isValid}
className={{
root: twMerge(
'bg-primary-100 font-bold text-white',
!isValid && 'bg-primary-40 cursor-not-allowed'
),
}}
data={{ cy: 'extend-activity-confirm' }}
>
{t('shared.generic.confirm')}
</Button>
</div>
</Form>
)}
</Formik>
</div>
</Modal>
)
}

export default ExtensionModal
Loading

0 comments on commit b02b5d4

Please sign in to comment.