chore: [app-router-migration 18] Migrate "/settings/organizations/*" pages (#13042)

* manual: app-directory-boilerplate-calcom

* manual: import components directly

* manual: move files to correct route groups and add metadata

* manual: Change structure & Refactor to make code up to date

* manual: refactors

* Fix

* manual: fix type of arg of getData

* manual: fix type error

* fix type bugs

* fix

* fixing the build

* wip

---------

Co-authored-by: Greg Pabian <35925521+grzpab@users.noreply.github.com>
This commit is contained in:
Benny Joo 2024-01-12 18:32:39 +00:00 committed by GitHub
parent 65d9704f2b
commit 0bdc45a1a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 428 additions and 43 deletions

View File

@ -1,13 +1,12 @@
import LegacyPage from "@pages/apps/categories/index";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { getAppRegistry, getAppRegistryWithCredentials } from "@calcom/app-store/_appRegistry";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { APP_NAME } from "@calcom/lib/constants";
import type { buildLegacyCtx } from "@lib/buildLegacyCtx";
import { ssrInit } from "@server/lib/ssr";
export const generateMetadata = async () => {
@ -17,11 +16,9 @@ export const generateMetadata = async () => {
);
};
const getData = async (ctx: ReturnType<typeof buildLegacyCtx>) => {
// @ts-expect-error Argument of type '{ query: Params; params: Params; req: { headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }; }' is not assignable to parameter of type 'GetServerSidePropsContext'.
const getData = async (ctx: GetServerSidePropsContext) => {
const ssr = await ssrInit(ctx);
// @ts-expect-error Type '{ headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }' is not assignable to type 'NextApiRequest | IncomingMessage
const session = await getServerSession({ req: ctx.req });
let appStore;

View File

@ -1,6 +1,7 @@
import AppsPage from "@pages/apps";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { getAppRegistry, getAppRegistryWithCredentials } from "@calcom/app-store/_appRegistry";
import { getLayout } from "@calcom/features/MainLayoutAppDir";
@ -10,8 +11,6 @@ import getUserAdminTeams from "@calcom/features/ee/teams/lib/getUserAdminTeams";
import { APP_NAME } from "@calcom/lib/constants";
import type { AppCategories } from "@calcom/prisma/enums";
import type { buildLegacyCtx } from "@lib/buildLegacyCtx";
import { ssrInit } from "@server/lib/ssr";
export const generateMetadata = async () => {
@ -21,11 +20,9 @@ export const generateMetadata = async () => {
);
};
const getData = async (ctx: ReturnType<typeof buildLegacyCtx>) => {
// @ts-expect-error Argument of type '{ query: Params; params: Params; req: { headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }; }' is not assignable to parameter of type 'GetServerSidePropsContext'.
const getData = async (ctx: GetServerSidePropsContext) => {
const ssr = await ssrInit(ctx);
// @ts-expect-error Type '{ headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }' is not assignable to type 'NextApiRequest
const session = await getServerSession({ req: ctx.req });
let appStore, userAdminTeams: UserAdminTeams;

View File

@ -1,13 +1,12 @@
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { notFound } from "next/navigation";
import { z } from "zod";
import { getLayout } from "@calcom/features/MainLayoutAppDir";
import { APP_NAME } from "@calcom/lib/constants";
import type { buildLegacyCtx } from "@lib/buildLegacyCtx";
import { ssgInit } from "@server/lib/ssg";
const validStatuses = ["upcoming", "recurring", "past", "cancelled", "unconfirmed"] as const;
@ -26,7 +25,7 @@ export const generateStaticParams = async () => {
return validStatuses.map((status) => ({ status }));
};
const getData = async (ctx: ReturnType<typeof buildLegacyCtx>) => {
const getData = async (ctx: GetServerSidePropsContext) => {
const parsedParams = querySchema.safeParse(ctx.params);
if (!parsedParams.success) {

View File

@ -1,16 +1,15 @@
import LegacyPage from "@pages/getting-started/[[...step]]";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { cookies, headers } from "next/headers";
import { redirect } from "next/navigation";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import prisma from "@calcom/prisma";
import type { buildLegacyCtx } from "@lib/buildLegacyCtx";
import { ssrInit } from "@server/lib/ssr";
const getData = async (ctx: ReturnType<typeof buildLegacyCtx>) => {
const getData = async (ctx: GetServerSidePropsContext) => {
const req = { headers: headers(), cookies: cookies() };
//@ts-expect-error Type '{ headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }' is not assignable to type 'NextApiRequest
@ -19,7 +18,6 @@ const getData = async (ctx: ReturnType<typeof buildLegacyCtx>) => {
if (!session?.user?.id) {
return redirect("/auth/login");
}
// @ts-expect-error Argument of type '{ query: Params; params: Params; req: { headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }; }' is not assignable to parameter of type 'GetServerSidePropsContext'.
const ssr = await ssrInit(ctx);
await ssr.viewer.me.prefetch();
@ -54,7 +52,7 @@ const getData = async (ctx: ReturnType<typeof buildLegacyCtx>) => {
return {
dehydratedState: ssr.dehydrate(),
hasPendingInvites: user.teams.find((team: any) => team.accepted === false) ?? false,
hasPendingInvites: user.teams.find((team) => team.accepted === false) ?? false,
requiresLicense: false,
themeBasis: null,
};

View File

@ -0,0 +1,11 @@
import LegacyPage, { WrappedAboutOrganizationPage } from "@pages/settings/organizations/[id]/about";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("about_your_organization"),
(t) => t("about_your_organization_description")
);
export default WithLayout({ Page: LegacyPage, getLayout: WrappedAboutOrganizationPage });

View File

@ -0,0 +1,11 @@
import LegacyPage, { WrapperAddNewTeamsPage } from "@pages/settings/organizations/[id]/add-teams";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("create_your_teams"),
(t) => t("create_your_teams_description")
);
export default WithLayout({ Page: LegacyPage, getLayout: WrapperAddNewTeamsPage });

View File

@ -0,0 +1,35 @@
import LegacyPage, {
buildWrappedOnboardTeamMembersPage,
} from "@pages/settings/organizations/[id]/onboard-admins";
import { type Params } from "app/_types";
import { _generateMetadata } from "app/_utils";
import { headers } from "next/headers";
import PageWrapper from "@components/PageWrapperAppDir";
type PageProps = Readonly<{
params: Params;
}>;
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("invite_organization_admins"),
(t) => t("invite_organization_admins_description")
);
const Page = ({ params }: PageProps) => {
const h = headers();
const nonce = h.get("x-nonce") ?? undefined;
return (
<PageWrapper
getLayout={(page: React.ReactElement) => buildWrappedOnboardTeamMembersPage(params.id, page)}
requiresLicense={false}
nonce={nonce}
themeBasis={null}>
<LegacyPage />
</PageWrapper>
);
};
export default Page;

View File

@ -0,0 +1,11 @@
import LegacyPage, { WrappedSetPasswordPage } from "@pages/settings/organizations/[id]/set-password";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("set_a_password"),
(t) => t("set_a_password_description")
);
export default WithLayout({ Page: LegacyPage, getLayout: WrappedSetPasswordPage });

View File

@ -0,0 +1,5 @@
import { WithLayout } from "app/layoutHOC";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
export default WithLayout({ getLayout });

View File

@ -0,0 +1,11 @@
import { _generateMetadata } from "app/_utils";
import Page from "@calcom/features/ee/organizations/pages/settings/appearance";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("appearance"),
(t) => t("appearance_org_description")
);
export default Page;

View File

@ -0,0 +1,5 @@
import { WithLayout } from "app/layoutHOC";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
export default WithLayout({ getLayout });

View File

@ -0,0 +1,10 @@
import Page from "@pages/settings/billing/index";
import { _generateMetadata } from "app/_utils";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("billing"),
(t) => t("manage_billing_description")
);
export default Page;

View File

@ -0,0 +1,5 @@
import { WithLayout } from "app/layoutHOC";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
export default WithLayout({ getLayout });

View File

@ -0,0 +1,11 @@
import { _generateMetadata } from "app/_utils";
import Page from "@calcom/features/ee/organizations/pages/settings/general";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("general"),
(t) => t("general_description")
);
export default Page;

View File

@ -0,0 +1,5 @@
import { WithLayout } from "app/layoutHOC";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
export default WithLayout({ getLayout });

View File

@ -0,0 +1,11 @@
import { _generateMetadata } from "app/_utils";
import Page from "@calcom/features/ee/organizations/pages/settings/members";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("organization_members"),
(t) => t("organization_description")
);
export default Page;

View File

@ -0,0 +1,34 @@
import LegacyPage, { WrappedCreateNewOrganizationPage } from "@pages/settings/organizations/new/index";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import { type GetServerSidePropsContext } from "next";
import { notFound } from "next/navigation";
import { getFeatureFlagMap } from "@calcom/features/flags/server/utils";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("set_up_your_organization"),
(t) => t("organizations_description")
);
const getPageProps = async (context: GetServerSidePropsContext) => {
const prisma = await import("@calcom/prisma").then((mod) => mod.default);
const flags = await getFeatureFlagMap(prisma);
// Check if organizations are enabled
if (flags["organizations"] !== true) {
return notFound();
}
const querySlug = context.query.slug as string;
return {
querySlug: querySlug ?? null,
};
};
export default WithLayout({
getLayout: WrappedCreateNewOrganizationPage,
Page: LegacyPage,
getData: getPageProps,
});

View File

@ -0,0 +1,5 @@
import { WithLayout } from "app/layoutHOC";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
export default WithLayout({ getLayout });

View File

@ -0,0 +1,11 @@
import { _generateMetadata } from "app/_utils";
import Page from "@calcom/features/ee/organizations/pages/settings/profile";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("profile"),
(t) => t("profile_org_description")
);
export default Page;

View File

@ -0,0 +1,5 @@
import { WithLayout } from "app/layoutHOC";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
export default WithLayout({ getLayout });

View File

@ -0,0 +1,11 @@
import { _generateMetadata } from "app/_utils";
import Page from "@calcom/features/ee/teams/pages/team-appearance-view";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("booking_appearance"),
(t) => t("appearance_team_description")
);
export default Page;

View File

@ -0,0 +1,5 @@
import { WithLayout } from "app/layoutHOC";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
export default WithLayout({ getLayout });

View File

@ -0,0 +1,11 @@
import { _generateMetadata } from "app/_utils";
import Page from "@calcom/features/ee/organizations/pages/settings/other-team-members-view";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("team_members"),
(t) => t("members_team_description")
);
export default Page;

