Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion client/src/api/auth/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { StudentType } from "../student/student.type";
import { TeacherType } from "../teacher/teacher.type";
import { ModeratorType } from "../moderator/moderator.type.ts";

export type Role = "student" | "teacher" | "moderator";

Expand All @@ -14,7 +15,7 @@ export type RegisterFinalType = RegisterFormTypes & {
role: Role;
};

export type UserType = StudentType | TeacherType;
export type UserType = StudentType | TeacherType | ModeratorType;

export type LoginFormTypes = {
email: string;
Expand Down
15 changes: 14 additions & 1 deletion client/src/api/moderator/moderator.api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import { LoginFormTypes } from "../auth/types.ts";
import { apiPublic } from "../api.ts";
import { apiProtected, apiPublic } from "../api.ts";
import { TeacherStatus } from "../teacher/teacher.type.ts";

export async function loginModeratorApi(data: LoginFormTypes) {
const res = await apiPublic.post("/api/moderator/auth/login", data);
return res.data as { accessToken: string };
}

export async function moderatorChangeTeacherStatusApi({
id,
status,
}: {
id: string;
status: TeacherStatus;
}) {
return await apiProtected.patch(`/api/moderator/teachers/${id}/status`, {
status,
});
}
9 changes: 9 additions & 0 deletions client/src/api/moderator/moderator.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type ModeratorType = {
id: string;
firstName: string;
lastName: string;
email: string;
profileImageUrl: string | null;
createdAt: Date;
role: "moderator";
};
21 changes: 21 additions & 0 deletions client/src/api/teacher/teacher.api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { apiProtected, apiPublic } from "../api.ts";
import {
TeacherOutputModel,
TeachersForModeratorQuery,
TeachersQuery,
TeacherType,
UpdateTeacherProfileInput,
Expand All @@ -14,11 +15,31 @@ export async function getAllTeachersApi(query: TeachersQuery) {
return res.data;
}

export async function getAllTeachersForModeratorApi(
query: TeachersForModeratorQuery,
) {
const res = await apiProtected.get<TeacherOutputModel>(
"/api/teachers/get-teachers-moderator",
{
params: query,
},
);

return res.data;
}

export async function getTeacherByIdApi(teacherId: string) {
const res = await apiPublic.get<TeacherType>(`/api/teachers/${teacherId}`);
return res.data;
}

export async function getTeacherByIdForModeratorApi(teacherId: string) {
const res = await apiProtected.get<TeacherType>(
`/api/teachers/${teacherId}/moderator`,
);
return res.data;
}

type ApiSlot = { start: string; end: string };
type ApiAvailability = {
monday: ApiSlot[];
Expand Down
16 changes: 15 additions & 1 deletion client/src/api/teacher/teacher.type.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { Role } from "../auth/types";

export type TeacherStatus =
| "draft"
| "pending"
| "active"
| "rejected"
| "blocked";
type EducationItem = {
degree: string;
institution: string;
Expand Down Expand Up @@ -58,6 +63,7 @@ export type TeacherType = {
availability: AvailabilityItem;
address: AddressItem;
createdAt: Date;
status: TeacherStatus;
role: Role;
};

Expand All @@ -71,6 +77,7 @@ export type TeacherOutputModel = {

export type SortDirection = "asc" | "desc";
export type SortBy = "createdAt" | "priceFrom" | "rating";
export type SortByTeachersForModerator = "status" | "createdAt";

export type TeachersQuery = {
subject?: string;
Expand All @@ -83,6 +90,13 @@ export type TeachersQuery = {
pageSize?: number;
};

export type TeachersForModeratorQuery = {
sortBy?: SortByTeachersForModerator;
sortDirection?: SortDirection;
pageNumber?: number;
pageSize?: number;
};

export type UpdateTeacherProfileInput = {
firstName?: string;
lastName?: string;
Expand Down
16 changes: 13 additions & 3 deletions client/src/components/cardsList/CardsList.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { TeacherCard } from "../teacherCard/teacherCard";
import { TeacherType } from "../../api/teacher/teacher.type";
import { TeacherStatus, TeacherType } from "../../api/teacher/teacher.type";
import { motion, type Variants, useReducedMotion } from "framer-motion";
import { useRef } from "react";
type CardsListType = {
cards: TeacherType[];
changeStatus?: (id: string, status: TeacherStatus) => void;
isStatusPending?: boolean;
};

export const CardsList = ({ cards }: CardsListType) => {
export const CardsList = ({
cards,
changeStatus,
isStatusPending,
}: CardsListType) => {
const reduceMotion = useReducedMotion();

const listVariants: Variants = {
Expand Down Expand Up @@ -44,7 +50,11 @@ export const CardsList = ({ cards }: CardsListType) => {
>
{cards.map((teacher) => (
<motion.div key={teacher.id} variants={itemVariants}>
<TeacherCard teacher={teacher} />
<TeacherCard
isStatusPending={isStatusPending}
changeStatus={changeStatus}
teacher={teacher}
/>
</motion.div>
))}
</motion.div>
Expand Down
15 changes: 15 additions & 0 deletions client/src/components/sidebar/sidebarMenuItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import Chat from "../icons/Chat";
import UsersIcon from "../icons/UsersIcon";
import {
chatRoutes,
moderatorBase,
moderatorPrivatesRoutesVariables,
studentBase,
studentPrivatesRoutesVariables,
teacherBase,
Expand Down Expand Up @@ -63,3 +65,16 @@ export const defaultTeacherMenuItems: MenuItem[] = [
icon: Chat,
},
];

export const defaultModeratorMenuItems: MenuItem[] = [
{
name: "Teachers",
link: joinPath(moderatorBase, moderatorPrivatesRoutesVariables.teachers),
icon: DashboardIcon,
},
{
name: "Chat",
link: joinPath(moderatorBase, chatRoutes.root),
icon: Chat,
},
];
37 changes: 37 additions & 0 deletions client/src/components/statusChanger/StatusChange.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
getStatusButtonClass,
statusOptions,
statusUi,
} from "../../util/statusButtons.tsx";
import { Button } from "../ui/button/Button.tsx";
import { TeacherStatus } from "../../api/teacher/teacher.type.ts";

type StatusChangeProps = {
id: string;
changeStatus: (id: string, status: TeacherStatus) => void;
status: TeacherStatus;
};

export const StatusChange = ({
changeStatus,
id,
status,
}: StatusChangeProps) => {
return (
<>
<div className="flex flex-wrap items-center gap-2">
{statusOptions.map((s) => (
<Button
key={s}
type="button"
variant="link"
className={getStatusButtonClass(s, s === status)}
onClick={() => changeStatus(id, s)}
>
{statusUi[s].label}
</Button>
))}
</div>
</>
);
};
Loading
Loading