- {isPending || isError || searchResults.length < 1 ? (
+ {isPending || isError || searchResults?.length < 1 ? (
{isPending
? "Loading..."
diff --git a/client/src/components/ui/Users/school-data-grid.tsx b/client/src/components/ui/Users/school-data-grid.tsx
index 8ab54f6c..ab2a1fb8 100644
--- a/client/src/components/ui/Users/school-data-grid.tsx
+++ b/client/src/components/ui/Users/school-data-grid.tsx
@@ -12,7 +12,7 @@ import {
} from "@/components/ui/table";
import { cn } from "@/lib/utils";
import { DatagridProps } from "@/types/data-grid";
-import { School } from "@/types/school";
+import { School } from "@/types/user";
/**
* Renders a paginated data grid for displaying school information.
@@ -84,13 +84,13 @@ export function SchoolDataGrid({
{item.id}
{item.name}
- {item.time_created ? (
+ {item.created_at ? (
<>
- {new Date(item.time_created).toLocaleDateString()}
+ {new Date(item.created_at).toLocaleDateString()}
- {new Date(item.time_created).toLocaleTimeString()}
+ {new Date(item.created_at).toLocaleTimeString()}
>
) : null}
diff --git a/client/src/components/ui/Users/school-data-table-form.tsx b/client/src/components/ui/Users/school-data-table-form.tsx
index f9709be9..809af60d 100644
--- a/client/src/components/ui/Users/school-data-table-form.tsx
+++ b/client/src/components/ui/Users/school-data-table-form.tsx
@@ -20,7 +20,7 @@ import {
TableRow,
} from "@/components/ui/table";
import { cn } from "@/lib/utils";
-import { createSchoolSchema } from "@/types/school";
+import { createSchoolSchema } from "@/types/user";
type School = z.infer;
diff --git a/client/src/components/ui/Users/select-school.tsx b/client/src/components/ui/Users/select-school.tsx
index 827fae89..4f152bff 100644
--- a/client/src/components/ui/Users/select-school.tsx
+++ b/client/src/components/ui/Users/select-school.tsx
@@ -7,7 +7,7 @@ import {
} from "@/components/ui/select";
import { useFetchData } from "@/hooks/use-fetch-data";
import { cn } from "@/lib/utils";
-import { School } from "@/types/school";
+import { School } from "@/types/user";
type Props = {
selectedId: number | undefined;
@@ -47,8 +47,8 @@ export function SelectSchool({ selectedId, onChange, className }: Props) {
isPending,
isError,
} = useFetchData({
- queryKey: ["users.school.list"],
- endpoint: "/users/school",
+ queryKey: ["users.schools"],
+ endpoint: "/users/schools/",
});
const onValueChange = (value: string) => {
diff --git a/client/src/components/ui/Users/team-data-grid.tsx b/client/src/components/ui/Users/team-data-grid.tsx
index 7662c61d..e2d7b6e6 100644
--- a/client/src/components/ui/Users/team-data-grid.tsx
+++ b/client/src/components/ui/Users/team-data-grid.tsx
@@ -86,7 +86,7 @@ export function TeamDataGrid({
>
{item.id}
{item.name}
- {item.school}
+ {item.school?.name}
{item.description}
{item.time_created ? (
diff --git a/client/src/pages/api/question/list.ts b/client/src/pages/api/question/list.ts
index 5a56eeb0..de63a2e0 100644
--- a/client/src/pages/api/question/list.ts
+++ b/client/src/pages/api/question/list.ts
@@ -12,51 +12,51 @@
import { NextApiRequest, NextApiResponse } from "next";
-import { Question } from "@/types/question";
+import { Category, Question } from "@/types/question";
// Mock data representing question entries
-const mockQuestions: Question[] = [
+const mockQuestions: Partial[] = [
{
id: 1,
name: "Question01_2024",
- category: "Geometry Questions",
- difficulty: "Difficult",
+ category: [{ genre: "Geometry Questions" }] as Category[],
+ diff_level: 1,
},
{
id: 2,
name: "Question02_2024",
- category: "Algebra Questions",
- difficulty: "Difficult",
+ category: [{ genre: "Algebra Questions" }] as Category[],
+ diff_level: 3,
},
{
id: 3,
name: "Question03_2024",
- category: "Arithmetic Questions",
- difficulty: "Easy",
+ category: [{ genre: "Arithmetic Questions" }] as Category[],
+ diff_level: 1,
},
{
id: 4,
name: "Question04_2024",
- category: "Statistics Questions",
- difficulty: "Medium",
+ category: [{ genre: "Statistics Questions" }] as Category[],
+ diff_level: 2,
},
{
id: 5,
name: "Question05_2024",
- category: "Calculus Questions",
- difficulty: "Difficult",
+ category: [{ genre: "Calculus Questions" }] as Category[],
+ diff_level: 3,
},
{
id: 6,
name: "Question06_2024",
- category: "Calculus Questions",
- difficulty: "Difficult",
+ category: [{ genre: "Calculus Questions" }] as Category[],
+ diff_level: 3,
},
{
id: 7,
name: "Question07_2024",
- category: "Calculus Questions",
- difficulty: "Easy",
+ category: [{ genre: "Calculus Questions" }] as Category[],
+ diff_level: 1,
},
];
@@ -74,5 +74,5 @@ export default function handler(
_req: NextApiRequest,
res: NextApiResponse,
): void {
- res.status(200).json(mockQuestions);
+ res.status(200).json(mockQuestions as Question[]);
}
diff --git a/client/src/pages/api/test/practices.ts b/client/src/pages/api/test/practices.ts
index 87b3ed79..04a802c0 100644
--- a/client/src/pages/api/test/practices.ts
+++ b/client/src/pages/api/test/practices.ts
@@ -12,32 +12,32 @@
import { NextApiRequest, NextApiResponse } from "next";
// Mock data representing practice entries
-import { Practice } from "@/types/practice";
+import { AdminQuiz } from "@/types/quiz";
-const mockPractices: Partial[] = [
+const mockPractices: Partial[] = [
{
name: "Practice01_2024",
- status: "Published",
+ status: 0,
},
{
name: "Practice02_2024",
- status: "Unpublished",
+ status: 1,
},
{
name: "Practice03_2024",
- status: "Unpublished",
+ status: 2,
},
{
name: "Practice04_2024",
- status: "Published",
+ status: 3,
},
{
name: "Practice05_2024",
- status: "Published",
+ status: 1,
},
{
name: "Practice06_2024",
- status: "Unpublished",
+ status: 3,
},
];
@@ -53,7 +53,7 @@ const mockPractices: Partial[] = [
*/
export default function handler(
_req: NextApiRequest,
- res: NextApiResponse,
+ res: NextApiResponse,
): void {
- res.status(200).json(mockPractices as Practice[]);
+ res.status(200).json(mockPractices as AdminQuiz[]);
}
diff --git a/client/src/pages/api/users/school.ts b/client/src/pages/api/users/school.ts
index 34b91ec9..3823b6b2 100644
--- a/client/src/pages/api/users/school.ts
+++ b/client/src/pages/api/users/school.ts
@@ -12,7 +12,7 @@
import { NextApiRequest, NextApiResponse } from "next";
-import { School } from "@/types/school";
+import { School } from "@/types/user";
/**
* Mock data representing school entries.
@@ -25,17 +25,17 @@ for (let i = 0; i < 11; i++) {
{
id: i * 3 + 1,
name: `School Alpha ${i + 1}`,
- time_created: new Date(`2025-01-01T12:00:00Z`),
+ created_at: new Date(`2025-01-01T12:00:00Z`),
},
{
id: i * 3 + 2,
name: `School Beta ${i + 1}`,
- time_created: new Date(`2025-01-01T13:00:00Z`),
+ created_at: new Date(`2025-01-01T13:00:00Z`),
},
{
id: i * 3 + 3,
name: `School Gamma ${i + 1}`,
- time_created: new Date(`2025-01-01T14:00:00Z`),
+ created_at: new Date(`2025-01-01T14:00:00Z`),
},
);
}
diff --git a/client/src/pages/api/users/team.ts b/client/src/pages/api/users/team.ts
index 9c905c06..11a93433 100644
--- a/client/src/pages/api/users/team.ts
+++ b/client/src/pages/api/users/team.ts
@@ -13,6 +13,7 @@
import { NextApiRequest, NextApiResponse } from "next";
import { Team } from "@/types/team";
+import { School } from "@/types/user";
/**
* Mock data representing team entries.
@@ -25,21 +26,21 @@ for (let i = 0; i < 9; i++) {
{
id: i * 3 + 1,
name: `Team Alpha ${i + 1}`,
- school: "Greenfield High",
+ school: { name: "Greenfield High" } as School,
description: `A description for Team Alpha ${i + 1}.`,
time_created: new Date(`2025-01-01T12:00:00Z`),
},
{
id: i * 3 + 2,
name: `Team Beta ${i + 1}`,
- school: "Westwood Academy",
+ school: { name: "Westwood Academy" } as School,
description: `A description for Team Beta ${i + 1}.`,
time_created: new Date(`2025-01-01T13:00:00Z`),
},
{
id: i * 3 + 3,
name: `Team Gamma ${i + 1}`,
- school: "Northside School",
+ school: { name: "Northside School" } as School,
description: `A description for Team Gamma ${i + 1}.`,
time_created: new Date(`2025-01-01T14:00:00Z`),
},
diff --git a/client/src/pages/question/index.tsx b/client/src/pages/question/index.tsx
index ebce9dd9..1904a95d 100644
--- a/client/src/pages/question/index.tsx
+++ b/client/src/pages/question/index.tsx
@@ -16,7 +16,7 @@ export default function Index() {
isError: isQuestionError,
error: QuestionError,
} = useFetchData({
- queryKey: ["question.list"],
+ queryKey: ["questions.question-bank"],
endpoint: "/questions/question-bank/",
});
diff --git a/client/src/pages/test/competition/index.tsx b/client/src/pages/test/competition/index.tsx
index 77bcd54c..6c2f7113 100644
--- a/client/src/pages/test/competition/index.tsx
+++ b/client/src/pages/test/competition/index.tsx
@@ -6,7 +6,7 @@ import { WaitingLoader } from "@/components/ui/loading";
import { SearchInput } from "@/components/ui/search";
import { CompetitionDataGrid } from "@/components/ui/Test/competition-data-grid";
import { useFetchData } from "@/hooks/use-fetch-data";
-import { Competition } from "@/types/competition";
+import { Competition } from "@/types/quiz";
export default function Index() {
const {
@@ -15,8 +15,8 @@ export default function Index() {
isError: isCompetitionError,
error: competitionError,
} = useFetchData({
- queryKey: ["competition.list"],
- endpoint: "/test/competitions",
+ queryKey: ["quiz.competition"],
+ endpoint: "/quiz/competition/",
});
const [page, setPage] = useState(1);
diff --git a/client/src/pages/test/index.tsx b/client/src/pages/test/index.tsx
index 3e69afbc..2a3d8936 100644
--- a/client/src/pages/test/index.tsx
+++ b/client/src/pages/test/index.tsx
@@ -6,7 +6,7 @@ import { WaitingLoader } from "@/components/ui/loading";
import { SearchInput } from "@/components/ui/search";
import { PracticeDataGrid } from "@/components/ui/Test/practice-data-grid";
import { useFetchData } from "@/hooks/use-fetch-data";
-import { Practice } from "@/types/practice";
+import { AdminQuiz } from "@/types/quiz";
export default function Index() {
const {
@@ -14,13 +14,13 @@ export default function Index() {
isLoading: isPracticeLoading,
isError: isPracticeError,
error: practiceError,
- } = useFetchData({
- queryKey: ["practice.list"],
- endpoint: "/test/practices",
+ } = useFetchData({
+ queryKey: ["quiz.admin-quizzes"],
+ endpoint: "/quiz/admin-quizzes/",
});
const [page, setPage] = useState(1);
- const [filteredData, setFilteredData] = useState([]);
+ const [filteredData, setFilteredData] = useState([]);
useEffect(() => {
if (practices) {
diff --git a/client/src/pages/test/leaderboard/index.tsx b/client/src/pages/test/leaderboard/index.tsx
index 15ab1a48..f2bf026e 100644
--- a/client/src/pages/test/leaderboard/index.tsx
+++ b/client/src/pages/test/leaderboard/index.tsx
@@ -15,8 +15,8 @@ export default function Index() {
isError: isLeaderboardError,
error: leaderboardError,
} = useFetchData({
- queryKey: ["leaderboard.list"],
- endpoint: "/test/leaderboards",
+ queryKey: ["leaderboard.individual"],
+ endpoint: "/leaderboard/individual/",
});
const [page, setPage] = useState(1);
diff --git a/client/src/pages/test/leaderboard/insight.tsx b/client/src/pages/test/leaderboard/insight.tsx
index c6fb3dd8..ad1d65b8 100644
--- a/client/src/pages/test/leaderboard/insight.tsx
+++ b/client/src/pages/test/leaderboard/insight.tsx
@@ -12,8 +12,8 @@ export default function Index() {
isError: isInsightError,
error: insightError,
} = useFetchData({
- queryKey: ["insight.list"],
- endpoint: "/test/insights",
+ queryKey: ["leaderboard.individual"],
+ endpoint: "/leaderboard/individual/",
});
const [page, setPage] = useState(1);
diff --git a/client/src/pages/test/leaderboard/ranking.tsx b/client/src/pages/test/leaderboard/ranking.tsx
index 30fa4de2..07d9c6c3 100644
--- a/client/src/pages/test/leaderboard/ranking.tsx
+++ b/client/src/pages/test/leaderboard/ranking.tsx
@@ -12,8 +12,8 @@ export default function Index() {
isError: isRankingError,
error: rankingError,
} = useFetchData({
- queryKey: ["ranking.list"],
- endpoint: "/test/rankings",
+ queryKey: ["leaderboard.individual"],
+ endpoint: "/leaderboard/individual/",
});
const [page, setPage] = useState(1);
diff --git a/client/src/pages/users/index.tsx b/client/src/pages/users/index.tsx
index 7d294b26..f4ce9bad 100644
--- a/client/src/pages/users/index.tsx
+++ b/client/src/pages/users/index.tsx
@@ -15,8 +15,8 @@ export default function UserList() {
isError: isUserError,
error: UserError,
} = useFetchData({
- queryKey: ["user.list"],
- endpoint: "/users",
+ queryKey: ["users.students"],
+ endpoint: "/users/students/",
});
const [page, setPage] = useState(1);
diff --git a/client/src/pages/users/school.tsx b/client/src/pages/users/school.tsx
index 2395a99b..f500976b 100644
--- a/client/src/pages/users/school.tsx
+++ b/client/src/pages/users/school.tsx
@@ -6,7 +6,7 @@ import { WaitingLoader } from "@/components/ui/loading";
import { SearchInput } from "@/components/ui/search";
import { SchoolDataGrid } from "@/components/ui/Users/school-data-grid";
import { useFetchData } from "@/hooks/use-fetch-data";
-import type { School } from "@/types/school";
+import type { School } from "@/types/user";
export default function SchoolList() {
const {
@@ -15,8 +15,8 @@ export default function SchoolList() {
isError: isSchoolError,
error: schoolError,
} = useFetchData({
- queryKey: ["users.school.list"],
- endpoint: "/users/school",
+ queryKey: ["users.schools"],
+ endpoint: "/users/schools/",
});
const [page, setPage] = useState(1);
diff --git a/client/src/pages/users/team.tsx b/client/src/pages/users/team.tsx
index 41225642..2f9a6438 100644
--- a/client/src/pages/users/team.tsx
+++ b/client/src/pages/users/team.tsx
@@ -15,8 +15,8 @@ export default function TeamList() {
isError: isTeamError,
error: TeamError,
} = useFetchData({
- queryKey: ["users.team.list"],
- endpoint: "/users/team",
+ queryKey: ["team.teams"],
+ endpoint: "/team/teams/",
});
const [page, setPage] = useState(1);
diff --git a/client/src/types/leaderboard.ts b/client/src/types/leaderboard.ts
index dce51d0e..96353484 100644
--- a/client/src/types/leaderboard.ts
+++ b/client/src/types/leaderboard.ts
@@ -1,3 +1,5 @@
+import { Student } from "@/types/user";
+
/**
* Example of `Leaderboard`.
*
@@ -16,12 +18,30 @@
* };
*/
export interface Leaderboard {
+ // to be discuss
id: number;
name: string;
participant_students: number;
participant_teams: number;
}
+export interface LeaderboardIndividual {
+ name: string;
+ year_level: number;
+ school: string;
+ school_type: string;
+ is_country: boolean;
+ total_marks: number;
+}
+
+export interface LeaderboardTeam {
+ school: string;
+ id: number;
+ total_marks: number;
+ is_country: true;
+ students: Student[];
+}
+
export interface Ranking {
student_name: string;
team: string;
diff --git a/client/src/types/practice.ts b/client/src/types/practice.ts
index 8eab6f5e..be5c9137 100644
--- a/client/src/types/practice.ts
+++ b/client/src/types/practice.ts
@@ -1,25 +1,74 @@
import { z } from "zod";
-import {
- genericCreateTestSchema,
- QuestionBlock,
- QuestionStatus,
-} from "./competition";
+/**
+ * Enum representing the status of a question.
+ *
+ * @enum
+ */
+export const QuestionStatusEnum = z.enum(["Published", "Unpublished"], {
+ errorMap: () => ({ message: "Invalid Status" }),
+});
+
+/** Type alias for the QuestionStatusEnum. */
+export type QuestionStatus = z.infer;
+
+/**
+ * Zod schema for validating a question creation input.
+ *
+ * Ensures that each question has a non-negative integer ID and a non-empty name.
+ *
+ * @constant
+ */
+const createQuestionSchema = z.object({
+ id: z.number().int().nonnegative(),
+ name: z.string().min(1, "Question name is required"),
+});
+
+/**
+ * Zod schema for validating a question block.
+ *
+ * Ensures that each question block has a non-negative integer ID and at least one question.
+ *
+ * @constant
+ */
+const createQuestionBlockSchema = z.object({
+ id: z.number().int().nonnegative(),
+ questions: z
+ .array(createQuestionSchema)
+ .min(1, "At least one question is required"),
+});
+
+/**
+ * Zod schema for validating generic test creation input.
+ *
+ * Validates name, general instructions, and at least one question block.
+ *
+ * @constant
+ */
+export const genericCreateTestSchema = z.object({
+ name: z.string().min(1, "Required"),
+ general_instructions: z.string().min(1, "Required"),
+ blocks: z
+ .array(createQuestionBlockSchema)
+ .min(1, "At least one question block is required"), // An array of question blocks
+});
/**
- * Interface representing a Practice session.
+ * Zod schema for validating competition creation input.
+ *
+ * Extends the generic test schema and ensures that the start time is earlier than the end time.
*
- * @interface
+ * @constant
*/
-export interface Practice {
- id: number;
- name: string;
- general_instructions: string;
- hours: number;
- minutes: number;
- status: QuestionStatus;
- blocks: QuestionBlock[];
-}
+export const createCompetitionSchema = genericCreateTestSchema
+ .extend({
+ start_time: z.date(),
+ end_time: z.date(),
+ })
+ .refine((data) => data.start_time < data.end_time, {
+ message: "Start time must be earlier than end time.",
+ path: ["start_time"], // optional: Specify which field the error applies to
+ });
/**
* Zod schema for validating practice creation input.
diff --git a/client/src/types/question.ts b/client/src/types/question.ts
index 19ed4651..e5e76afb 100644
--- a/client/src/types/question.ts
+++ b/client/src/types/question.ts
@@ -1,4 +1,11 @@
import { ReactNode } from "react";
+import { z } from "zod";
+
+export interface Category {
+ id: number;
+ genre: string;
+ info: string;
+}
/**
* Represents a Question object with its properties.
@@ -20,8 +27,20 @@ import { ReactNode } from "react";
export interface Question {
id: number;
name: string;
- category: string;
- difficulty: string;
+ created_by: string;
+ modified_by: string;
+ category: Category[]; // to be discussed
+ is_comp: boolean;
+ answer: number[];
+ question_text: string;
+ note: string;
+ answer_text: string;
+ diff_level: number;
+ layout: string;
+ mark: number;
+ time_created: Date;
+ time_modified: Date;
+ image: number;
}
/**
@@ -132,3 +151,79 @@ export interface PreviewModalProps {
children: ReactNode;
dataContext: PreviewModalDataContext;
}
+
+/**
+ * Zod schema for validating a question creation input.
+ *
+ * Ensures that each question has a non-negative integer ID and a non-empty name.
+ *
+ * @constant
+ */
+const createQuestionSchema = z.object({
+ id: z.number().int().nonnegative(),
+ name: z.string().min(1, "Question name is required"),
+});
+
+/**
+ * Zod schema for validating a question block.
+ *
+ * Ensures that each question block has a non-negative integer ID and at least one question.
+ *
+ * @constant
+ */
+const createQuestionBlockSchema = z.object({
+ id: z.number().int().nonnegative(),
+ questions: z
+ .array(createQuestionSchema)
+ .min(1, "At least one question is required"),
+});
+
+/**
+ * Zod schema for validating generic test creation input.
+ *
+ * Validates name, general instructions, and at least one question block.
+ *
+ * @constant
+ */
+export const genericCreateTestSchema = z.object({
+ name: z.string().min(1, "Required"),
+ general_instructions: z.string().min(1, "Required"),
+ blocks: z
+ .array(createQuestionBlockSchema)
+ .min(1, "At least one question block is required"), // An array of question blocks
+});
+
+/**
+ * Zod schema for validating competition creation input.
+ *
+ * Extends the generic test schema and ensures that the start time is earlier than the end time.
+ *
+ * @constant
+ */
+export const createCompetitionSchema = genericCreateTestSchema
+ .extend({
+ start_time: z.date(),
+ end_time: z.date(),
+ })
+ .refine((data) => data.start_time < data.end_time, {
+ message: "Start time must be earlier than end time.",
+ path: ["start_time"], // optional: Specify which field the error applies to
+ });
+
+/**
+ * Zod schema for validating practice creation input.
+ *
+ * Extends the generic test schema with additional validations for `hours` and `minutes`.
+ *
+ * @constant
+ */
+export const createPracticeSchema = genericCreateTestSchema.extend({
+ hours: z
+ .number()
+ .min(0, "Number must be at least 0")
+ .max(24, "Number must be at most 24"),
+ minutes: z
+ .number()
+ .min(0, "Number must be at least 0")
+ .max(60, "Number must be at most 60"),
+});
diff --git a/client/src/types/quiz.ts b/client/src/types/quiz.ts
new file mode 100644
index 00000000..b475049d
--- /dev/null
+++ b/client/src/types/quiz.ts
@@ -0,0 +1,94 @@
+import { Question } from "@/types/question";
+
+export interface AdminQuiz {
+ id: number;
+ name: string;
+ intro: string;
+ total_marks: string;
+ is_comp: boolean;
+ visible: boolean;
+ open_time_date: Date;
+ time_limit: number;
+ time_window: number;
+ status: number;
+}
+
+export interface AdminQuizSlot {
+ id: number;
+ name: string;
+ intro: string;
+ total_marks: string;
+ is_comp: boolean;
+ visible: boolean;
+ open_time_date: Date;
+ time_limit: number;
+ time_window: number;
+ status: number;
+}
+
+export interface Quiz {
+ id: number;
+ name: string;
+ intro: string;
+ total_marks: string;
+}
+
+export interface QuizSlot {
+ id: number;
+ name: string;
+ intro: string;
+ total_marks: string;
+}
+
+export enum QuizStatus {
+ NormalPractice = 0,
+ Upcoming = 1,
+ Ongoing = 2,
+ Finished = 3,
+}
+
+export interface Competition {
+ id: number;
+ name: string;
+ intro: string;
+ total_marks: string;
+ open_time_date: Date; // need from server
+ status: QuizStatus; // to be discuss
+}
+
+export interface CompetitionSlot {
+ id: number;
+ name: string;
+ intro: string;
+ total_marks: string;
+}
+
+export interface QuestionAttempt {
+ id: number;
+ answer_student: number;
+ is_correct: boolean;
+ student: number;
+ question: number;
+ quiz_attempt: number;
+}
+
+export interface QuizAttempt {
+ id: number;
+ current_page: number;
+ state: number;
+ time_start: Date;
+ time_finish: Date;
+ time_modified: Date;
+ total_marks: number;
+ quiz: number;
+ student: number;
+ team: number;
+}
+
+export interface QuizSlot {
+ id: number;
+ question: Question;
+ slot_index: number;
+ block: number;
+ quiz: number;
+}
diff --git a/client/src/types/school.ts b/client/src/types/school.ts
deleted file mode 100644
index 64c42b35..00000000
--- a/client/src/types/school.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { z } from "zod";
-
-/**
- * Represents a school with its id, name, and creation date.
- *
- * @interface School
- * @property {number} id - The unique identifier for the school.
- * @property {string} name - The name of the school.
- * @property {Date} time_created - The timestamp of when the school was created.
- */
-export interface School {
- id: number;
- name: string;
- time_created: Date;
-}
-
-/**
- * A Zod schema for validating the creation of a school.
- *
- * @example
- * const schoolData = { name: "University of Example" };
- * const parsedData = createSchoolSchema.parse(schoolData);
- */
-export const createSchoolSchema = z.object({
- name: z.string().min(1, "Required"),
-});
diff --git a/client/src/types/team.ts b/client/src/types/team.ts
index 6253424b..0b096656 100644
--- a/client/src/types/team.ts
+++ b/client/src/types/team.ts
@@ -1,5 +1,14 @@
import { z } from "zod";
+import { School, Student } from "@/types/user";
+
+export interface TeamMember {
+ id: number;
+ student: Student;
+ time_added: Date;
+ team: number;
+}
+
/**
* Represents a team with its id, name, associated school, description, and creation date.
*
@@ -12,10 +21,12 @@ import { z } from "zod";
*/
export interface Team {
id: number;
+ members: TeamMember[];
+ school: School;
name: string;
- school: string;
description: string;
time_created: Date;
+ students: Student[];
}
/**
diff --git a/client/src/types/user.ts b/client/src/types/user.ts
index 665c81bf..fa81869f 100644
--- a/client/src/types/user.ts
+++ b/client/src/types/user.ts
@@ -42,6 +42,38 @@ export interface User {
school: string;
}
+export interface Student {
+ id: number;
+ name: string;
+ year_level: number;
+}
+
+/**
+ * Represents a school with its id, name, and creation date.
+ *
+ * @interface School
+ * @property {number} id - The unique identifier for the school.
+ * @property {string} name - The name of the school.
+ * @property {Date} time_created - The timestamp of when the school was created.
+ */
+export interface School {
+ id: number;
+ name: string;
+ type: string;
+ is_country: boolean;
+ created_at: Date; // need from server
+}
+
+export interface Teacher {
+ id: number;
+ first_name: string;
+ last_name: string;
+ school: School;
+ email: string;
+ phone: string;
+ created_at: Date;
+}
+
/**
* Zod schema for validating login input.
*
@@ -86,3 +118,14 @@ export const createUserSchema = loginSchema.extend({
school_id: z.number({ message: "Required" }),
email: z.string().email("Invalid email address").optional(),
});
+
+/**
+ * A Zod schema for validating the creation of a school.
+ *
+ * @example
+ * const schoolData = { name: "University of Example" };
+ * const parsedData = createSchoolSchema.parse(schoolData);
+ */
+export const createSchoolSchema = z.object({
+ name: z.string().min(1, "Required"),
+});