diff --git a/packages/features/troubleshooter/components/EventScheduleItem.tsx b/packages/features/troubleshooter/components/EventScheduleItem.tsx
index df124610f5..45aa1d8c1b 100644
--- a/packages/features/troubleshooter/components/EventScheduleItem.tsx
+++ b/packages/features/troubleshooter/components/EventScheduleItem.tsx
@@ -31,7 +31,7 @@ export function EventScheduleItem() {
suffixSlot={
schedule && (
-
+
{t("edit")}
diff --git a/packages/features/troubleshooter/components/EventTypeSelect.tsx b/packages/features/troubleshooter/components/EventTypeSelect.tsx
index bd29b4d59f..c430c6b2f6 100644
--- a/packages/features/troubleshooter/components/EventTypeSelect.tsx
+++ b/packages/features/troubleshooter/components/EventTypeSelect.tsx
@@ -1,4 +1,5 @@
import { useMemo, useEffect, startTransition } from "react";
+import { shallow } from "zustand/shallow";
import { trpc } from "@calcom/trpc";
import { SelectField } from "@calcom/ui/components/form";
@@ -7,67 +8,80 @@ import { getQueryParam } from "../../bookings/Booker/utils/query-param";
import { useTroubleshooterStore } from "../store";
export function EventTypeSelect() {
- const { data: eventTypes, isPending } = trpc.viewer.eventTypes.list.useQuery();
- const selectedEventType = useTroubleshooterStore((state) => state.event);
- const setSelectedEventType = useTroubleshooterStore((state) => state.setEvent);
-
- const selectedEventQueryParam = getQueryParam("eventType");
+ const { data: eventTypes, isPending } = trpc.viewer.eventTypes.listWithTeam.useQuery();
+ const { event: selectedEventType, setEvent: setSelectedEventType } = useTroubleshooterStore(
+ (state) => ({
+ event: state.event,
+ setEvent: state.setEvent,
+ }),
+ shallow
+ );
const options = useMemo(() => {
if (!eventTypes) return [];
return eventTypes.map((e) => ({
label: e.title,
- value: e.slug,
+ value: e.id.toString(),
id: e.id,
duration: e.length,
}));
}, [eventTypes]);
+ // Initialize event type from query param or default to first event
useEffect(() => {
- if (!selectedEventType && eventTypes && eventTypes[0] && !selectedEventQueryParam) {
- const { id, slug, length } = eventTypes[0];
- setSelectedEventType({
- id,
- slug,
- duration: length,
- });
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [eventTypes]);
+ if (!eventTypes || eventTypes.length === 0) return;
- useEffect(() => {
- if (selectedEventQueryParam) {
- // ensure that the update is deferred until the Suspense boundary has finished hydrating
+ const selectedEventIdParam = getQueryParam("eventTypeId");
+ const eventTypeId = selectedEventIdParam ? parseInt(selectedEventIdParam, 10) : null;
+
+ // If we already have a selected event that matches the query param, don't do anything
+ if (selectedEventType?.id === eventTypeId) return;
+
+ // If there's a query param, try to find and set that event
+ if (eventTypeId && !isNaN(eventTypeId)) {
startTransition(() => {
- const foundEventType = eventTypes?.find((et) => et.slug === selectedEventQueryParam);
+ const foundEventType = eventTypes.find((et) => et.id === eventTypeId);
if (foundEventType) {
- const { id, slug, length } = foundEventType;
- setSelectedEventType({ id, slug, duration: length });
- } else if (eventTypes && eventTypes[0]) {
- const { id, slug, length } = eventTypes[0];
setSelectedEventType({
- id,
- slug,
- duration: length,
+ id: foundEventType.id,
+ slug: foundEventType.slug,
+ duration: foundEventType.length,
+ teamId: foundEventType.team?.id ?? null,
});
+ return;
}
});
}
- }, [eventTypes, selectedEventQueryParam, setSelectedEventType]);
+
+ // If no event is selected and no valid query param, default to first event
+ if (!selectedEventType && !eventTypeId) {
+ const firstEvent = eventTypes[0];
+ setSelectedEventType({
+ id: firstEvent.id,
+ slug: firstEvent.slug,
+ duration: firstEvent.length,
+ teamId: firstEvent.team?.id ?? null,
+ });
+ }
+ }, [eventTypes, selectedEventType, setSelectedEventType]);
return (
option.value === selectedEventType?.slug) || options[0]}
+ value={options.find((option) => option.id === selectedEventType?.id) || options[0]}
onChange={(option) => {
if (!option) return;
- setSelectedEventType({
- slug: option.value,
- id: option.id,
- duration: option.duration,
- });
+ const foundEventType = eventTypes?.find((et) => et.id === option.id);
+ if (foundEventType) {
+ setSelectedEventType({
+ id: foundEventType.id,
+ slug: foundEventType.slug,
+ duration: foundEventType.length,
+ teamId: foundEventType.team?.id ?? null,
+ });
+ }
}}
/>
);
diff --git a/packages/features/troubleshooter/components/LargeCalendar.tsx b/packages/features/troubleshooter/components/LargeCalendar.tsx
index de2f725a71..012b63d5cb 100644
--- a/packages/features/troubleshooter/components/LargeCalendar.tsx
+++ b/packages/features/troubleshooter/components/LargeCalendar.tsx
@@ -28,6 +28,7 @@ export const LargeCalendar = ({ extraDays }: { extraDays: number }) => {
.add(extraDays - 1, "day")
.utc()
.format(),
+ eventTypeId: event?.id,
withSource: true,
},
{
@@ -35,13 +36,16 @@ export const LargeCalendar = ({ extraDays }: { extraDays: number }) => {
}
);
+ const isTeamEvent = !!event?.teamId;
const { data: schedule } = useSchedule({
username: session?.user.username || "",
- eventSlug: event?.slug,
+ // For team events, don't pass eventSlug to avoid slug lookup issues - use eventId instead
+ eventSlug: isTeamEvent ? null : event?.slug,
eventId: event?.id,
timezone,
month: startDate.format("YYYY-MM"),
orgSlug: session?.user.org?.slug,
+ isTeamEvent,
});
const endDate = dayjs(startDate)
diff --git a/packages/features/troubleshooter/store.ts b/packages/features/troubleshooter/store.ts
index 4d5daa2601..49e23ee4e2 100644
--- a/packages/features/troubleshooter/store.ts
+++ b/packages/features/troubleshooter/store.ts
@@ -17,6 +17,7 @@ type EventType = {
id: number;
slug: string;
duration: number;
+ teamId?: number | null;
};
export type TroubleshooterStore = {
@@ -76,7 +77,7 @@ export const useTroubleshooterStore = create((set, get) =>
event: null,
setEvent: (event: EventType) => {
set({ event });
- updateQueryParam("eventType", event.slug ?? "");
+ updateQueryParam("eventTypeId", event.id.toString());
},
month: getQueryParam("month") || getQueryParam("date") || dayjs().format("YYYY-MM"),
setMonth: (month: string | null) => {
diff --git a/packages/trpc/server/routers/viewer/eventTypes/listWithTeam.handler.ts b/packages/trpc/server/routers/viewer/eventTypes/listWithTeam.handler.ts
index 6bdff69800..907c6b23a7 100644
--- a/packages/trpc/server/routers/viewer/eventTypes/listWithTeam.handler.ts
+++ b/packages/trpc/server/routers/viewer/eventTypes/listWithTeam.handler.ts
@@ -11,19 +11,26 @@ type ListWithTeamOptions = {
export const listWithTeamHandler = async ({ ctx }: ListWithTeamOptions) => {
const userId = ctx.user.id;
- const query = Prisma.sql`SELECT "public"."EventType"."id", "public"."EventType"."teamId", "public"."EventType"."title", "public"."EventType"."slug", "j1"."name" as "teamName"
+ const query = Prisma.sql`SELECT "public"."EventType"."id", "public"."EventType"."teamId", "public"."EventType"."title", "public"."EventType"."slug", "public"."EventType"."length", "j1"."name" as "teamName"
FROM "public"."EventType"
LEFT JOIN "public"."Team" AS "j1" ON ("j1"."id") = ("public"."EventType"."teamId")
WHERE "public"."EventType"."userId" = ${userId}
UNION
- SELECT "public"."EventType"."id", "public"."EventType"."teamId", "public"."EventType"."title", "public"."EventType"."slug", "j1"."name" as "teamName"
+ SELECT "public"."EventType"."id", "public"."EventType"."teamId", "public"."EventType"."title", "public"."EventType"."slug", "public"."EventType"."length", "j1"."name" as "teamName"
FROM "public"."EventType"
INNER JOIN "public"."Team" AS "j1" ON ("j1"."id") = ("public"."EventType"."teamId")
INNER JOIN "public"."Membership" AS "t2" ON "t2"."teamId" = "j1"."id"
WHERE "t2"."userId" = ${userId} AND "t2"."accepted" = true`;
const result = await db.$queryRaw<
- { id: number; teamId: number | null; title: string; slug: string; teamName: string | null }[]
+ {
+ id: number;
+ teamId: number | null;
+ title: string;
+ slug: string;
+ length: number;
+ teamName: string | null;
+ }[]
>(query);
return result.map((row) => ({
@@ -31,5 +38,6 @@ export const listWithTeamHandler = async ({ ctx }: ListWithTeamOptions) => {
team: row.teamId ? { id: row.teamId, name: row.teamName || "" } : null,
title: row.title,
slug: row.slug,
+ length: row.length,
}));
};