View File

@ -0,0 +1,5 @@
import { WithLayout } from "app/layoutHOC";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
export default WithLayout({ getLayout });

View File

@ -0,0 +1,11 @@
import { _generateMetadata } from "app/_utils";
import Page from "@calcom/features/ee/organizations/pages/settings/other-team-profile-view";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("profile"),
(t) => t("profile_team_description")
);
export default Page;

View File

@ -0,0 +1,5 @@
import { WithLayout } from "app/layoutHOC";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayoutAppDir";
export default WithLayout({ getLayout });

View File

@ -0,0 +1,11 @@
import { _generateMetadata } from "app/_utils";
import Page from "@calcom/features/ee/organizations/pages/settings/other-team-listing-view";
export const generateMetadata = async () =>
await _generateMetadata(
(t) => t("org_admin_other_teams"),
(t) => t("org_admin_other_teams_description")
);
export default Page;

View File

@ -1,13 +1,12 @@
import OldPage from "@pages/teams/index";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { redirect } from "next/navigation";
import { getLayout } from "@calcom/features/MainLayoutAppDir";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import type { buildLegacyCtx } from "@lib/buildLegacyCtx";
import { ssrInit } from "@server/lib/ssr";
export const generateMetadata = async () =>
@ -16,14 +15,12 @@ export const generateMetadata = async () =>
(t) => t("create_manage_teams_collaborative")
);
async function getData(context: ReturnType<typeof buildLegacyCtx>) {
// @ts-expect-error Argument of type '{ query: Params; params: Params; req: { headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }; }' is not assignable to parameter of type 'GetServerSidePropsContext'.
async function getData(context: GetServerSidePropsContext) {
const ssr = await ssrInit(context);
await ssr.viewer.me.prefetch();
const session = await getServerSession({
// @ts-expect-error Type '{ headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }' is not assignable to type 'NextApiRequest | (IncomingMessage & { cookies: Partial<{ [key: string]: string; }>; })'.
req: context.req,
});

View File

@ -2,14 +2,13 @@ import OldPage from "@pages/video/[uid]";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import MarkdownIt from "markdown-it";
import type { GetServerSidePropsContext } from "next";
import { redirect } from "next/navigation";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { APP_NAME } from "@calcom/lib/constants";
import prisma, { bookingMinimalSelect } from "@calcom/prisma";
import type { buildLegacyCtx } from "@lib/buildLegacyCtx";
import { ssrInit } from "@server/lib/ssr";
export const generateMetadata = async () =>
@ -20,8 +19,7 @@ export const generateMetadata = async () =>
const md = new MarkdownIt("default", { html: true, breaks: true, linkify: true });
async function getData(context: ReturnType<typeof buildLegacyCtx>) {
// @ts-expect-error Argument of type '{ query: Params; params: Params; req: { headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }; }' is not assignable to parameter of type 'GetServerSidePropsContext'.
async function getData(context: GetServerSidePropsContext) {
const ssr = await ssrInit(context);
const booking = await prisma.booking.findUnique({
@ -79,12 +77,11 @@ async function getData(context: ReturnType<typeof buildLegacyCtx>) {
endTime: booking.endTime.toString(),
});
// @ts-expect-error Type '{ headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }' is not assignable to type 'NextApiRequest | (IncomingMessage & { cookies: Partial<{ [key: string]: string; }>; })'.
const session = await getServerSession({ req: context.req });
// set meetingPassword to null for guests
if (session?.user.id !== bookingObj.user?.id) {
bookingObj.references.forEach((bookRef: any) => {
bookingObj.references.forEach((bookRef) => {
bookRef.meetingPassword = null;
});
}

View File

@ -49,5 +49,4 @@ async function getData(context: Omit<GetServerSidePropsContext, "res" | "resolve
};
}
// @ts-expect-error getData arg
export default WithLayout({ getData, Page: OldPage, getLayout: null })<"P">;

View File

@ -47,5 +47,4 @@ async function getData(context: Omit<GetServerSidePropsContext, "res" | "resolve
};
}
// @ts-expect-error getData arg
export default WithLayout({ getData, Page: OldPage, getLayout: null })<"P">;

View File

@ -1,8 +1,7 @@
import LegacyPage from "@pages/video/no-meeting-found";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { buildLegacyCtx } from "@lib/buildLegacyCtx";
import { type GetServerSidePropsContext } from "next";
import { ssrInit } from "@server/lib/ssr";
@ -12,8 +11,7 @@ export const generateMetadata = async () =>
(t) => t("no_meeting_found")
);
const getData = async (context: ReturnType<typeof buildLegacyCtx>) => {
// @ts-expect-error Argument of type '{ query: Params; params: Params; req: { headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }; }' is not assignable to parameter of type 'GetServerSidePropsContext'.
const getData = async (context: GetServerSidePropsContext) => {
const ssr = await ssrInit(context);
return {

View File

@ -35,7 +35,6 @@ async function getProps(context: GetServerSidePropsContext) {
export const generateStaticParams = () => [];
// @ts-expect-error getData arg
export default WithLayout({ getLayout: null, getData: getProps, Page: LegacyPage })<"P">;
export const dynamic = "force-static";
// generate segments on demand

View File

@ -1,4 +1,5 @@
import type { LayoutProps, PageProps } from "app/_types";
import { type GetServerSidePropsContext } from "next";
import { cookies, headers } from "next/headers";
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
@ -8,14 +9,16 @@ import PageWrapper from "@components/PageWrapperAppDir";
type WithLayoutParams<T extends Record<string, any>> = {
getLayout: ((page: React.ReactElement) => React.ReactNode) | null;
Page?: (props: T) => React.ReactElement | null;
getData?: (arg: ReturnType<typeof buildLegacyCtx>) => Promise<T>;
getData?: (arg: GetServerSidePropsContext) => Promise<T>;
};
export function WithLayout<T extends Record<string, any>>({ getLayout, getData, Page }: WithLayoutParams<T>) {
return async <P extends "P" | "L">(p: P extends "P" ? PageProps : LayoutProps) => {
const h = headers();
const nonce = h.get("x-nonce") ?? undefined;
const props = getData ? await getData(buildLegacyCtx(h, cookies(), p.params)) : ({} as T);
const props = getData
? await getData(buildLegacyCtx(h, cookies(), p.params) as unknown as GetServerSidePropsContext)
: ({} as T);
const children = "children" in p ? p.children : null;

View File

@ -1,6 +1,8 @@
"use client";
import { AboutOrganizationForm } from "@calcom/features/ee/organizations/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Meta, WizardLayout } from "@calcom/ui";
import { Meta, WizardLayout, WizardLayoutAppDir } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
@ -15,7 +17,7 @@ const AboutOrganizationPage = () => {
</>
);
};
const LayoutWrapper = (page: React.ReactElement) => {
export const LayoutWrapper = (page: React.ReactElement) => {
return (
<WizardLayout currentStep={3} maxSteps={5}>
{page}
@ -23,6 +25,14 @@ const LayoutWrapper = (page: React.ReactElement) => {
);
};
export const WrappedAboutOrganizationPage = (page: React.ReactElement) => {
return (
<WizardLayoutAppDir currentStep={3} maxSteps={5}>
{page}
</WizardLayoutAppDir>
);
};
AboutOrganizationPage.getLayout = LayoutWrapper;
AboutOrganizationPage.PageWrapper = PageWrapper;

View File

@ -1,8 +1,12 @@
"use client";
import type { AppProps as NextAppProps } from "next/app";
import { redirect } from "next/navigation";
import { AddNewTeamsForm } from "@calcom/features/ee/organizations/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Meta, WizardLayout } from "@calcom/ui";
import { WizardLayoutAppDir } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
@ -33,4 +37,17 @@ AddNewTeamsPage.getLayout = (page: React.ReactElement, router: NextAppProps["rou
AddNewTeamsPage.PageWrapper = PageWrapper;
export const WrapperAddNewTeamsPage = (page: React.ReactElement) => {
return (
<WizardLayoutAppDir
currentStep={5}
maxSteps={5}
isOptionalCallback={() => {
redirect(`/event-types`);
}}>
{page}
</WizardLayoutAppDir>
);
};
export default AddNewTeamsPage;

View File

@ -1,8 +1,11 @@
"use client";
import type { AppProps as NextAppProps } from "next/app";
import { redirect } from "next/navigation";
import { AddNewOrgAdminsForm } from "@calcom/features/ee/organizations/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Meta, WizardLayout } from "@calcom/ui";
import { Meta, WizardLayout, WizardLayoutAppDir } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
@ -33,6 +36,22 @@ OnboardTeamMembersPage.getLayout = (page: React.ReactElement, router: NextAppPro
</WizardLayout>
);
export const buildWrappedOnboardTeamMembersPage = (
id: string | string[] | undefined,
page: React.ReactElement
) => {
return (
<WizardLayoutAppDir
currentStep={4}
maxSteps={5}
isOptionalCallback={() => {
redirect(`/settings/organizations/${id}/add-teams`);
}}>
{page}
</WizardLayoutAppDir>
);
};
OnboardTeamMembersPage.PageWrapper = PageWrapper;
export default OnboardTeamMembersPage;

View File

@ -1,6 +1,8 @@
"use client";
import { SetPasswordForm } from "@calcom/features/ee/organizations/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Meta, WizardLayout } from "@calcom/ui";
import { Meta, WizardLayout, WizardLayoutAppDir } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
@ -23,6 +25,14 @@ const LayoutWrapper = (page: React.ReactElement) => {
);
};
export const WrappedSetPasswordPage = (page: React.ReactElement) => {
return (
<WizardLayoutAppDir currentStep={2} maxSteps={5}>
{page}
</WizardLayoutAppDir>
);
};
SetPasswordPage.getLayout = LayoutWrapper;
SetPasswordPage.PageWrapper = PageWrapper;

View File

@ -1,10 +1,12 @@
"use client";
import type { GetServerSidePropsContext } from "next";
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
import { CreateANewOrganizationForm } from "@calcom/features/ee/organizations/components";
import { getFeatureFlagMap } from "@calcom/features/flags/server/utils";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { WizardLayout, Meta } from "@calcom/ui";
import { WizardLayout, Meta, WizardLayoutAppDir } from "@calcom/ui";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
@ -27,6 +29,14 @@ const LayoutWrapper = (page: React.ReactElement) => {
);
};
export const WrappedCreateNewOrganizationPage = (page: React.ReactElement) => {
return (
<WizardLayoutAppDir currentStep={1} maxSteps={5}>
{page}
</WizardLayoutAppDir>
);
};
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const prisma = await import("@calcom/prisma").then((mod) => mod.default);
const flags = await getFeatureFlagMap(prisma);

View File

@ -1,3 +1,5 @@
"use client";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { useForm } from "react-hook-form";

View File

@ -1,3 +1,5 @@
"use client";
import { useRouter } from "next/navigation";
import { Controller, useForm } from "react-hook-form";

View File

@ -1,3 +1,5 @@
"use client";
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout";
import { UserListTable } from "@calcom/features/users/components/UserTable/UserListTable";

View File

@ -1,3 +1,5 @@
"use client";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Meta } from "@calcom/ui";

View File

@ -1,3 +1,5 @@
"use client";
// import { debounce } from "lodash";
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";

View File

@ -1,3 +1,5 @@
"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import type { Prisma } from "@prisma/client";
import { useSession } from "next-auth/react";

View File

@ -1,3 +1,5 @@
"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import type { Prisma } from "@prisma/client";
import { LinkIcon } from "lucide-react";

View File

@ -150,6 +150,7 @@ export { CreateButton, CreateButtonWithTeamsList } from "./components/createButt
export { useCalcomTheme } from "./styles/useCalcomTheme";
export { ScrollableArea } from "./components/scrollable/ScrollableArea";
export { WizardLayout } from "./layouts/WizardLayout";
export { WizardLayoutAppDir } from "./layouts/WizardLayoutAppDir";
export { DataTable } from "./components/data-table";
export {
Sheet,

View File

@ -0,0 +1,76 @@
"use client";
// eslint-disable-next-line no-restricted-imports
import { noop } from "lodash";
import { usePathname } from "next/navigation";
import React, { useEffect, useState } from "react";
import { Toaster } from "react-hot-toast";
import { APP_NAME } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, SkeletonText, StepCard, Steps } from "@calcom/ui";
export function WizardLayoutAppDir({
children,
maxSteps = 2,
currentStep = 0,
isOptionalCallback,
}: {
children: React.ReactNode;
} & { maxSteps?: number; currentStep?: number; isOptionalCallback?: () => void }) {
const { t, isLocaleReady } = useLocale();
const [meta, setMeta] = useState({ title: "", subtitle: " " });
const pathname = usePathname();
const { title, subtitle } = meta;
useEffect(() => {
setMeta({
title: window.document.title,
subtitle: window.document.querySelector('meta[name="description"]')?.getAttribute("content") || "",
});
}, [pathname]);
return (
<div
className="dark:bg-brand dark:text-brand-contrast text-emphasis min-h-screen"
data-testid="onboarding">
<div>
<Toaster position="bottom-right" />
</div>
<div className="mx-auto px-4 py-24">
<div className="relative">
<div className="sm:mx-auto sm:w-full sm:max-w-[600px]">
<div className="mx-auto sm:max-w-[520px]">
<header>
{isLocaleReady ? (
<>
<p className="font-cal mb-3 text-[28px] font-medium leading-7">
{title.replace(` | ${APP_NAME}`, "")}&nbsp;
</p>
<p className="text-subtle font-sans text-sm font-normal">{subtitle}&nbsp;</p>
</>
) : (
<>
<SkeletonText className="h-6 w-1/2" />
<SkeletonText className="mt-4 h-4 w-3/4" />
</>
)}
</header>
<Steps maxSteps={maxSteps} currentStep={currentStep} navigateToStep={noop} />
</div>
<StepCard>{children}</StepCard>
</div>
</div>
{isOptionalCallback && (
<div className="mt-4 flex justify-center">
<Button color="minimal" onClick={isOptionalCallback}>
{t("ill_do_this_later")}
</Button>
</div>
)}
</div>
</div>
);
}
export const getLayout = (page: React.ReactElement) => <WizardLayoutAppDir>{page}</WizardLayoutAppDir>;