feat: assignmentTask creation and switching

This commit is contained in:
swve 2024-07-13 20:03:08 +02:00
parent 6a4e16ec29
commit acfcea026b
9 changed files with 354 additions and 55 deletions

View file

@ -0,0 +1,77 @@
import { useLHSession } from '@components/Contexts/LHSessionContext';
import { getAPIUrl } from '@services/config/config';
import { createAssignmentTask } from '@services/courses/assignments'
import { AArrowUp, FileUp, ListTodo } from 'lucide-react'
import React from 'react'
import toast from 'react-hot-toast';
import { mutate } from 'swr';
function NewTaskModal({ closeModal, assignment_uuid }: any) {
const session = useLHSession() as any;
const access_token = session?.data?.tokens?.access_token;
const reminderShownRef = React.useRef(false);
function showReminderToast() {
// Check if the reminder has already been shown using sessionStorage
if (sessionStorage.getItem("TasksReminderShown") !== "true") {
setTimeout(() => {
toast('When editing/adding your tasks, make sure to Unpublish your Assignment to avoid any issues with students, you can Publish it again when you are ready.',
{ icon: '✋', duration: 10000, style: { minWidth: 600 } });
// Mark the reminder as shown in sessionStorage
sessionStorage.setItem("TasksReminderShown", "true");
}, 3000);
}
}
async function createTask(type: string) {
const task_object = {
title: "Untitled Task",
description: "",
hint: "",
reference_file: "",
assignment_type: type,
contents: {},
max_grade_value: 100,
}
await createAssignmentTask(task_object, assignment_uuid, access_token)
toast.success('Task created successfully')
showReminderToast()
mutate(`${getAPIUrl()}assignments/${assignment_uuid}/tasks`)
closeModal(false)
}
return (
<div className='flex space-x-6 mx-auto justify-center items-center'>
<div
onClick={() => createTask('QUIZ')}
className='flex flex-col space-y-2 justify-center text-center pt-10'>
<div className='px-5 py-5 rounded-full nice-shadow w-fit mx-auto bg-gray-100/50 text-gray-500 cursor-pointer hover:bg-gray-100 transition-all ease-linear'>
<ListTodo size={30} />
</div>
<p className='text-xl text-gray-700 font-semibold'>Quiz</p>
<p className='text-sm text-gray-500 w-40'>Questions with multiple choice answers</p>
</div>
<div
onClick={() => createTask('FILE_SUBMISSION')}
className='flex flex-col space-y-2 justify-center text-center pt-10'>
<div className='px-5 py-5 rounded-full nice-shadow w-fit mx-auto bg-gray-100/50 text-gray-500 cursor-pointer hover:bg-gray-100 transition-all ease-linear'>
<FileUp size={30} />
</div>
<p className='text-xl text-gray-700 font-semibold'>File submissions</p>
<p className='text-sm text-gray-500 w-40'>Students can submit files for this task</p>
</div>
<div
onClick={() => toast.error('Forms are not yet supported')}
className='flex flex-col space-y-2 justify-center text-center pt-10 opacity-25'>
<div className='px-5 py-5 rounded-full nice-shadow w-fit mx-auto bg-gray-100/50 text-gray-500 cursor-pointer hover:bg-gray-100 transition-all ease-linear'>
<AArrowUp size={30} />
</div>
<p className='text-xl text-gray-700 font-semibold'>Forms</p>
<p className='text-sm text-gray-500 w-40'>Forms for students to fill out</p>
</div>
</div>
)
}
export default NewTaskModal

View file

@ -1,30 +1,52 @@
'use client';
import { Info, Link } from 'lucide-react'
import React from 'react'
import { useAssignmentsTask } from '@components/Contexts/Assignments/AssignmentsTaskContext';
import { Info, TentTree } from 'lucide-react'
import React, { useEffect } from 'react'
function AssignmentTaskEditor({ task_uuid, page }: any) {
function AssignmentTaskEditor({ page }: any) {
const [selectedSubPage, setSelectedSubPage] = React.useState(page)
const assignmentTaskState = useAssignmentsTask() as any
useEffect(() => {
console.log(assignmentTaskState)
}
, [assignmentTaskState])
return (
<div className="flex flex-col font-black text-sm w-full z-20">
<div className='flex flex-col bg-white pl-10 pr-10 text-sm tracking-tight z-10 shadow-[0px_4px_16px_rgba(0,0,0,0.06)] pt-5'>
<div className='font-semibold text-lg py-1'>
Assignment Test #1
</div>
<div className='flex space-x-2 '>
<div
className={`flex space-x-4 py-2 w-fit text-center border-black transition-all ease-linear ${selectedSubPage === 'overview'
? 'border-b-4'
: 'opacity-50'
} cursor-pointer`}
>
<div className="flex items-center space-x-2.5 mx-2">
<Info size={16} />
<div>Overview</div>
{assignmentTaskState.assignmentTask && Object.keys(assignmentTaskState.assignmentTask).length > 0 && (
<div className='flex flex-col bg-white pl-10 pr-10 text-sm tracking-tight z-10 shadow-[0px_4px_16px_rgba(0,0,0,0.06)] pt-5'>
<div className='font-semibold text-lg py-1'>
Assignment Test #1
</div>
<div className='flex space-x-2 '>
<div
className={`flex space-x-4 py-2 w-fit text-center border-black transition-all ease-linear ${selectedSubPage === 'overview'
? 'border-b-4'
: 'opacity-50'
} cursor-pointer`}
>
<div className="flex items-center space-x-2.5 mx-2">
<Info size={16} />
<div>Overview</div>
</div>
</div>
</div>
</div>
</div>
)}
{Object.keys(assignmentTaskState.assignmentTask).length == 0 && (
<div className='flex flex-col h-full bg-white pl-10 pr-10 text-sm tracking-tight z-10 shadow-[0px_4px_16px_rgba(0,0,0,0.06)] pt-5'>
<div className='flex justify-center items-center h-full text-gray-300 antialiased'>
<div className='flex flex-col space-y-2 items-center'>
<TentTree size={60} />
<div className='font-semibold text-2xl py-1'>
No Task Selected
</div>
</div>
</div>
</div>
)}
</div>
)
}

View file

@ -1,12 +1,20 @@
import { useAssignments } from '@components/Contexts/Assignments/AssignmentContext'
import { Plus } from 'lucide-react';
import Modal from '@components/StyledElements/Modal/Modal';
import { FileUp, ListTodo, PanelLeftOpen, Plus } from 'lucide-react';
import React, { useEffect } from 'react'
import NewTaskModal from './Modals/NewTaskModal';
import { useAssignmentsTaskDispatch } from '@components/Contexts/Assignments/AssignmentsTaskContext';
function AssignmentTasks() {
function AssignmentTasks({ assignment_uuid }: any) {
const assignments = useAssignments() as any;
const assignmentTaskHook = useAssignmentsTaskDispatch() as any;
const [isNewTaskModalOpen, setIsNewTaskModalOpen] = React.useState(false)
async function setSelectTask(task_uuid: string) {
assignmentTaskHook({ type: 'setSelectedAssignmentTaskUUID', payload: task_uuid })
}
useEffect(() => {
console.log(assignments)
}, [assignments])
@ -15,19 +23,47 @@ function AssignmentTasks() {
<div className='flex flex-col space-y-3 mx-auto'>
{assignments && assignments?.assignment_tasks?.map((task: any) => {
return (
<div key={task.id} className='flex flex-col w-[250px] nice-shadow bg-white shadow-[0px_4px_16px_rgba(0,0,0,0.06)] p-3 rounded-md'>
<div className='flex justify-between px-2'>
<div className='font-semibold text-sm'>{task.title}</div>
<div
key={task.id}
className='flex flex-col w-[250px] nice-shadow bg-white shadow-[0px_4px_16px_rgba(0,0,0,0.06)] p-3 rounded-md'
onClick={() => setSelectTask(task.assignment_task_uuid)}
>
<div className='flex items-center px-2 justify-between'>
<div className="flex space-x-3 items-center">
<div className='text-gray-500'>
{task.assignment_type === 'QUIZ' && <ListTodo size={15} />}
{task.assignment_type === 'FILE_SUBMISSION' && <FileUp size={15} />}
</div>
<div className='font-semibold text-sm'>{task.title}</div>
</div>
<button className="outline outline-1 outline-gray-200 hover:bg-slate-100/50 rounded-md text-gray-500 font-bold py-2 px-3 focus:bg-slate-100 ease-linear transition-all">
<PanelLeftOpen size={16} />
</button>
</div>
</div>
)
})}
<div className='flex space-x-1.5 px-2 py-2 bg-black text-white text-xs rounded-md antialiased items-center font-semibold cursor-pointer'>
<Plus size={17} />
<p>Add Task</p>
</div>
<Modal
isDialogOpen={isNewTaskModalOpen}
onOpenChange={setIsNewTaskModalOpen}
minHeight="sm"
minWidth='sm'
dialogContent={
<NewTaskModal assignment_uuid={assignment_uuid} closeModal={setIsNewTaskModalOpen} />
}
dialogTitle="Add an Assignment Task"
dialogDescription="Create a new task for this assignment"
dialogTrigger={
<div className='flex space-x-1.5 px-2 py-2 justify-center bg-black text-white text-xs rounded-md antialiased items-center font-semibold cursor-pointer'>
<Plus size={17} />
<p>Add Task</p>
</div>
}
/>
</div>
</div>
)
}

View file

@ -1,12 +1,13 @@
'use client';
import BreadCrumbs from '@components/Dashboard/UI/BreadCrumbs'
import AuthenticatedClientElement from '@components/Security/AuthenticatedClientElement'
import { BookOpen, BookOpenCheck, BookX, Check, Ellipsis, EllipsisVertical, GalleryVerticalEnd, Info, LayoutList, UserRoundCog } from 'lucide-react'
import { BookOpen, BookX, EllipsisVertical, LayoutList } from 'lucide-react'
import React from 'react'
import AssignmentTaskEditor from './_components/TaskEditor';
import { AssignmentProvider } from '@components/Contexts/Assignments/AssignmentContext';
import AssignmentTasks from './_components/Tasks';
import { useParams } from 'next/navigation';
import { AssignmentsTaskProvider } from '@components/Contexts/Assignments/AssignmentsTaskContext';
import ToolTip from '@components/StyledElements/Tooltip/Tooltip';
function AssignmentEdit() {
const params = useParams<{ assignmentuuid: string; }>()
@ -24,33 +25,47 @@ function AssignmentEdit() {
<div className='flex mx-auto mt-5 items-center space-x-4'>
<div className='flex bg-green-200/60 text-xs rounded-full px-3.5 py-2 mx-auto font-bold outline outline-1 outline-green-300'>Published</div>
<div><EllipsisVertical className='text-gray-500' size={13} /></div>
<div className='flex px-3 py-2 cursor-pointer rounded-md space-x-2 items-center bg-gradient-to-bl text-green-800 font-medium from-green-400/50 to-lime-200/80 border border-green-600/10 shadow-green-900/10 shadow-lg'>
<BookOpen size={18} />
<p className=' text-sm font-bold'>Publish</p>
</div>
<ToolTip
side='left'
slateBlack
sideOffset={10}
content="Make your Assignment public and available for students" >
<div className='flex px-3 py-2 cursor-pointer rounded-md space-x-2 items-center bg-gradient-to-bl text-green-800 font-medium from-green-400/50 to-lime-200/80 border border-green-600/10 shadow-green-900/10 shadow-lg'>
<BookOpen size={18} />
<p className=' text-sm font-bold'>Publish</p>
</div>
</ToolTip>
<ToolTip
side='left'
slateBlack
sideOffset={10}
content="Make your Assignment unavailable for students" >
<div className='flex px-3 py-2 cursor-pointer rounded-md space-x-2 items-center bg-gradient-to-bl text-gray-800 font-medium from-gray-400/50 to-gray-200/80 border border-gray-600/10 shadow-gray-900/10 shadow-lg'>
<BookX size={18} />
<p className='text-sm font-bold'>Unpublish</p>
</div>
</ToolTip>
</div>
</div>
</div>
</div>
<div className="flex w-full">
<div className='flex w-[400px] flex-col h-screen custom-dots-bg'>
<div className='flex mx-auto px-3.5 py-1 bg-neutral-600/80 space-x-2 my-5 items-center text-sm font-bold text-white rounded-full'>
<LayoutList size={18} />
<p>Tasks</p>
<div className="flex h-full w-full">
<AssignmentsTaskProvider>
<div className='flex w-[400px] flex-col h-full custom-dots-bg'>
<div className='flex mx-auto px-3.5 py-1 bg-neutral-600/80 space-x-2 my-5 items-center text-sm font-bold text-white rounded-full'>
<LayoutList size={18} />
<p>Tasks</p>
</div>
<AssignmentProvider assignment_uuid={'assignment_' + params.assignmentuuid}>
<AssignmentTasks assignment_uuid={'assignment_' + params.assignmentuuid} />
</AssignmentProvider>
</div>
<AssignmentProvider assignment_uuid='assignment_a35fdbb9-11bd-40cf-a781-f6bdd5d87165'>
<AssignmentTasks />
</AssignmentProvider>
</div>
<div className='flex flex-grow bg-[#fefcfe] nice-shadow h-screen w-full'>
<AssignmentProvider assignment_uuid={'assignment_' + params.assignmentuuid}>
<AssignmentTaskEditor task_uuid='UUID' page='overview' />
</AssignmentProvider>
</div>
<div className='flex flex-grow bg-[#fefcfe] nice-shadow h-full w-full'>
<AssignmentProvider assignment_uuid={'assignment_' + params.assignmentuuid}>
<AssignmentTaskEditor task_uuid='UUID' page='overview' />
</AssignmentProvider>
</div>
</AssignmentsTaskProvider>
</div>
</div>
)