diff --git a/server/src/handlers/tutor.ts b/server/src/handlers/tutor.ts index 8fda6153..d4af2692 100644 --- a/server/src/handlers/tutor.ts +++ b/server/src/handlers/tutor.ts @@ -80,7 +80,7 @@ async function getTutors(req: Request, res: Response, next: NextFunction) { if (!allowed) return next(forbidden()); const filter = httpQueryFilter( - tutors.columns.filterable as NonEmptyList, + tutors.columns.fullTutorFields.filterable as NonEmptyList, req.query ); @@ -107,8 +107,20 @@ async function delete_(req: Request, res: Response, next: NextFunction) { } async function getTutorsMedia(req: Request, res: Response, next: NextFunction) { - const list = await tutors.findTutorsMedia(); - res.status(200).json(list); + const allowed = enforceRequest(req); + if (!allowed) return next(forbidden()); + + const filter = httpQueryFilter( + tutors.columns.tutorMediaFields.filterable as NonEmptyList, + req.query + ); + + const [list, total] = await Promise.all([ + tutors.findTutorsMedia(filter), + count(tutors.table), + ]); + + res.status(200).json({ list, total }); } async function getTutorMediaById( diff --git a/server/src/models/tutors.ts b/server/src/models/tutors.ts index 97e4c2aa..b493e201 100644 --- a/server/src/models/tutors.ts +++ b/server/src/models/tutors.ts @@ -3,12 +3,12 @@ import { first, isEmpty, omit } from "lodash"; import { IUser, ITutor, IFilter } from "@litespace/types"; import { isValuedObject } from "@/lib/utils"; +type TutorMediaFieldsMap = Record; +type FullTutorFieldsMap = Record; type FullTutorFields = Omit & { password: string; }; -type FullTutorFieldsMap = Record; - const fullTutorFields: FullTutorFieldsMap = { id: "users.id", email: "users.email", @@ -34,16 +34,38 @@ const fullTutorFields: FullTutorFieldsMap = { mediaProviderId: "tutors.media_provider_id", } as const; +const tutorMediaFields: TutorMediaFieldsMap = { + id: "users.id", + email: "users.email", + name: "users.name", + photo: "users.photo", + video: "tutors.video", +} as const; + export class Tutors { table = "tutors"; columns: { - fullTutorFields: FullTutorFieldsMap; - filterable: Array; + fullTutorFields: { + map: FullTutorFieldsMap; + filterable: Array; + }; + tutorMediaFields: { + map: TutorMediaFieldsMap; + filterable: Array; + }; } = { - fullTutorFields, - filterable: Object.values(omit(fullTutorFields, "password")) as Array< - keyof FullTutorFields - >, + fullTutorFields: { + map: fullTutorFields, + filterable: Object.values(omit(fullTutorFields, "password")) as Array< + keyof FullTutorFields + >, + }, + tutorMediaFields: { + map: tutorMediaFields, + filterable: Object.values(tutorMediaFields) as Array< + keyof TutorMediaFieldsMap + >, + }, }; async create( @@ -137,12 +159,12 @@ export class Tutors { } async findByEmail(email: string): Promise { - const tutors = await this.getSelectQuery().where("email", email).limit(1); + const tutors = await this.fullTutorQuery().where("email", email).limit(1); return first(tutors) || null; } async findById(id: number): Promise { - const tutors = await this.getSelectQuery().where("tutors.id", id).limit(1); + const tutors = await this.fullTutorQuery().where("tutors.id", id).limit(1); return first(tutors) || null; } @@ -153,62 +175,40 @@ export class Tutors { async find(filter?: IFilter.Self): Promise { return await withFilter({ - builder: this.getSelectQuery(), + builder: this.fullTutorQuery(), + defaults: { + search: { columns: this.columns.fullTutorFields.filterable }, + }, filter, - defaults: { search: { columns: this.columns.filterable } }, }).then(); } - async findTutorsMedia(): Promise { - return await knex("users") - .select({ - id: "users.id", - email: "users.email", - name: "users.name", - photo: "users.photo", - video: "tutors.video", - }) + async findTutorsMedia(filter?: IFilter.Self): Promise { + const builder = knex("users") + .select(this.columns.tutorMediaFields.map) .innerJoin("tutors", "users.id", "tutors.id"); + + return withFilter({ + builder, + filter, + defaults: { + search: { columns: this.columns.tutorMediaFields.filterable }, + }, + }); } async findTutorMediaById(id: number): Promise { const list = await knex("users") - .select({ - id: "users.id", - email: "users.email", - name: "users.name", - photo: "users.photo", - video: "tutors.video", - }) + .select(this.columns.tutorMediaFields.map) .innerJoin("tutors", "users.id", "tutors.id") .where("users.id", id); return first(list) || null; } - getSelectQuery() { + fullTutorQuery() { return knex - .select({ - id: "users.id", - email: "users.email", - name: "users.name", - photo: "users.photo", - role: "users.role", - // birthday: "users.birthday", - gender: "users.gender", - online: "users.online", - createdAt: "users.created_at", - updatedAt: "users.updated_at", - metaUpdatedAt: "tutors.updated_at", - bio: "tutors.bio", - about: "tutors.about", - video: "tutors.video", - activated: "tutors.activated", - activatedBy: "tutors.activated_by", - passedInterview: "tutors.passed_interview", - interviewUrl: "tutors.interview_url", - meidaProviderId: "tutors.media_provider_id", - }) + .select(this.columns.fullTutorFields.map) .from("users") .innerJoin("tutors", "users.id", "tutors.id") .clone();