mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: full quiz tasks edition and creation
This commit is contained in:
parent
aa55c51b48
commit
175a5a97fa
8 changed files with 453 additions and 144 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import { useAssignmentsTaskDispatch } from '@components/Contexts/Assignments/AssignmentsTaskContext';
|
||||
import { useLHSession } from '@components/Contexts/LHSessionContext';
|
||||
import { getAPIUrl } from '@services/config/config';
|
||||
import { createAssignmentTask } from '@services/courses/assignments'
|
||||
|
|
@ -10,6 +11,7 @@ function NewTaskModal({ closeModal, assignment_uuid }: any) {
|
|||
const session = useLHSession() as any;
|
||||
const access_token = session?.data?.tokens?.access_token;
|
||||
const reminderShownRef = React.useRef(false);
|
||||
const assignmentTaskStateHook = useAssignmentsTaskDispatch() as any
|
||||
|
||||
function showReminderToast() {
|
||||
// Check if the reminder has already been shown using sessionStorage
|
||||
|
|
@ -33,10 +35,11 @@ function NewTaskModal({ closeModal, assignment_uuid }: any) {
|
|||
contents: {},
|
||||
max_grade_value: 100,
|
||||
}
|
||||
await createAssignmentTask(task_object, assignment_uuid, access_token)
|
||||
const res = await createAssignmentTask(task_object, assignment_uuid, access_token)
|
||||
toast.success('Task created successfully')
|
||||
showReminderToast()
|
||||
mutate(`${getAPIUrl()}assignments/${assignment_uuid}/tasks`)
|
||||
assignmentTaskStateHook({ type: 'setSelectedAssignmentTaskUUID', payload: res.data.assignment_task_uuid })
|
||||
closeModal(false)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
import { useAssignments } from '@components/Contexts/Assignments/AssignmentContext';
|
||||
import { useAssignmentsTask, useAssignmentsTaskDispatch } from '@components/Contexts/Assignments/AssignmentsTaskContext';
|
||||
import { useLHSession } from '@components/Contexts/LHSessionContext';
|
||||
import React, { useEffect } from 'react'
|
||||
import TaskQuizObject from './TaskTypes/TaskQuizObject';
|
||||
|
||||
function AssignmentTaskContentEdit() {
|
||||
const session = useLHSession() as any;
|
||||
const access_token = session?.data?.tokens?.access_token;
|
||||
const assignmentTaskStateHook = useAssignmentsTaskDispatch() as any
|
||||
const assignment = useAssignments() as any
|
||||
|
||||
useEffect(() => {
|
||||
}
|
||||
, [assignment, assignmentTaskStateHook])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<TaskQuizObject />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AssignmentTaskContentEdit
|
||||
|
|
@ -16,103 +16,7 @@ import React, { use, useEffect } from 'react'
|
|||
import toast from 'react-hot-toast';
|
||||
import { mutate } from 'swr';
|
||||
|
||||
function AssignmentTaskEditor({ page }: any) {
|
||||
const [selectedSubPage, setSelectedSubPage] = React.useState(page)
|
||||
const assignment = useAssignments() as any
|
||||
const assignmentTaskState = useAssignmentsTask() as any
|
||||
const assignmentTaskStateHook = useAssignmentsTaskDispatch() as any
|
||||
const session = useLHSession() as any;
|
||||
const access_token = session?.data?.tokens?.access_token;
|
||||
|
||||
async function deleteTaskUI() {
|
||||
const res = await deleteAssignmentTask(assignmentTaskState.assignmentTask.assignment_task_uuid, assignment.assignment_object.assignment_uuid, access_token)
|
||||
if (res) {
|
||||
assignmentTaskStateHook({
|
||||
type: 'SET_MULTIPLE_STATES',
|
||||
payload: {
|
||||
selectedAssignmentTaskUUID: null,
|
||||
assignmentTask: {},
|
||||
},
|
||||
});
|
||||
mutate(`${getAPIUrl()}assignments/${assignment.assignment_object.assignment_uuid}/tasks`)
|
||||
toast.success('Task deleted successfully')
|
||||
} else {
|
||||
toast.error('Error deleting task, please retry later.')
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
}
|
||||
, [assignmentTaskState,assignmentTaskStateHook])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col font-black text-sm w-full z-20">
|
||||
{assignmentTaskState.assignmentTask && Object.keys(assignmentTaskState.assignmentTask).length > 0 && (
|
||||
<div className='flex flex-col space-y-3'>
|
||||
<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 mb-3 nice-shadow'>
|
||||
<div className='flex py-1 justify-between items-center'>
|
||||
<div className='font-semibold text-lg '>
|
||||
{assignmentTaskState?.assignmentTask.title}
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
onClick={() => deleteTaskUI()}
|
||||
className='flex px-2 py-1.5 cursor-pointer rounded-md space-x-2 items-center bg-gradient-to-bl text-red-800 bg-rose-100 border border-rose-600/10 shadow-rose-900/10 shadow-lg'>
|
||||
<Trash size={18} />
|
||||
<p className='text-xs font-semibold'>Delete Task</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex space-x-2 '>
|
||||
<div
|
||||
onClick={() => setSelectedSubPage('general')}
|
||||
className={`flex space-x-4 py-2 w-fit text-center border-black transition-all ease-linear ${selectedSubPage === 'general'
|
||||
? 'border-b-4'
|
||||
: 'opacity-50'
|
||||
} cursor-pointer`}
|
||||
>
|
||||
<div className="flex items-center space-x-2.5 mx-2">
|
||||
<Info size={16} />
|
||||
<div>General</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => setSelectedSubPage('content')}
|
||||
className={`flex space-x-4 py-2 w-fit text-center border-black transition-all ease-linear ${selectedSubPage === 'content'
|
||||
? 'border-b-4'
|
||||
: 'opacity-50'
|
||||
} cursor-pointer`}
|
||||
>
|
||||
<div className="flex items-center space-x-2.5 mx-2">
|
||||
<GalleryVerticalEnd size={16} />
|
||||
<div>Content</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='ml-10 mr-10 mt-10 mx-auto bg-white rounded-xl shadow-sm px-6 py-5 nice-shadow'>
|
||||
{selectedSubPage === 'general' && <AssignmentTaskGeneralEdit />}
|
||||
</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>
|
||||
)
|
||||
}
|
||||
|
||||
function AssignmentTaskGeneralEdit() {
|
||||
export function AssignmentTaskGeneralEdit() {
|
||||
const session = useLHSession() as any;
|
||||
const access_token = session?.data?.tokens?.access_token;
|
||||
const assignmentTaskState = useAssignmentsTask() as any
|
||||
|
|
@ -127,8 +31,6 @@ function AssignmentTaskGeneralEdit() {
|
|||
return errors;
|
||||
};
|
||||
|
||||
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
title: assignmentTaskState.assignmentTask.title,
|
||||
|
|
@ -373,6 +275,4 @@ function UpdateTaskRef() {
|
|||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AssignmentTaskEditor
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
import { useAssignments } from '@components/Contexts/Assignments/AssignmentContext';
|
||||
import { useAssignmentsTask, useAssignmentsTaskDispatch } from '@components/Contexts/Assignments/AssignmentsTaskContext';
|
||||
import { useLHSession } from '@components/Contexts/LHSessionContext';
|
||||
import AssignmentBoxUI from '@components/Objects/Assignments/AssignmentBoxUI';
|
||||
import { updateAssignmentTask } from '@services/courses/assignments';
|
||||
import { Check, Minus, Plus, PlusCircle, X } from 'lucide-react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
type QuizSchema = {
|
||||
questionText: string;
|
||||
questionUUID?: string;
|
||||
options: {
|
||||
optionUUID?: string;
|
||||
text: string;
|
||||
fileID: string;
|
||||
type: 'text' | 'image' | 'audio' | 'video';
|
||||
correct: boolean;
|
||||
}[];
|
||||
};
|
||||
|
||||
function TaskQuizObject() {
|
||||
const session = useLHSession() as any;
|
||||
const access_token = session?.data?.tokens?.access_token;
|
||||
const assignmentTaskState = useAssignmentsTask() as any;
|
||||
const assignmentTaskStateHook = useAssignmentsTaskDispatch() as any;
|
||||
const assignment = useAssignments() as any;
|
||||
|
||||
// Teacher area
|
||||
const [questions, setQuestions] = useState<QuizSchema[]>([
|
||||
{ questionText: '', questionUUID: 'question_' + uuidv4(), options: [{ text: '', fileID: '', type: 'text', correct: false, optionUUID: 'option_' + uuidv4() }] },
|
||||
]);
|
||||
|
||||
const handleQuestionChange = (index: number, value: string) => {
|
||||
const updatedQuestions = [...questions];
|
||||
updatedQuestions[index].questionText = value;
|
||||
setQuestions(updatedQuestions);
|
||||
};
|
||||
|
||||
const handleOptionChange = (qIndex: number, oIndex: number, value: string) => {
|
||||
const updatedQuestions = [...questions];
|
||||
updatedQuestions[qIndex].options[oIndex].text = value;
|
||||
setQuestions(updatedQuestions);
|
||||
};
|
||||
|
||||
const addOption = (qIndex: number) => {
|
||||
const updatedQuestions = [...questions];
|
||||
updatedQuestions[qIndex].options.push({ text: '', fileID: '', type: 'text', correct: false, optionUUID: 'option_' + uuidv4() });
|
||||
setQuestions(updatedQuestions);
|
||||
};
|
||||
|
||||
const removeOption = (qIndex: number, oIndex: number) => {
|
||||
const updatedQuestions = [...questions];
|
||||
updatedQuestions[qIndex].options.splice(oIndex, 1);
|
||||
setQuestions(updatedQuestions);
|
||||
};
|
||||
|
||||
const addQuestion = () => {
|
||||
setQuestions([...questions, { questionText: '', questionUUID: 'question_' + uuidv4(), options: [{ text: '', fileID: '', type: 'text', correct: false, optionUUID: 'option_' + uuidv4() }] }]);
|
||||
};
|
||||
|
||||
const removeQuestion = (qIndex: number) => {
|
||||
const updatedQuestions = [...questions];
|
||||
updatedQuestions.splice(qIndex, 1);
|
||||
setQuestions(updatedQuestions);
|
||||
};
|
||||
|
||||
const toggleCorrectOption = (qIndex: number, oIndex: number) => {
|
||||
const updatedQuestions = [...questions];
|
||||
// Find the option to toggle
|
||||
const optionToToggle = updatedQuestions[qIndex].options[oIndex];
|
||||
// Toggle the 'correct' property of the option
|
||||
optionToToggle.correct = !optionToToggle.correct;
|
||||
setQuestions(updatedQuestions);
|
||||
};
|
||||
|
||||
const saveFC = async () => {
|
||||
// Save the quiz to the server
|
||||
const values = {
|
||||
contents: {
|
||||
questions,
|
||||
},
|
||||
};
|
||||
const res = await updateAssignmentTask(values, assignmentTaskState.assignmentTask.assignment_task_uuid, assignment.assignment_object.assignment_uuid, access_token);
|
||||
if (res) {
|
||||
assignmentTaskStateHook({
|
||||
type: 'reload',
|
||||
});
|
||||
toast.success('Task saved successfully');
|
||||
} else {
|
||||
toast.error('Error saving task, please retry later.');
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (assignmentTaskState.assignmentTask.contents?.questions) {
|
||||
setQuestions(assignmentTaskState.assignmentTask.contents.questions);
|
||||
}
|
||||
}, [assignmentTaskState,assignment,assignmentTaskStateHook,access_token]);
|
||||
|
||||
// Teacher area end
|
||||
|
||||
return (
|
||||
<AssignmentBoxUI saveFC={saveFC} view='teacher' type="quiz">
|
||||
<div className="flex flex-col space-y-6">
|
||||
{questions.map((question, qIndex) => (
|
||||
<div key={qIndex} className="flex flex-col space-y-1.5">
|
||||
<div className="flex space-x-2 items-center">
|
||||
<input
|
||||
value={question.questionText}
|
||||
onChange={(e) => handleQuestionChange(qIndex, e.target.value)}
|
||||
placeholder="Question"
|
||||
className="w-full px-3 text-neutral-600 bg-[#00008b00] border-2 border-gray-200 rounded-md border-dotted text-sm font-bold"
|
||||
/>
|
||||
<div
|
||||
className="w-[20px] flex-none flex items-center h-[20px] rounded-lg bg-slate-200/60 text-slate-500 hover:bg-slate-300 text-sm transition-all ease-linear cursor-pointer"
|
||||
onClick={() => removeQuestion(qIndex)}
|
||||
>
|
||||
<Minus size={12} className="mx-auto" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-2">
|
||||
{question.options.map((option, oIndex) => (
|
||||
<div className="flex" key={oIndex}>
|
||||
<div
|
||||
key={oIndex}
|
||||
className="answer outline outline-3 outline-white pr-2 shadow w-full flex items-center space-x-2 h-[30px] hover:bg-opacity-100 hover:shadow-md rounded-lg bg-white text-sm duration-150 cursor-pointer ease-linear nice-shadow"
|
||||
>
|
||||
<div className="font-bold text-base flex items-center h-full w-[40px] rounded-l-md text-slate-800 bg-slate-100/80">
|
||||
<p className="mx-auto font-bold text-sm">{String.fromCharCode(65 + oIndex)}</p>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
value={option.text}
|
||||
onChange={(e) => handleOptionChange(qIndex, oIndex, e.target.value)}
|
||||
placeholder="Option"
|
||||
className="w-full mx-2 px-3 pr-6 text-neutral-600 bg-[#00008b00] border-2 border-gray-200 rounded-md border-dotted text-sm font-bold"
|
||||
/>
|
||||
<div
|
||||
className={`w-fit flex-none flex text-xs px-2 py-0.5 space-x-1 items-center h-fit rounded-lg ${option.correct ? 'bg-lime-200 text-lime-600' : 'bg-rose-200/60 text-rose-500'
|
||||
} hover:bg-lime-300 text-sm transition-all ease-linear cursor-pointer`}
|
||||
onClick={() => toggleCorrectOption(qIndex, oIndex)}
|
||||
>
|
||||
{option.correct ? <Check size={12} className="mx-auto" /> : <X size={12} className="mx-auto" />}
|
||||
{option.correct ? (
|
||||
<p className="mx-auto font-bold text-xs">Correct</p>
|
||||
) : (
|
||||
<p className="mx-auto font-bold text-xs">Incorrect</p>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className="w-[20px] flex-none flex items-center h-[20px] rounded-lg bg-slate-200/60 text-slate-500 hover:bg-slate-300 text-sm transition-all ease-linear cursor-pointer"
|
||||
onClick={() => removeOption(qIndex, oIndex)}
|
||||
>
|
||||
<Minus size={12} className="mx-auto" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{/* Show this at the last option */}
|
||||
{oIndex === question.options.length - 1 && (
|
||||
<div className="flex justify-center mx-auto px-2">
|
||||
<div
|
||||
className="outline text-xs outline-3 outline-white px-2 shadow w-full flex items-center h-[30px] hover:bg-opacity-100 hover:shadow-md rounded-lg bg-white duration-150 cursor-pointer ease-linear nice-shadow"
|
||||
onClick={() => addOption(qIndex)}
|
||||
>
|
||||
<Plus size={14} className="inline-block" />
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex justify-center mx-auto px-2">
|
||||
<div
|
||||
className="flex w-full my-2 py-2 px-4 bg-white text-slate text-xs rounded-md nice-shadow hover:shadow-sm cursor-pointer space-x-3 items-center transition duration-150 ease-linear"
|
||||
onClick={addQuestion}
|
||||
>
|
||||
<PlusCircle size={14} className="inline-block" />
|
||||
<span>Add Question</span>
|
||||
</div>
|
||||
</div>
|
||||
</AssignmentBoxUI>
|
||||
);
|
||||
}
|
||||
|
||||
export default TaskQuizObject;
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
'use client';
|
||||
import { useAssignments } from '@components/Contexts/Assignments/AssignmentContext';
|
||||
import { useAssignmentsTask, useAssignmentsTaskDispatch } from '@components/Contexts/Assignments/AssignmentsTaskContext';
|
||||
import { useLHSession } from '@components/Contexts/LHSessionContext';
|
||||
import { useOrg } from '@components/Contexts/OrgContext';
|
||||
import FormLayout, { FormField, FormLabelAndMessage, Input, Textarea } from '@components/StyledElements/Form/Form';
|
||||
import * as Form from '@radix-ui/react-form';
|
||||
import { getAPIUrl } from '@services/config/config';
|
||||
import { getActivity, getActivityByID } from '@services/courses/activities';
|
||||
import { deleteAssignmentTask, updateAssignmentTask, updateReferenceFile } from '@services/courses/assignments';
|
||||
import { getTaskRefFileDir } from '@services/media/media';
|
||||
import { useFormik } from 'formik';
|
||||
import { ArrowBigUpDash, Cloud, File, GalleryVerticalEnd, Info, Loader, TentTree, Trash, Upload, UploadCloud } from 'lucide-react'
|
||||
import Link from 'next/link';
|
||||
import React, { use, useEffect } from 'react'
|
||||
import toast from 'react-hot-toast';
|
||||
import { mutate } from 'swr';
|
||||
import { AssignmentTaskGeneralEdit } from './Subs/AssignmentTaskGeneralEdit';
|
||||
import AssignmentTaskContentEdit from './Subs/AssignmentTaskContentEdit';
|
||||
|
||||
function AssignmentTaskEditor({ page }: any) {
|
||||
const [selectedSubPage, setSelectedSubPage] = React.useState(page)
|
||||
const assignment = useAssignments() as any
|
||||
const assignmentTaskState = useAssignmentsTask() as any
|
||||
const assignmentTaskStateHook = useAssignmentsTaskDispatch() as any
|
||||
const session = useLHSession() as any;
|
||||
const access_token = session?.data?.tokens?.access_token;
|
||||
|
||||
async function deleteTaskUI() {
|
||||
const res = await deleteAssignmentTask(assignmentTaskState.assignmentTask.assignment_task_uuid, assignment.assignment_object.assignment_uuid, access_token)
|
||||
if (res) {
|
||||
assignmentTaskStateHook({
|
||||
type: 'SET_MULTIPLE_STATES',
|
||||
payload: {
|
||||
selectedAssignmentTaskUUID: null,
|
||||
assignmentTask: {},
|
||||
},
|
||||
});
|
||||
mutate(`${getAPIUrl()}assignments/${assignment.assignment_object.assignment_uuid}/tasks`)
|
||||
mutate(`${getAPIUrl()}assignments/${assignment.assignment_object.assignment_uuid}`)
|
||||
toast.success('Task deleted successfully')
|
||||
} else {
|
||||
toast.error('Error deleting task, please retry later.')
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// Switch back to general page if the selectedAssignmentTaskUUID is changed
|
||||
if (assignmentTaskState.selectedAssignmentTaskUUID !== assignmentTaskState.assignmentTask.assignment_task_uuid) {
|
||||
setSelectedSubPage('general')
|
||||
}
|
||||
}
|
||||
, [assignmentTaskState, assignmentTaskStateHook, selectedSubPage, assignment])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col font-black text-sm w-full z-20">
|
||||
{assignmentTaskState.assignmentTask && Object.keys(assignmentTaskState.assignmentTask).length > 0 && (
|
||||
<div className='flex flex-col space-y-3'>
|
||||
<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 mb-3 nice-shadow'>
|
||||
<div className='flex py-1 justify-between items-center'>
|
||||
<div className='font-semibold text-lg '>
|
||||
{assignmentTaskState?.assignmentTask.title}
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
onClick={() => deleteTaskUI()}
|
||||
className='flex px-2 py-1.5 cursor-pointer rounded-md space-x-2 items-center bg-gradient-to-bl text-red-800 bg-rose-100 border border-rose-600/10 shadow-rose-900/10 shadow-lg'>
|
||||
<Trash size={18} />
|
||||
<p className='text-xs font-semibold'>Delete Task</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex space-x-2 '>
|
||||
<div
|
||||
onClick={() => setSelectedSubPage('general')}
|
||||
className={`flex space-x-4 py-2 w-fit text-center border-black transition-all ease-linear ${selectedSubPage === 'general'
|
||||
? 'border-b-4'
|
||||
: 'opacity-50'
|
||||
} cursor-pointer`}
|
||||
>
|
||||
<div className="flex items-center space-x-2.5 mx-2">
|
||||
<Info size={16} />
|
||||
<div>General</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
onClick={() => setSelectedSubPage('content')}
|
||||
className={`flex space-x-4 py-2 w-fit text-center border-black transition-all ease-linear ${selectedSubPage === 'content'
|
||||
? 'border-b-4'
|
||||
: 'opacity-50'
|
||||
} cursor-pointer`}
|
||||
>
|
||||
<div className="flex items-center space-x-2.5 mx-2">
|
||||
<GalleryVerticalEnd size={16} />
|
||||
<div>Content</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='ml-10 mr-10 mt-10 mx-auto bg-white rounded-xl shadow-sm px-6 py-5 nice-shadow'>
|
||||
{selectedSubPage === 'general' && <AssignmentTaskGeneralEdit />}
|
||||
{selectedSubPage === 'content' && <AssignmentTaskContentEdit />}
|
||||
</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>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default AssignmentTaskEditor
|
||||
|
|
@ -1,56 +1,57 @@
|
|||
'use client';
|
||||
import BreadCrumbs from '@components/Dashboard/UI/BreadCrumbs'
|
||||
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 React, { useEffect } from 'react'
|
||||
import { AssignmentProvider, useAssignments } 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';
|
||||
import AssignmentTaskEditor from './_components/TaskEditor/TaskEditor';
|
||||
|
||||
function AssignmentEdit() {
|
||||
const params = useParams<{ assignmentuuid: string; }>()
|
||||
return (
|
||||
<div className='flex w-full flex-col'>
|
||||
<div className='pb-5 bg-white z-50 shadow-[0px_4px_16px_rgba(0,0,0,0.06)] nice-shadow'>
|
||||
<div className='flex justify-between mr-10 h-full'>
|
||||
<div className="pl-10 mr-10 tracking-tighter">
|
||||
<BreadCrumbs type="assignments" last_breadcrumb='UUID' />
|
||||
<div className="w-100 flex justify-between">
|
||||
<div className="flex font-bold text-2xl">Assignment Editor</div>
|
||||
<AssignmentProvider assignment_uuid={'assignment_' + params.assignmentuuid}>
|
||||
<div className='pb-5 bg-white z-50 shadow-[0px_4px_16px_rgba(0,0,0,0.06)] nice-shadow'>
|
||||
<div className='flex justify-between mr-10 h-full'>
|
||||
<div className="pl-10 mr-10 tracking-tighter">
|
||||
<BrdCmpx />
|
||||
<div className="w-100 flex justify-between">
|
||||
<div className="flex font-bold text-2xl">Assignment Editor</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-col justify-center antialiased'>
|
||||
<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>
|
||||
<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 className='flex flex-col justify-center antialiased'>
|
||||
<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>
|
||||
<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>
|
||||
<div className="flex h-full w-full">
|
||||
<AssignmentProvider assignment_uuid={'assignment_' + params.assignmentuuid}>
|
||||
<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'>
|
||||
|
|
@ -65,10 +66,21 @@ function AssignmentEdit() {
|
|||
</AssignmentProvider>
|
||||
</div>
|
||||
</AssignmentsTaskProvider>
|
||||
</AssignmentProvider>
|
||||
</div>
|
||||
</div>
|
||||
</AssignmentProvider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AssignmentEdit
|
||||
export default AssignmentEdit
|
||||
|
||||
function BrdCmpx() {
|
||||
const assignment = useAssignments() as any
|
||||
|
||||
useEffect(() => {
|
||||
}, [assignment])
|
||||
|
||||
return (
|
||||
<BreadCrumbs type="assignments" last_breadcrumb={assignment?.assignment_object?.title} />
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue