feat: full quiz tasks edition and creation

This commit is contained in:
swve 2024-07-17 23:41:46 +02:00
parent aa55c51b48
commit 175a5a97fa
8 changed files with 453 additions and 144 deletions

View file

@ -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)
}

View file

@ -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

View file

@ -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
}

View file

@ -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;

View file

@ -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

View file

@ -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} />
)
}

View file

@ -0,0 +1,53 @@
import { BookUser, EllipsisVertical, ListTodo, Save } from 'lucide-react'
import React from 'react'
type AssignmentBoxProps = {
type: 'quiz' | 'task'
view?: 'teacher' | 'student'
saveFC?: () => void
children: React.ReactNode
}
function AssignmentBoxUI({ type, view, saveFC, children }: AssignmentBoxProps) {
return (
<div className='flex flex-col px-4 py-2 nice-shadow rounded-md bg-slate-100/30'>
<div className='flex justify-between space-x-2 pb-2 text-slate-400 items-center'>
<div className='flex space-x-1 items-center'>
<div className='text-lg font-semibold'>
{type === 'quiz' &&
<div className='flex space-x-1.5 items-center'>
<ListTodo size={17} />
<p>Quiz</p>
</div>}
</div>
<div className='flex items-center space-x-1'>
<EllipsisVertical size={15} />
</div>
{view === 'teacher' &&
<div className='flex bg-amber-200/20 text-xs rounded-full space-x-1 px-2 py-0.5 mx-auto font-bold outline items-center text-amber-600 outline-1 outline-amber-300/40'>
<BookUser size={12} />
<p>Teacher view</p>
</div>
}
</div>
<div className='flex px-1 py-1 rounded-md items-center'>
{/* Save button */}
<div
onClick={() => saveFC && saveFC()}
className='flex px-2 py-1 cursor-pointer rounded-md space-x-2 items-center bg-gradient-to-bl text-slate-500 bg-white/60 hover:bg-white/80 linear transition-all nice-shadow '>
<Save size={14} />
<p className='text-xs font-semibold'>Save</p>
</div>
</div>
</div>
{children}
</div>
)
}
export default AssignmentBoxUI