calcom/apps/web/pages/d/[link]/[slug].tsx
Syed Ali Shahbaz 89b4acdfaf Hash my url (#2484)
* disposable link model added

* disposable model updated

* added disposable slug availability page

* added disposable book page

* added disposable slug hook

* added disposable link booking flow

* updated schema

* checktype fix

* added checkfix and schema generated

* create link API added

* added one time link view on event type list

* adjusted schema

* fixed disposable visual indicator

* expired check and visual indicator added

* updated slug for disposable event type

* revised schema

* WIP

* revert desc

* revert --WIP

* rework based on change of plans

* further adjustments

* added eventtype option for hashed link

* added refresh and delete on update

* fixed update call conditions

* cleanup

* code improvement

* clean up

* Potential fix for 404

* backward compat for booking page

* fixes regular booking for user and team

* typefix

* updated path for Booking import

* checkfix

* e2e wip

* link err fix

* workaround for banner issue in event type update-test

* added regenerate hash check

* fixed test according to new testID

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: zomars <zomars@me.com>
2022-05-02 16:21:11 -06:00

182 lines
4.2 KiB
TypeScript

import { Prisma } from "@prisma/client";
import { GetServerSidePropsContext } from "next";
import { JSONObject } from "superjson/dist/types";
import { asStringOrNull } from "@lib/asStringOrNull";
import { getWorkingHours } from "@lib/availability";
import { GetBookingType } from "@lib/getBooking";
import prisma from "@lib/prisma";
import { inferSSRProps } from "@lib/types/inferSSRProps";
import AvailabilityPage from "@components/booking/pages/AvailabilityPage";
import { ssrInit } from "@server/lib/ssr";
export type AvailabilityPageProps = inferSSRProps<typeof getServerSideProps>;
export default function Type(props: AvailabilityPageProps) {
return <AvailabilityPage {...props} />;
}
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const ssr = await ssrInit(context);
const link = asStringOrNull(context.query.link) || "";
const slug = asStringOrNull(context.query.slug) || "";
const dateParam = asStringOrNull(context.query.date);
const eventTypeSelect = Prisma.validator<Prisma.EventTypeSelect>()({
id: true,
title: true,
availability: true,
description: true,
length: true,
price: true,
currency: true,
periodType: true,
periodStartDate: true,
periodEndDate: true,
periodDays: true,
periodCountCalendarDays: true,
schedulingType: true,
userId: true,
schedule: {
select: {
availability: true,
timeZone: true,
},
},
hidden: true,
slug: true,
minimumBookingNotice: true,
beforeEventBuffer: true,
afterEventBuffer: true,
timeZone: true,
metadata: true,
slotInterval: true,
users: {
select: {
id: true,
avatar: true,
name: true,
username: true,
hideBranding: true,
plan: true,
timeZone: true,
},
},
});
const hashedLink = await prisma.hashedLink.findUnique({
where: {
link,
},
select: {
eventTypeId: true,
eventType: {
select: eventTypeSelect,
},
},
});
const userId = hashedLink?.eventType.userId || hashedLink?.eventType.users[0]?.id;
if (!userId)
return {
notFound: true,
};
if (hashedLink?.eventType.slug !== slug)
return {
notFound: true,
};
const users = await prisma.user.findMany({
where: {
id: userId,
},
select: {
id: true,
username: true,
name: true,
email: true,
bio: true,
avatar: true,
startTime: true,
endTime: true,
timeZone: true,
weekStart: true,
availability: true,
hideBranding: true,
brandColor: true,
darkBrandColor: true,
defaultScheduleId: true,
allowDynamicBooking: true,
away: true,
schedules: {
select: {
availability: true,
timeZone: true,
id: true,
},
},
theme: true,
plan: true,
},
});
if (!users || !users.length) {
return {
notFound: true,
};
}
const [user] = users;
const eventTypeObject = Object.assign({}, hashedLink.eventType, {
metadata: {} as JSONObject,
periodStartDate: hashedLink.eventType.periodStartDate?.toString() ?? null,
periodEndDate: hashedLink.eventType.periodEndDate?.toString() ?? null,
slug,
});
const schedule = {
...user.schedules.filter(
(schedule) => !user.defaultScheduleId || schedule.id === user.defaultScheduleId
)[0],
};
const timeZone = schedule.timeZone || user.timeZone;
const workingHours = getWorkingHours(
{
timeZone,
},
schedule.availability || user.availability
);
eventTypeObject.schedule = null;
eventTypeObject.availability = [];
let booking: GetBookingType | null = null;
const profile = {
name: user.name || user.username,
image: user.avatar,
slug: user.username,
theme: user.theme,
weekStart: user.weekStart,
brandColor: user.brandColor,
darkBrandColor: user.darkBrandColor,
};
return {
props: {
away: user.away,
isDynamicGroup: false,
profile,
plan: user.plan,
date: dateParam,
eventType: eventTypeObject,
workingHours,
trpcState: ssr.dehydrate(),
previousPage: context.req.headers.referer ?? null,
booking,
},
};
};