Skip to content

Commit

Permalink
Merge pull request #28 from team-inu/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
Porping committed May 22, 2024
2 parents a9b2115 + 652a60c commit fd2bbea
Show file tree
Hide file tree
Showing 57 changed files with 1,558 additions and 929 deletions.
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"semi": true,
"tabWidth": 2,
"useTabs": false,
"printWidth": 120,
"importOrderSeparation": true,
"importOrderSortSpecifiers": true,
"importOrder": ["<THIRD_PARTY_MODULES>", "^@/(.*)$", "^[./]"],
Expand Down
25 changes: 20 additions & 5 deletions app/(main)/course/[id]/setting/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
'use client';

import { SkullIcon } from 'lucide-react';
import { useParams } from 'next/navigation';
import { useState } from 'react';

import CourseImporterDialog from '@/components/features/course/importer/course-importer-dialog';
import CourseSettingForm from '@/components/features/course/settings/course-setting-form';
import Loading from '@/components/features/loading-screen';
import { Button } from '@/components/ui/button';
import { Dialog } from '@/components/ui/dialog';
import { useGetCourseById } from '@/hooks/course-hook';

const SettingPage = () => {
const { id: courseId } = useParams<{ id: string }>();
const { data: courseData, isLoading } = useGetCourseById(courseId);

const [isImportOpen, setIsImportOpen] = useState(false);

if (isLoading) {
return <Loading />;
}
Expand All @@ -18,9 +25,15 @@ const SettingPage = () => {
<div className="space-y-6">
<div>
<h3 className="text-lg font-medium">Course Information</h3>
<p className="text-sm text-muted-foreground">
Update your course information and settings.
</p>
<p className="text-sm text-muted-foreground">Update your course information and settings.</p>

<Button variant={'secondary'} className="my-5 space-x-3" onClick={() => setIsImportOpen(true)}>
<SkullIcon className="h-5 w-5" />
<div className="">Re-Import course</div>
</Button>
<Dialog open={isImportOpen} onOpenChange={setIsImportOpen}>
<CourseImporterDialog />
</Dialog>
</div>
{courseData === undefined ? (
<Loading />
Expand All @@ -31,8 +44,10 @@ const SettingPage = () => {
name: courseData.name,
description: courseData.description,
curriculum: courseData.curriculum,
expectedPassingCloPercentage:
courseData.expectedPassingCloPercentage,
expectedPassingCloPercentage: courseData.expectedPassingCloPercentage,
academicYear: courseData.academicYear,
graduateYear: courseData.graduateYear,
programYear: courseData.programYear,
criteriaGradeA: courseData.criteriaGradeA,
criteriaGradeBP: courseData.criteriaGradeBP,
criteriaGradeB: courseData.criteriaGradeB,
Expand Down
11 changes: 10 additions & 1 deletion app/(main)/course/create/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use client';

import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
import { FormProvider } from 'react-hook-form';

import CreateCourseHeader from '@/components/features/course/course-form/create-course-header';
Expand All @@ -15,11 +17,18 @@ import {
} from '@/types/schema/course-schema';

const CreateCoursePage = () => {
const rounter = useRouter();
const form = useStrictForm(
CreateCourseSchema,
CreateCourseSchemaDefaultValues,
);
const { mutate, isPending: isSubmitting } = useCreateCourse();
const { mutate, isSuccess } = useCreateCourse();

useEffect(() => {
if (isSuccess) {
rounter.push('/course');
}
}, [form, isSuccess, rounter]);
const onSubmit = (values: CreateCourseSchemaValues) => {
checkGrade(values);
mutate(values);
Expand Down
54 changes: 31 additions & 23 deletions app/(main)/course/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,25 @@ import CourseCard from '@/components/features/course/course-card';
import Loading from '@/components/features/loading-screen';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { useAuth } from '@/hooks/auth-hook';
import { useCourseList } from '@/hooks/course-hook';
import { Role } from '@/types/auth-type';

const CoursePage = () => {
const [searchValue, setSearchValue] = useState('');
const [curriculum, setCurriculum] = useState('none');
const [year, setYear] = useState('2023');
const [curriculum, setCurriculum] = useState('all programmes');
const [year, setYear] = useState('all years');
const { user } = useAuth();
const { data: courses, isLoading: isCourseLoading } = useCourseList();
const curriculumLists = ['international', 'regular', 'none'];
const curriculumLists = ['international', 'regular', 'all programmes'];

const yearSet = new Set<string>();
yearSet.add('all years');

courses?.forEach((course) => {
yearSet.add(String(course.semester.year));
});

const handleYearChange = (e: string) => {
setYear(e);
Expand Down Expand Up @@ -68,10 +68,17 @@ const CoursePage = () => {
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="2022">2022</SelectItem>
<SelectItem value="2023">2023</SelectItem>
<SelectItem value="2024">2024</SelectItem>
<SelectItem value="2025">2025</SelectItem>
{Array.from(yearSet)
.sort((a, b) => {
return Number(b) - Number(a);
})
.map((year, i) => {
return (
<SelectItem key={i} value={year}>
{year}
</SelectItem>
);
})}
</SelectGroup>
</SelectContent>
</Select>
Expand All @@ -80,11 +87,7 @@ const CoursePage = () => {

{user.data?.role === Role.HEAD_OF_CURRICULUM && (
<Link href="/course/create" className="flex w-2/12 justify-end">
<Button
variant={'default'}
className="min-w-max text-base font-bold"
size={'lg'}
>
<Button variant={'default'} className="min-w-max text-base font-bold" size={'lg'}>
Add course
</Button>
</Link>
Expand All @@ -105,16 +108,21 @@ const CoursePage = () => {
const lowerCaseCourseId = e.code.toLowerCase();

return (
lowerCaseCourseName.includes(lowerCaseSearchValue) ||
lowerCaseCourseId.includes(lowerCaseSearchValue)
lowerCaseCourseName.includes(lowerCaseSearchValue) || lowerCaseCourseId.includes(lowerCaseSearchValue)
);
})
.filter((e) => {
if (curriculum === 'none') {
if (curriculum === 'all programmes') {
return e;
}
return e.curriculum === curriculum;
})
.filter((e) => {
if (year === 'all years') {
return true;
}
return String(e.semester.year) === year;
})
.map((e, i) => {
return (
<CourseCard
Expand Down
64 changes: 34 additions & 30 deletions components/features/course/assignment/assignment-add-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,44 +48,35 @@ const AssignmentAddDialog: React.FC<StudentAddDialogProps> = ({

return (
<div>
<DialogContent>
<DialogContent className="">
<DialogHeader>
<DialogTitle>Add Assessment</DialogTitle>
<DialogDescription>
Fill in the assessment information
</DialogDescription>
</DialogHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-3">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<div className="flex flex-col space-y-3">
<Input {...field} />
<FormMessage />
</div>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="description"
render={({ field }) => (
<FormItem>
<FormLabel>Description</FormLabel>
<FormControl>
<Textarea {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="my-auto h-max space-y-3 overflow-auto"
>
<div className="grid grid-cols-2 gap-3">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<div className="flex flex-col space-y-3">
<Input {...field} />
<FormMessage />
</div>
</FormControl>
</FormItem>
)}
/>

<FormField
control={form.control}
name="maxScore"
Expand All @@ -102,6 +93,19 @@ const AssignmentAddDialog: React.FC<StudentAddDialogProps> = ({
)}
/>
</div>
<FormField
control={form.control}
name="description"
render={({ field }) => (
<FormItem>
<FormLabel>Description</FormLabel>
<FormControl>
<Textarea {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
Expand Down
72 changes: 43 additions & 29 deletions components/features/course/assignment/assignment-row-action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,47 +81,61 @@ export function AssignmentRowActions<TData>({
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-[160px]">
<DropdownMenuItem onClick={() => setIsEditDialogOpen(true)}>
<DropdownMenuItem
onClick={(e) => {
setIsEditDialogOpen(true);
e.stopPropagation();
}}
>
Edit
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setIsDeleteDialogOpen(true)}>
<DropdownMenuItem
onClick={(e) => {
setIsDeleteDialogOpen(true);
e.stopPropagation();
}}
>
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>

{isEditDialogOpen && (
<AssignmentEditDialog
onSubmit={onSubmitEdit}
defaultValues={{
id: assignment.id,
description: assignment.description,
expectedPassingStudentPercentage:
assignment.expectedPassingStudentPercentage,
expectedScorePercentage: assignment.expectedScorePercentage,
maxScore: assignment.maxScore,
name: assignment.name,
isIncludedInClo: assignment.isIncludedInClo,
}}
/>
<div onClick={(e) => e.stopPropagation()}>
<AssignmentEditDialog
onSubmit={onSubmitEdit}
defaultValues={{
id: assignment.id,
description: assignment.description,
expectedPassingStudentPercentage:
assignment.expectedPassingStudentPercentage,
expectedScorePercentage: assignment.expectedScorePercentage,
maxScore: assignment.maxScore,
name: assignment.name,
isIncludedInClo: assignment.isIncludedInClo,
}}
/>
</div>
)}

{isDeleteDialogOpen && (
<DialogContent>
<DialogHeader>
<DialogTitle>Are your sure to delete?</DialogTitle>
<DialogDescription>
{`You can't undo this action. This will permanently delete the.`}
</DialogDescription>
</DialogHeader>
<div onClick={(e) => e.stopPropagation()}>
<DialogContent>
<DialogHeader>
<DialogTitle>Are your sure to delete?</DialogTitle>
<DialogDescription>
{`You can't undo this action. This will permanently delete the.`}
</DialogDescription>
</DialogHeader>

<DialogFooter>
<DialogClose asChild>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button onClick={onSubmitDelete}>Delete</Button>
</DialogFooter>
</DialogContent>
<DialogFooter>
<DialogClose asChild>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button onClick={onSubmitDelete}>Delete</Button>
</DialogFooter>
</DialogContent>
</div>
)}
</Dialog>
);
Expand Down
6 changes: 5 additions & 1 deletion components/features/course/assignment/assignment-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ export function AssignmentDataTable<TData, TValue>({
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id} colSpan={header.colSpan}>
<TableHead
key={header.id}
colSpan={header.colSpan}
className="font-bold text-primary"
>
{header.isPlaceholder
? null
: flexRender(
Expand Down
Loading

0 comments on commit fd2bbea

Please sign in to comment.