chore: Remove Pages Router / Render App Router - /video (#16518)

* /video: Remove Pages Router / Render App Router

* fix

* add meeting_unavailable i18n

* remove <Head> from videos view

* add correct metadata to video/[uid]

* add safety to videos-single-view logic

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
This commit is contained in:
Benny Joo
2024-12-11 18:51:30 +01:00
committed by GitHub
co-authored by Udit Takkar
parent 0eb72d66a7
commit 1a4afe06c8
17 changed files with 123 additions and 163 deletions
+1 -1
View File
@@ -358,7 +358,7 @@ APP_ROUTER_APPS_CATEGORIES_CATEGORY_ENABLED=0
APP_ROUTER_BOOKING_ENABLED=0
APP_ROUTER_BOOKINGS_STATUS_ENABLED=0
APP_ROUTER_GETTING_STARTED_STEP_ENABLED=0
APP_ROUTER_VIDEO_ENABLED=0
APP_ROUTER_APPS_ENABLED=0
APP_ROUTER_TEAM_ENABLED=0
APP_ROUTER_TEAMS_ENABLED=0
APP_ROUTER_AVAILABILITY_ENABLED=0
-1
View File
@@ -23,7 +23,6 @@ const ROUTES: [URLPattern, boolean][] = [
["/getting-started/:step", process.env.APP_ROUTER_GETTING_STARTED_STEP_ENABLED === "1"] as const,
["/bookings/:status", process.env.APP_ROUTER_BOOKINGS_STATUS_ENABLED === "1"] as const,
["/booking/:path*", process.env.APP_ROUTER_BOOKING_ENABLED === "1"] as const,
["/video/:path*", process.env.APP_ROUTER_VIDEO_ENABLED === "1"] as const,
["/team", process.env.APP_ROUTER_TEAM_ENABLED === "1"] as const,
["/teams", process.env.APP_ROUTER_TEAMS_ENABLED === "1"] as const,
["/availability", process.env.APP_ROUTER_AVAILABILITY_ENABLED === "1"] as const,
-20
View File
@@ -1,20 +0,0 @@
import { withAppDirSsr } from "app/WithAppDirSsr";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import { APP_NAME } from "@calcom/lib/constants";
import { getServerSideProps } from "@lib/video/[uid]/getServerSideProps";
import type { PageProps } from "~/videos/views/videos-single-view";
import VideosSingleView from "~/videos/views/videos-single-view";
export const generateMetadata = async () =>
await _generateMetadata(
() => `${APP_NAME} Video`,
(t) => t("quick_video_meeting")
);
const getData = withAppDirSsr<PageProps>(getServerSideProps);
export default WithLayout({ getData, Page: VideosSingleView, getLayout: null })<"P">;
+39
View File
@@ -0,0 +1,39 @@
import { withAppDirSsr } from "app/WithAppDirSsr";
import { getTranslate } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import { APP_NAME, SEO_IMG_OGIMG_VIDEO, WEBSITE_URL } from "@calcom/lib/constants";
import { getServerSideProps } from "@lib/video/[uid]/getServerSideProps";
import type { PageProps } from "~/videos/views/videos-single-view";
import VideosSingleView from "~/videos/views/videos-single-view";
export const generateMetadata = async () => {
const t = await getTranslate();
return {
title: `${APP_NAME} Video`,
description: t("quick_video_meeting"),
openGraph: {
title: `${APP_NAME} Video`,
description: t("quick_video_meeting"),
url: `${WEBSITE_URL}/video`,
images: [
{
url: SEO_IMG_OGIMG_VIDEO,
},
],
type: "website",
},
twitter: {
card: "summary_large_image",
title: `${APP_NAME} Video`,
description: t("quick_video_meeting"),
images: [SEO_IMG_OGIMG_VIDEO],
},
};
};
const getData = withAppDirSsr<PageProps>(getServerSideProps);
export default WithLayout({ getData, Page: VideosSingleView, getLayout: null })<"P">;
@@ -9,8 +9,8 @@ import MeetingEnded from "~/videos/views/videos-meeting-ended-single-view";
export const generateMetadata = async () =>
await _generateMetadata(
() => "Meeting Unavailable",
() => "Meeting Unavailable"
(t) => t("meeting_unavailable"),
(t) => t("meeting_unavailable")
);
const getData = withAppDirSsr<PageProps>(getServerSideProps);
-1
View File
@@ -183,7 +183,6 @@ export const config = {
"/bookings/:status/",
"/future/bookings/:status/",
"/video/:path*",
"/future/video/:path*",
"/teams",
"/future/teams/",
"/settings/:path*",
@@ -14,7 +14,7 @@ export default function MeetingUnavailable(props: PageProps) {
return (
<div>
<HeadSeo title="Meeting Unavailable" description="Meeting Unavailable" />
<HeadSeo title={t("meeting_unavailable")} description={t("meeting_unavailable")} />
<main className="mx-auto my-24 max-w-3xl">
<div className="fixed inset-0 z-50 overflow-y-auto">
<div className="flex min-h-screen items-end justify-center px-4 pb-20 pt-4 text-center sm:block sm:p-0">
@@ -3,12 +3,11 @@
import type { DailyCall } from "@daily-co/daily-js";
import DailyIframe from "@daily-co/daily-js";
import { DailyProvider } from "@daily-co/daily-react";
import Head from "next/head";
import { useState, useEffect, useRef } from "react";
import dayjs from "@calcom/dayjs";
import classNames from "@calcom/lib/classNames";
import { APP_NAME, SEO_IMG_OGIMG_VIDEO, WEBSITE_URL } from "@calcom/lib/constants";
import { WEBSITE_URL } from "@calcom/lib/constants";
import { TRANSCRIPTION_STOPPED_ICON, RECORDING_DEFAULT_ICON } from "@calcom/lib/constants";
import { formatToLocalizedDate, formatToLocalizedTime } from "@calcom/lib/date-fns";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -23,111 +22,98 @@ import { CalAiTranscribe } from "~/videos/ai/ai-transcribe";
export type PageProps = inferSSRProps<typeof getServerSideProps>;
export default function JoinCall(props: PageProps) {
const { t } = useLocale();
const { meetingUrl, meetingPassword, booking, hasTeamPlan, calVideoLogo } = props;
const [daily, setDaily] = useState<DailyCall | null>(null);
useEffect(() => {
const callFrame = DailyIframe.createFrame({
theme: {
colors: {
accent: "#FFF",
accentText: "#111111",
background: "#111111",
backgroundAccent: "#111111",
baseText: "#FFF",
border: "#292929",
mainAreaBg: "#111111",
mainAreaBgAccent: "#1A1A1A",
mainAreaText: "#FFF",
supportiveText: "#FFF",
},
},
showLeaveButton: true,
iframeStyle: {
position: "fixed",
width: "100%",
height: "100%",
},
url: meetingUrl,
...(typeof meetingPassword === "string" && { token: meetingPassword }),
...(hasTeamPlan && {
customTrayButtons: {
recording: {
label: "Record",
tooltip: "Start or stop recording",
iconPath: RECORDING_DEFAULT_ICON,
iconPathDarkMode: RECORDING_DEFAULT_ICON,
},
transcription: {
label: "Cal.ai",
tooltip: "Transcription powered by AI",
iconPath: TRANSCRIPTION_STOPPED_ICON,
iconPathDarkMode: TRANSCRIPTION_STOPPED_ICON,
let callFrame: DailyCall | undefined;
try {
callFrame = DailyIframe.createFrame({
theme: {
colors: {
accent: "#FFF",
accentText: "#111111",
background: "#111111",
backgroundAccent: "#111111",
baseText: "#FFF",
border: "#292929",
mainAreaBg: "#111111",
mainAreaBgAccent: "#1A1A1A",
mainAreaText: "#FFF",
supportiveText: "#FFF",
},
},
}),
});
showLeaveButton: true,
iframeStyle: {
position: "fixed",
width: "100%",
height: "100%",
},
url: meetingUrl,
...(typeof meetingPassword === "string" && { token: meetingPassword }),
...(hasTeamPlan && {
customTrayButtons: {
recording: {
label: "Record",
tooltip: "Start or stop recording",
iconPath: RECORDING_DEFAULT_ICON,
iconPathDarkMode: RECORDING_DEFAULT_ICON,
},
transcription: {
label: "Cal.ai",
tooltip: "Transcription powered by AI",
iconPath: TRANSCRIPTION_STOPPED_ICON,
iconPathDarkMode: TRANSCRIPTION_STOPPED_ICON,
},
},
}),
});
} catch (err) {
callFrame = DailyIframe.getCallInstance();
} finally {
setDaily(callFrame ?? null);
setDaily(callFrame);
callFrame.join();
callFrame?.join();
}
return () => {
callFrame.destroy();
callFrame?.destroy();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const title = `${APP_NAME} Video`;
return (
<>
<Head>
<title>{title}</title>
<meta name="description" content={t("quick_video_meeting")} />
<meta property="og:image" content={SEO_IMG_OGIMG_VIDEO} />
<meta property="og:type" content="website" />
<meta property="og:url" content={`${WEBSITE_URL}/video`} />
<meta property="og:title" content={`${APP_NAME} Video`} />
<meta property="og:description" content={t("quick_video_meeting")} />
<meta property="twitter:image" content={SEO_IMG_OGIMG_VIDEO} />
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={`${WEBSITE_URL}/video`} />
<meta property="twitter:title" content={`${APP_NAME} Video`} />
<meta property="twitter:description" content={t("quick_video_meeting")} />
</Head>
<DailyProvider callObject={daily}>
<div
className="mx-auto hidden sm:block"
style={{ zIndex: 2, left: "30%", position: "absolute", bottom: 100, width: "auto" }}>
<CalAiTranscribe />
</div>
<div style={{ zIndex: 2, position: "relative" }}>
{calVideoLogo ? (
<img
className="min-w-16 min-h-16 fixed z-10 hidden aspect-square h-16 w-16 rounded-full sm:inline-block"
src={calVideoLogo}
alt="My Org Logo"
style={{
top: 32,
left: 32,
}}
/>
) : (
<img
className="fixed z-10 hidden h-5 sm:inline-block"
src={`${WEBSITE_URL}/cal-logo-word-dark.svg`}
alt="Logo"
style={{
top: 47,
left: 20,
}}
/>
)}
</div>
<VideoMeetingInfo booking={booking} />
</DailyProvider>
</>
<DailyProvider callObject={daily}>
<div
className="mx-auto hidden sm:block"
style={{ zIndex: 2, left: "30%", position: "absolute", bottom: 100, width: "auto" }}>
<CalAiTranscribe />
</div>
<div style={{ zIndex: 2, position: "relative" }}>
{calVideoLogo ? (
<img
className="min-w-16 min-h-16 fixed z-10 hidden aspect-square h-16 w-16 rounded-full sm:inline-block"
src={calVideoLogo}
alt="My Org Logo"
style={{
top: 32,
left: 32,
}}
/>
) : (
<img
className="fixed z-10 hidden h-5 sm:inline-block"
src={`${WEBSITE_URL}/cal-logo-word-dark.svg`}
alt="Logo"
style={{
top: 47,
left: 20,
}}
/>
)}
</div>
<VideoMeetingInfo booking={booking} />
</DailyProvider>
);
}
-11
View File
@@ -1,11 +0,0 @@
import PageWrapper from "@components/PageWrapper";
import VideosSingleView, { type PageProps } from "~/videos/views/videos-single-view";
export { getServerSideProps } from "@lib/video/[uid]/getServerSideProps";
const VideosSinglePage = (props: PageProps) => <VideosSingleView {...props} />;
VideosSinglePage.PageWrapper = PageWrapper;
export default VideosSinglePage;
@@ -1,11 +0,0 @@
import PageWrapper from "@components/PageWrapper";
import MeetingEnded, { type PageProps } from "~/videos/views/videos-meeting-ended-single-view";
export { getServerSideProps } from "@lib/video/meeting-ended/[uid]/getServerSideProps";
const MeetingEndedPage = (props: PageProps) => <MeetingEnded {...props} />;
MeetingEndedPage.PageWrapper = PageWrapper;
export default MeetingEndedPage;
@@ -1,11 +0,0 @@
import PageWrapper from "@components/PageWrapper";
import MeetingNotStarted, { type PageProps } from "~/videos/views/videos-meeting-not-started-single-view";
export { getServerSideProps } from "@lib/video/meeting-not-started/[uid]/getServerSideProps";
const MeetingNotStartedPage = (props: PageProps) => <MeetingNotStarted {...props} />;
MeetingNotStartedPage.PageWrapper = PageWrapper;
export default MeetingNotStartedPage;
@@ -1,9 +0,0 @@
import PageWrapper from "@components/PageWrapper";
import NoMeetingFound from "~/videos/views/videos-no-meeting-found-single-view";
const NoMeetingFoundPage = () => <NoMeetingFound />;
NoMeetingFoundPage.PageWrapper = PageWrapper;
export default NoMeetingFoundPage;
@@ -2290,6 +2290,7 @@
"most_popular_events": "Most Popular Events",
"summary_of_events_for_your_team_for_the_last_30_days": "Here's your summary of popular events for your team {{teamName}} for the last 30 days",
"me": "Me",
"meeting_unavailable": "Meeting Unavailable",
"monthly_digest_email": "Monthly digest email",
"monthly_digest_email_for_teams": "Monthly digest email for teams",
"verify_team_tooltip": "Verify your team to enable sending messages to attendees",
@@ -24,7 +24,6 @@ checkRoute "$APP_ROUTER_AUTH_OAUTH2_ENABLED" app/future/auth/oauth2
checkRoute "$APP_ROUTER_GETTING_STARTED_STEP_ENABLED" app/future/getting-started
checkRoute "$APP_ROUTER_BOOKINGS_STATUS_ENABLED" app/future/bookings
checkRoute "$APP_ROUTER_BOOKING_ENABLED" app/future/booking
checkRoute "$APP_ROUTER_VIDEO_ENABLED" app/future/video
checkRoute "$APP_ROUTER_TEAM_ENABLED" app/future/team
checkRoute "$APP_ROUTER_TEAMS_ENABLED" app/future/teams
-1
View File
@@ -241,7 +241,6 @@
"APP_ROUTER_BOOKINGS_STATUS_ENABLED",
"APP_ROUTER_EVENT_TYPES_ENABLED",
"APP_ROUTER_GETTING_STARTED_STEP_ENABLED",
"APP_ROUTER_VIDEO_ENABLED",
"APP_ROUTER_AUTH_FORGOT_PASSWORD_ENABLED",
"APP_ROUTER_AUTH_LOGIN_ENABLED",
"APP_ROUTER_AUTH_LOGOUT_ENABLED",