import { z } from "zod" import * as api from "@/lib/api" import { badRequestError, forbiddenError, internalServerError, unauthorizedError, } from "@/server/errors/trpc" import { protectedProcedure, router } from "@/server/trpc" import { soonestUpcomingStaysInput, staysInput } from "./input" import { getUserSchema } from "./output" import { benefits, extendedUser, nextLevelPerks, previousStays, upcomingStays, } from "./temp" function fakingRequest(payload: T): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(payload) }, 1500) }) } export const userQueryRouter = router({ get: protectedProcedure.query(async function ({ ctx }) { try { const apiResponse = await api.get(api.endpoints.v0.profile, { cache: "no-store", headers: { Authorization: `Bearer ${ctx.session.token.access_token}`, }, }) if (!apiResponse.ok) { switch (apiResponse.status) { case 400: throw badRequestError() case 401: throw unauthorizedError() case 403: throw forbiddenError() default: throw internalServerError() } } const apiJson = await apiResponse.json() if (!apiJson.data?.length) { throw internalServerError() } const verifiedData = getUserSchema.safeParse(apiJson.data[0].attributes) if (!verifiedData.success) { console.info(`Get User - Verified Data Error`) console.error(verifiedData.error) throw badRequestError() } return { ...extendedUser, ...verifiedData.data, firstName: verifiedData.data.name, name: `${verifiedData.data.name} ${verifiedData.data.lastName}`, } } catch (error) { console.info(`Get User Error`) console.error(error) throw internalServerError() } }), benefits: router({ current: protectedProcedure.query(async function (opts) { // TODO: Make request to get user data from Scandic API return await fakingRequest(benefits) }), nextLevel: protectedProcedure.query(async function (opts) { // TODO: Make request to get user data from Scandic API return await fakingRequest(nextLevelPerks) }), }), stays: router({ soonestUpcoming: protectedProcedure .input(soonestUpcomingStaysInput) .query(async ({ input }) => { return upcomingStays.slice(0, input.limit) }), previous: protectedProcedure.input(staysInput).query(async (opts) => { const { perPage, page, cursor } = opts.input let nextCursor: typeof cursor | undefined = undefined const nrPages = Math.ceil(previousStays.length / perPage) let stays, nextPage if (cursor) { stays = previousStays.slice(cursor, perPage + cursor + 1) nextPage = cursor / perPage + 1 } else { stays = previousStays.slice( page * perPage, page * perPage + perPage + 1 ) } if ( (nextPage && nextPage < nrPages && stays.length == perPage + 1) || (!nextPage && nrPages > 1) ) { const nextItem = stays.pop() if (nextItem) { nextCursor = previousStays.indexOf(nextItem) } } // TODO: Make request to get user data from Scandic API return { data: stays, nextCursor } }), upcoming: protectedProcedure.input(staysInput).query(async (opts) => { const { perPage, page, cursor } = opts.input let nextCursor: typeof cursor | undefined = undefined const nrPages = Math.ceil(upcomingStays.length / perPage) let stays, nextPage if (cursor) { stays = upcomingStays.slice(cursor, perPage + cursor + 1) nextPage = cursor / perPage + 1 } else { stays = upcomingStays.slice( page * perPage, page * perPage + perPage + 1 ) } if ( (nextPage && nextPage < nrPages && stays.length == perPage + 1) || (!nextPage && nrPages > 1) ) { const nextItem = stays.pop() if (nextItem) { nextCursor = upcomingStays.indexOf(nextItem) } } // TODO: Make request to get user data from Scandic API return { data: stays, nextCursor } }), }), })