diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/availability/error.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/availability/error.tsx
index a722a613a4..7fa72bb7b1 100644
--- a/apps/web/app/(use-page-wrapper)/(main-nav)/availability/error.tsx
+++ b/apps/web/app/(use-page-wrapper)/(main-nav)/availability/error.tsx
@@ -1,7 +1,9 @@
"use client";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Alert } from "@calcom/ui/components/alert";
export default function Error() {
- return ;
+ const { t } = useLocale();
+ return ;
}
diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/actions.ts b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/actions.ts
new file mode 100644
index 0000000000..4f68f668fa
--- /dev/null
+++ b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/actions.ts
@@ -0,0 +1,7 @@
+"use server";
+
+import { revalidatePath } from "next/cache";
+
+export async function revalidateEventTypesList() {
+ revalidatePath("/event-types");
+}
diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/error.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/error.tsx
new file mode 100644
index 0000000000..7fa72bb7b1
--- /dev/null
+++ b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/error.tsx
@@ -0,0 +1,9 @@
+"use client";
+
+import { useLocale } from "@calcom/lib/hooks/useLocale";
+import { Alert } from "@calcom/ui/components/alert";
+
+export default function Error() {
+ const { t } = useLocale();
+ return ;
+}
diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/loading.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/loading.tsx
new file mode 100644
index 0000000000..6e6622a8df
--- /dev/null
+++ b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/loading.tsx
@@ -0,0 +1,5 @@
+import { EventTypesSkeleton } from "./skeleton";
+
+export default function Loading() {
+ return ;
+}
diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx
index c4e938fc91..387e13e921 100644
--- a/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx
@@ -8,6 +8,7 @@ import { redirect } from "next/navigation";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { getTeamsFiltersFromQuery } from "@calcom/features/filters/lib/getTeamsFiltersFromQuery";
import { eventTypesRouter } from "@calcom/trpc/server/routers/viewer/eventTypes/_router";
+import { meRouter } from "@calcom/trpc/server/routers/viewer/me/_router";
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
@@ -32,19 +33,27 @@ const Page = async ({ params, searchParams }: PageProps) => {
}
const t = await getTranslate();
-
- const caller = await createRouterCaller(eventTypesRouter);
const filters = getTeamsFiltersFromQuery(_searchParams);
- const initialData = await caller.getUserEventGroups({ filters });
+
+ const [meCaller, eventTypesCaller] = await Promise.all([
+ createRouterCaller(meRouter),
+ createRouterCaller(eventTypesRouter),
+ ]);
+
+ const [me, userEventGroupsData] = await Promise.all([
+ meCaller.get(),
+ eventTypesCaller.getUserEventGroups({ filters }),
+ ]);
return (
}>
-
+ CTA={}>
+
);
};
export default Page;
+export const revalidate = 3600; // 1 hour in seconds
diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/skeleton.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/skeleton.tsx
new file mode 100644
index 0000000000..089ee88c5f
--- /dev/null
+++ b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/skeleton.tsx
@@ -0,0 +1,15 @@
+"use client";
+
+import { ShellMainAppDir } from "app/(use-page-wrapper)/(main-nav)/ShellMainAppDir";
+
+import { EventTypesSkeletonLoader } from "@calcom/features/eventtypes/components/SkeletonLoader";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
+
+export function EventTypesSkeleton() {
+ const { t } = useLocale();
+ return (
+
+
+
+ );
+}
diff --git a/apps/web/app/(use-page-wrapper)/event-types/[type]/actions.ts b/apps/web/app/(use-page-wrapper)/event-types/[type]/actions.ts
new file mode 100644
index 0000000000..feff0576fb
--- /dev/null
+++ b/apps/web/app/(use-page-wrapper)/event-types/[type]/actions.ts
@@ -0,0 +1,7 @@
+"use server";
+
+import { revalidatePath } from "next/cache";
+
+export async function revalidateEventTypeEditPage(id: number) {
+ revalidatePath(`/event-types/${id}`);
+}
diff --git a/apps/web/app/(use-page-wrapper)/event-types/[type]/error.tsx b/apps/web/app/(use-page-wrapper)/event-types/[type]/error.tsx
new file mode 100644
index 0000000000..0951beed67
--- /dev/null
+++ b/apps/web/app/(use-page-wrapper)/event-types/[type]/error.tsx
@@ -0,0 +1,14 @@
+"use client";
+
+import Shell from "@calcom/features/shell/Shell";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
+import { Alert } from "@calcom/ui/components/alert";
+
+export default function Error() {
+ const { t } = useLocale();
+ return (
+
+
+
+ );
+}
diff --git a/apps/web/app/(use-page-wrapper)/event-types/[type]/loading.tsx b/apps/web/app/(use-page-wrapper)/event-types/[type]/loading.tsx
new file mode 100644
index 0000000000..676c81856a
--- /dev/null
+++ b/apps/web/app/(use-page-wrapper)/event-types/[type]/loading.tsx
@@ -0,0 +1,5 @@
+import { EventTypeEditPageSkeleton } from "./skeleton";
+
+export default function Loading() {
+ return ;
+}
diff --git a/apps/web/app/(use-page-wrapper)/event-types/[type]/page.tsx b/apps/web/app/(use-page-wrapper)/event-types/[type]/page.tsx
index 06f47635e9..ebab01769b 100644
--- a/apps/web/app/(use-page-wrapper)/event-types/[type]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/event-types/[type]/page.tsx
@@ -1,14 +1,15 @@
-import type { PageProps as _PageProps } from "app/_types";
+import { createRouterCaller } from "app/_trpc/context";
+import type { PageProps } from "app/_types";
import { _generateMetadata } from "app/_utils";
import { cookies, headers } from "next/headers";
+import { redirect } from "next/navigation";
import { z } from "zod";
-import { EventTypeRepository } from "@calcom/lib/server/repository/eventType";
+import { EventTypeWebWrapper } from "@calcom/atoms/event-types/wrappers/EventTypeWebWrapper";
+import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
+import { eventTypesRouter } from "@calcom/trpc/server/routers/viewer/eventTypes/_router";
-import { buildLegacyCtx } from "@lib/buildLegacyCtx";
-import { getServerSideProps } from "@lib/event-types/[type]/getServerSideProps";
-
-import EventTypePageWrapper from "~/event-types/views/event-types-single-view";
+import { buildLegacyRequest } from "@lib/buildLegacyCtx";
const querySchema = z.object({
type: z
@@ -19,36 +20,34 @@ const querySchema = z.object({
.transform((val) => Number(val)),
});
-export const generateMetadata = async ({ params }: _PageProps) => {
- const parsed = querySchema.safeParse(await params);
- if (!parsed.success) {
- return await _generateMetadata(
- (t) => `${t("event_type")}`,
- () => "",
- undefined,
- undefined,
- "/event-types"
- );
- }
-
- const data = await EventTypeRepository.findTitleById({
- id: parsed.data.type,
- });
-
+export const generateMetadata = async () => {
return await _generateMetadata(
- (t) => (data?.title ? `${data.title} | ${t("event_type")}` : `${t("event_type")}`),
+ (t) => `${t("event_type")}`,
() => "",
undefined,
undefined,
- `/event-types/${parsed.data.type}`
+ "/event-types"
);
};
-const ServerPage = async ({ params, searchParams }: _PageProps) => {
- const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
- const props = await getServerSideProps(legacyCtx);
+const ServerPage = async ({ params }: PageProps) => {
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
+ if (!session?.user?.id) {
+ return redirect("/auth/login");
+ }
- return ;
+ const parsed = querySchema.safeParse(await params);
+ if (!parsed.success) {
+ throw new Error("Invalid Event Type id");
+ }
+ const eventTypeId = parsed.data.type;
+ const caller = await createRouterCaller(eventTypesRouter);
+ const data = await caller.get({ id: eventTypeId });
+ if (!data?.eventType) {
+ throw new Error("This event type does not exist");
+ }
+
+ return ;
};
export default ServerPage;
diff --git a/apps/web/app/(use-page-wrapper)/event-types/[type]/skeleton.tsx b/apps/web/app/(use-page-wrapper)/event-types/[type]/skeleton.tsx
new file mode 100644
index 0000000000..2f95b6ac84
--- /dev/null
+++ b/apps/web/app/(use-page-wrapper)/event-types/[type]/skeleton.tsx
@@ -0,0 +1,105 @@
+"use client";
+
+import Shell from "@calcom/features/shell/Shell";
+import {
+ SkeletonButton,
+ SkeletonContainer,
+ SkeletonText,
+ SkeletonAvatar,
+} from "@calcom/ui/components/skeleton";
+
+export const EventTypeEditPageSkeleton = () => {
+ const backButtonSkeleton = (
+
+ );
+
+ return (
+ } afterHeading={backButtonSkeleton}>
+
+
+
+
+ {/* Tab navigation items */}
+ {Array.from({ length: 8 }).map((_, index) => (
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+ {/* Form fields */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/error.tsx b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/error.tsx
index a722a613a4..7fa72bb7b1 100644
--- a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/error.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/error.tsx
@@ -1,7 +1,9 @@
"use client";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Alert } from "@calcom/ui/components/alert";
export default function Error() {
- return ;
+ const { t } = useLocale();
+ return ;
}
diff --git a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/users/[id]/edit/error.tsx b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/users/[id]/edit/error.tsx
index a722a613a4..7fa72bb7b1 100644
--- a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/users/[id]/edit/error.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/users/[id]/edit/error.tsx
@@ -1,7 +1,9 @@
"use client";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Alert } from "@calcom/ui/components/alert";
export default function Error() {
- return ;
+ const { t } = useLocale();
+ return ;
}
diff --git a/apps/web/app/(use-page-wrapper)/workflows/[workflow]/error.tsx b/apps/web/app/(use-page-wrapper)/workflows/[workflow]/error.tsx
index a722a613a4..7fa72bb7b1 100644
--- a/apps/web/app/(use-page-wrapper)/workflows/[workflow]/error.tsx
+++ b/apps/web/app/(use-page-wrapper)/workflows/[workflow]/error.tsx
@@ -1,7 +1,9 @@
"use client";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Alert } from "@calcom/ui/components/alert";
export default function Error() {
- return ;
+ const { t } = useLocale();
+ return ;
}
diff --git a/apps/web/lib/event-types/[type]/getServerSideProps.ts b/apps/web/lib/event-types/[type]/getServerSideProps.ts
deleted file mode 100644
index 393adc5b0e..0000000000
--- a/apps/web/lib/event-types/[type]/getServerSideProps.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { createRouterCaller } from "app/_trpc/context";
-import type { GetServerSidePropsContext } from "next";
-import { redirect, notFound } from "next/navigation";
-
-import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
-import logger from "@calcom/lib/logger";
-import { safeStringify } from "@calcom/lib/safeStringify";
-import type { RouterOutputs } from "@calcom/trpc";
-import { eventTypesRouter } from "@calcom/trpc/server/routers/viewer/eventTypes/_router";
-
-import { asStringOrThrow } from "@lib/asStringOrNull";
-
-export type PageProps = {
- type: number;
- data: RouterOutputs["viewer"]["eventTypes"]["get"];
-};
-
-export const getServerSideProps = async (context: GetServerSidePropsContext) => {
- const { req, query } = context;
-
- const session = await getServerSession({ req });
-
- const typeParam = parseInt(asStringOrThrow(query.type));
-
- if (Number.isNaN(typeParam)) {
- return notFound();
- }
-
- if (!session?.user?.id) {
- return redirect("/auth/login");
- }
- const getEventTypeById = async (eventTypeId: number) => {
- const caller = await createRouterCaller(eventTypesRouter);
-
- try {
- return await caller.get({ id: eventTypeId });
- } catch (e: unknown) {
- logger.error(safeStringify(e));
- // reject, user has no access to this event type.
- return null;
- }
- };
- const data = await getEventTypeById(typeParam);
- if (!data?.eventType) {
- return redirect("/event-types");
- }
- return {
- data,
- type: typeParam,
- };
-};
diff --git a/apps/web/modules/event-types/views/event-types-listing-view.tsx b/apps/web/modules/event-types/views/event-types-listing-view.tsx
index 678c4eb423..861e584c58 100644
--- a/apps/web/modules/event-types/views/event-types-listing-view.tsx
+++ b/apps/web/modules/event-types/views/event-types-listing-view.tsx
@@ -14,10 +14,7 @@ import { EventTypeEmbedButton, EventTypeEmbedDialog } from "@calcom/features/emb
import { EventTypeDescription } from "@calcom/features/eventtypes/components";
import CreateEventTypeDialog from "@calcom/features/eventtypes/components/CreateEventTypeDialog";
import { DuplicateDialog } from "@calcom/features/eventtypes/components/DuplicateDialog";
-import {
- InfiniteSkeletonLoader,
- EventTypesSkeletonLoader,
-} from "@calcom/features/eventtypes/components/SkeletonLoader";
+import { InfiniteSkeletonLoader } from "@calcom/features/eventtypes/components/SkeletonLoader";
import { parseEventTypeColor } from "@calcom/lib";
import { APP_NAME, WEBSITE_URL } from "@calcom/lib/constants";
import { useCopy } from "@calcom/lib/hooks/useCopy";
@@ -32,7 +29,6 @@ import { SchedulingType } from "@calcom/prisma/enums";
import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import classNames from "@calcom/ui/classNames";
-import { Alert } from "@calcom/ui/components/alert";
import { ArrowButton } from "@calcom/ui/components/arrow-button";
import { UserAvatarGroup } from "@calcom/ui/components/avatar";
import { Badge } from "@calcom/ui/components/badge";
@@ -58,8 +54,6 @@ import { Skeleton } from "@calcom/ui/components/skeleton";
import { showToast } from "@calcom/ui/components/toast";
import { Tooltip } from "@calcom/ui/components/tooltip";
-import useMeQuery from "@lib/hooks/useMeQuery";
-
import { TRPCClientError } from "@trpc/client";
type GetUserEventGroupsResponse = RouterOutputs["viewer"]["eventTypes"]["getUserEventGroups"];
@@ -839,7 +833,6 @@ const CreateFirstEventTypeView = ({ slug, searchTerm }: { slug: string; searchTe
const CTA = ({
profileOptions,
- isOrganization,
}: {
profileOptions: {
teamId: number | null | undefined;
@@ -848,7 +841,6 @@ const CTA = ({
membershipRole: MembershipRole | null | undefined;
slug: string | null;
}[];
- isOrganization: boolean;
}) => {
const { t } = useLocale();
@@ -890,28 +882,16 @@ const EmptyEventTypeList = ({
};
const InfiniteScrollMain = ({
- status,
- errorMessage,
eventTypeGroups,
profiles,
}: {
- status: string;
- errorMessage?: string;
- eventTypeGroups: GetUserEventGroupsResponse["eventTypeGroups"] | undefined;
- profiles: GetUserEventGroupsResponse["profiles"] | undefined;
+ eventTypeGroups: GetUserEventGroupsResponse["eventTypeGroups"];
+ profiles: GetUserEventGroupsResponse["profiles"];
}) => {
const searchParams = useSearchParams();
const { data } = useTypedQuery(querySchema);
const orgBranding = useOrgBranding();
- if (status === "error") {
- return ;
- }
-
- if (!eventTypeGroups || !profiles || status === "pending") {
- return ;
- }
-
const tabs = eventTypeGroups.map((item) => ({
name: item.profile.name ?? "",
href: item.teamId ? `/event-types?teamId=${item.teamId}` : "/event-types",
@@ -947,25 +927,13 @@ const InfiniteScrollMain = ({
};
type Props = {
- initialData: RouterOutputs["viewer"]["eventTypes"]["getUserEventGroups"];
- filters?: { teamIds?: number[] | undefined; userIds?: number[] | undefined; upIds?: string[] | undefined };
+ userEventGroupsData: GetUserEventGroupsResponse;
+ user: RouterOutputs["viewer"]["me"]["get"];
};
-export const EventTypesCTA = ({ initialData, filters }: Props) => {
- const { data: user } = useMeQuery();
- const { data: userEventGroupsQuery } = trpc.viewer.eventTypes.getUserEventGroups.useQuery(
- filters && { filters },
- {
- refetchOnWindowFocus: false,
- gcTime: 1 * 60 * 60 * 1000,
- staleTime: 1 * 60 * 60 * 1000,
- }
- );
-
- const getUserEventGroupsData = userEventGroupsQuery ?? initialData;
-
+export const EventTypesCTA = ({ userEventGroupsData }: Omit) => {
const profileOptions =
- getUserEventGroupsData?.profiles
+ userEventGroupsData?.profiles
?.filter((profile) => !profile.readOnly)
?.filter((profile) => !profile.eventTypesLockedByOrg)
?.map((profile) => {
@@ -978,28 +946,14 @@ export const EventTypesCTA = ({ initialData, filters }: Props) => {
};
}) ?? [];
- return ;
+ return ;
};
-const EventTypesPage = ({ initialData, filters }: Props) => {
- const { data: user } = useMeQuery();
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
+const EventTypesPage = ({ userEventGroupsData, user }: Props) => {
const [_showProfileBanner, setShowProfileBanner] = useState(false);
const orgBranding = useOrgBranding();
const router = useRouter();
- // TODO: Maybe useSuspenseQuery to focus on success case only? Remember that it would crash the page when there is an error in query. Also, it won't support skeleton
- const {
- data: getUserEventGroupsData,
- status: getUserEventGroupsStatus,
- error: getUserEventGroupsStatusError,
- } = trpc.viewer.eventTypes.getUserEventGroups.useQuery(filters && { filters }, {
- refetchOnWindowFocus: false,
- gcTime: 1 * 60 * 60 * 1000,
- staleTime: 1 * 60 * 60 * 1000,
- initialData,
- });
-
useEffect(() => {
/**
* During signup, if the account already exists, we redirect the user to /event-types instead of onboarding.
@@ -1019,10 +973,8 @@ const EventTypesPage = ({ initialData, filters }: Props) => {
return (
);
};
diff --git a/apps/web/modules/event-types/views/event-types-single-view.tsx b/apps/web/modules/event-types/views/event-types-single-view.tsx
deleted file mode 100644
index 3351ec7680..0000000000
--- a/apps/web/modules/event-types/views/event-types-single-view.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-"use client";
-
-import { EventTypeWebWrapper as EventType } from "@calcom/atoms/event-types/wrappers/EventTypeWebWrapper";
-
-import type { PageProps } from "@lib/event-types/[type]/getServerSideProps";
-
-const EventTypePageWrapper = ({ type, data }: PageProps) => {
- return ;
-};
-
-export default EventTypePageWrapper;
diff --git a/packages/features/ee/teams/pages/team-profile-view.tsx b/packages/features/ee/teams/pages/team-profile-view.tsx
index e55d802d17..6e253099e0 100644
--- a/packages/features/ee/teams/pages/team-profile-view.tsx
+++ b/packages/features/ee/teams/pages/team-profile-view.tsx
@@ -123,8 +123,8 @@ const ProfileView = () => {
const deleteTeamMutation = trpc.viewer.teams.delete.useMutation({
async onSuccess() {
- await utils.viewer.teams.list.invalidate();
revalidateTeamsList();
+ await utils.viewer.teams.list.invalidate();
await utils.viewer.eventTypes.getUserEventGroups.invalidate();
await utils.viewer.eventTypes.getByViewer.invalidate();
showToast(t("your_team_disbanded_successfully"), "success");
diff --git a/packages/features/eventtypes/components/SkeletonLoader.tsx b/packages/features/eventtypes/components/SkeletonLoader.tsx
index 0913a9dc54..2a0643b979 100644
--- a/packages/features/eventtypes/components/SkeletonLoader.tsx
+++ b/packages/features/eventtypes/components/SkeletonLoader.tsx
@@ -34,11 +34,11 @@ export function InfiniteSkeletonLoader() {
);
}
-export function TabsSkeletonLoader() {
+function TabsSkeletonLoader() {
return (
-
+