diff --git a/lib/helpers/extendRequest.ts b/lib/helpers/extendRequest.ts index 8ed3ee0571..14de404418 100644 --- a/lib/helpers/extendRequest.ts +++ b/lib/helpers/extendRequest.ts @@ -15,8 +15,13 @@ declare module "next" { session: { user: { id: number } }; query: { [key: string]: string | string[] }; isAdmin: boolean; + pagination: { take: number; skip: number }; } } export const extendRequest: NextMiddleware = async (req, res, next) => { + req.pagination = { + take: 100, + skip: 0, + }; await next(); }; diff --git a/lib/helpers/withMiddleware.ts b/lib/helpers/withMiddleware.ts index ab6d5cb79e..9ce21233fb 100644 --- a/lib/helpers/withMiddleware.ts +++ b/lib/helpers/withMiddleware.ts @@ -1,4 +1,5 @@ import { label } from "next-api-middleware"; +import PagesManifestPlugin from "next/dist/build/webpack/plugins/pages-manifest-plugin"; import { addRequestId } from "./addRequestid"; import { captureErrors } from "./captureErrors"; @@ -13,6 +14,7 @@ import { HTTP_GET_DELETE_PATCH, } from "./httpMethods"; import { verifyApiKey } from "./verifyApiKey"; +import { withPagination } from "./withPagination"; const withMiddleware = label( { @@ -26,6 +28,7 @@ const withMiddleware = label( verifyApiKey, customPrismaClient, extendRequest, + pagination: withPagination, sentry: captureErrors, }, // The order here, determines the order of execution, put customPrismaClient before verifyApiKey always. diff --git a/lib/helpers/withPagination.ts b/lib/helpers/withPagination.ts new file mode 100644 index 0000000000..6d76c680f1 --- /dev/null +++ b/lib/helpers/withPagination.ts @@ -0,0 +1,12 @@ +import { NextMiddleware } from "next-api-middleware"; + +export const withPagination: NextMiddleware = async (req, res, next) => { + const { page } = req.query; + const pageNumber = parseInt(page as string); + const skip = pageNumber * 10; + req.pagination = { + take: 10, + skip: skip || 0, + }; + await next(); +}; diff --git a/lib/validations/user.ts b/lib/validations/user.ts index dcaafdf8d2..15a66ed371 100644 --- a/lib/validations/user.ts +++ b/lib/validations/user.ts @@ -153,6 +153,7 @@ export const schemaUserReadPublic = User.pick({ createdDate: true, verified: true, invitedTo: true, + role: true, }); export const schemaUsersReadPublic = z.array(schemaUserReadPublic); diff --git a/next.config.js b/next.config.js index 22ff466595..344d6fdef8 100644 --- a/next.config.js +++ b/next.config.js @@ -10,6 +10,7 @@ const withTM = require("next-transpile-modules")([ "@calcom/ui", "@calcom/emails", "@calcom/embed-core", + "@calcom/dayjs", "@calcom/embed-snippet", ]); diff --git a/pages/api/availability/_get.ts b/pages/api/availability/_get.ts index 21450f005e..c3edc816c4 100644 --- a/pages/api/availability/_get.ts +++ b/pages/api/availability/_get.ts @@ -1,3 +1,4 @@ +import { HttpError } from "@/../../packages/lib/http-error"; import type { NextApiRequest } from "next"; import { z } from "zod"; @@ -8,22 +9,42 @@ import { stringOrNumber } from "@calcom/prisma/zod-utils"; const availabilitySchema = z .object({ userId: stringOrNumber.optional(), + teamId: stringOrNumber.optional(), username: z.string().optional(), dateFrom: z.string(), dateTo: z.string(), eventTypeId: stringOrNumber.optional(), }) - .refine((data) => !!data.username || !!data.userId, "Either username or userId should be filled in."); + .refine( + (data) => !!data.username || !!data.userId || !!data.teamId, + "Either username or userId or teamId should be filled in." + ); async function handler(req: NextApiRequest) { - const { username, userId, eventTypeId, dateTo, dateFrom } = availabilitySchema.parse(req.query); - return getUserAvailability({ - username, - dateFrom, - dateTo, - eventTypeId, - userId, - }); + const { prisma, isAdmin } = req; + const { username, userId, eventTypeId, dateTo, dateFrom, teamId } = availabilitySchema.parse(req.query); + if (!teamId) + return getUserAvailability({ + username, + dateFrom, + dateTo, + eventTypeId, + userId, + }); + const team = await prisma.team.findUnique({ where: { id: teamId }, select: { members: true } }); + if (!team) throw new HttpError({ statusCode: 404, message: "teamId not found" }); + if (!team.members) throw new HttpError({ statusCode: 404, message: "teamId not found" }); + if (!isAdmin) throw new HttpError({ statusCode: 401, message: "Unauthorized" }); + return team.members.map( + async (user) => + await getUserAvailability({ + username, + dateFrom, + dateTo, + eventTypeId, + userId: user.userId, + }) + ); } export default defaultResponder(handler); diff --git a/pages/api/users/_get.ts b/pages/api/users/_get.ts index 67bb53e2d1..90a03e11d0 100644 --- a/pages/api/users/_get.ts +++ b/pages/api/users/_get.ts @@ -2,6 +2,7 @@ import type { NextApiRequest } from "next"; import { defaultResponder } from "@calcom/lib/server"; +import { withMiddleware } from "@lib/helpers/withMiddleware"; import { schemaUsersReadPublic } from "@lib/validations/user"; import { Prisma } from ".prisma/client"; @@ -23,13 +24,20 @@ import { Prisma } from ".prisma/client"; * description: No users were found */ async function getHandler(req: NextApiRequest) { - const { userId, prisma, isAdmin } = req; + const { + userId, + prisma, + isAdmin, + pagination: { take, skip }, + } = req; const where: Prisma.UserWhereInput = {}; // If user is not ADMIN, return only his data. if (!isAdmin) where.id = userId; - const data = await prisma.user.findMany({ where }); + const data = await prisma.user.findMany({ where, take, skip }); + console.log(data); const users = schemaUsersReadPublic.parse(data); + console.log(users); return { users }; } -export default defaultResponder(getHandler); +export default withMiddleware("pagination")(defaultResponder(getHandler));