From 63740c02c752f89a90d8373fb19c09e3f0da935f Mon Sep 17 00:00:00 2001 From: Rajiv Sahal Date: Mon, 22 Sep 2025 17:47:33 +0530 Subject: [PATCH] feat: calendar view atom `v1` (#23840) * fix: refactor * add `isMonthViewProp` to header * feat: init v1 for calendar view atom * test breaking toggle buttons * fix: make sure week start is always sunday for calendar view atom * fixup * fix: remove extra comments * fix: add calendar view page in examples app * chore: add changesets * fix: coderabbit feedback * fixup --- .changeset/fuzzy-beers-know.md | 5 + .../bookings/Booker/components/Header.tsx | 13 +- .../Booker/components/LargeCalendar.tsx | 21 +- .../components/hooks/useAvailableTimeSlots.ts | 30 +++ .../hooks/useInitializeWeekStart.ts | 17 ++ .../features/calendar-view/LargeCalendar.tsx | 79 +++++++ .../components/LargeCalendar.tsx | 19 +- .../atoms/booker/BookerPlatformWrapper.tsx | 3 +- .../platform/atoms/calendar-view/index.ts | 1 + .../wrappers/CalendarViewPlatformWrapper.tsx | 223 ++++++++++++++++++ .../wrappers/EventTypePlatformWrapper.tsx | 33 +-- packages/platform/atoms/index.ts | 1 + ...lectedCalendarsSettingsPlatformWrapper.tsx | 2 +- .../base/src/components/Navbar/index.tsx | 5 +- .../examples/base/src/pages/calendar-view.tsx | 17 ++ 15 files changed, 413 insertions(+), 56 deletions(-) create mode 100644 .changeset/fuzzy-beers-know.md create mode 100644 packages/features/bookings/Booker/components/hooks/useAvailableTimeSlots.ts create mode 100644 packages/features/bookings/Booker/components/hooks/useInitializeWeekStart.ts create mode 100644 packages/features/calendar-view/LargeCalendar.tsx create mode 100644 packages/platform/atoms/calendar-view/index.ts create mode 100644 packages/platform/atoms/calendar-view/wrappers/CalendarViewPlatformWrapper.tsx create mode 100644 packages/platform/examples/base/src/pages/calendar-view.tsx diff --git a/.changeset/fuzzy-beers-know.md b/.changeset/fuzzy-beers-know.md new file mode 100644 index 0000000000..032cf20d23 --- /dev/null +++ b/.changeset/fuzzy-beers-know.md @@ -0,0 +1,5 @@ +--- +"@calcom/atoms": minor +--- + +This PR adds a new atom called `CalendarView` which is a read only calendar view component for a user. diff --git a/packages/features/bookings/Booker/components/Header.tsx b/packages/features/bookings/Booker/components/Header.tsx index 52f8e1a32e..1d9799d4bc 100644 --- a/packages/features/bookings/Booker/components/Header.tsx +++ b/packages/features/bookings/Booker/components/Header.tsx @@ -5,6 +5,7 @@ import { useIsPlatform } from "@calcom/atoms/hooks/useIsPlatform"; import dayjs from "@calcom/dayjs"; import { useIsEmbed } from "@calcom/embed-core/embed-iframe"; import { useBookerStoreContext } from "@calcom/features/bookings/Booker/BookerStoreProvider"; +import { useInitializeWeekStart } from "@calcom/features/bookings/Booker/components/hooks/useInitializeWeekStart"; import { WEBAPP_URL } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { BookerLayouts } from "@calcom/prisma/zod-utils"; @@ -25,6 +26,7 @@ export function Header({ eventSlug, isMyLink, renderOverlay, + isCalendarView, }: { extraDays: number; isMobile: boolean; @@ -33,14 +35,16 @@ export function Header({ eventSlug: string; isMyLink: boolean; renderOverlay?: () => JSX.Element | null; + isCalendarView?: boolean; }) { const { t, i18n } = useLocale(); const isEmbed = useIsEmbed(); + const isPlatform = useIsPlatform(); const [layout, setLayout] = useBookerStoreContext((state) => [state.layout, state.setLayout], shallow); const selectedDateString = useBookerStoreContext((state) => state.selectedDate); const setSelectedDate = useBookerStoreContext((state) => state.setSelectedDate); const addToSelectedDate = useBookerStoreContext((state) => state.addToSelectedDate); - const isMonthView = layout === BookerLayouts.MONTH_VIEW; + const isMonthView = isCalendarView !== undefined ? !isCalendarView : layout === BookerLayouts.MONTH_VIEW; const today = dayjs(); const selectedDate = selectedDateString ? dayjs(selectedDateString) : today; const selectedDateMin3DaysDifference = useMemo(() => { @@ -48,6 +52,8 @@ export function Header({ return diff > 3 || diff < -3; }, [today, selectedDate]); + useInitializeWeekStart(isPlatform, isCalendarView ?? false); + const onLayoutToggle = useCallback( (newLayout: string) => { if (layout === newLayout || !newLayout) return; @@ -130,7 +136,10 @@ export function Header({ )} diff --git a/packages/features/bookings/Booker/components/LargeCalendar.tsx b/packages/features/bookings/Booker/components/LargeCalendar.tsx index 0151d399d2..839b5a6fdc 100644 --- a/packages/features/bookings/Booker/components/LargeCalendar.tsx +++ b/packages/features/bookings/Booker/components/LargeCalendar.tsx @@ -2,10 +2,10 @@ import { useMemo, useEffect } from "react"; import dayjs from "@calcom/dayjs"; import { useBookerStoreContext } from "@calcom/features/bookings/Booker/BookerStoreProvider"; +import { useAvailableTimeSlots } from "@calcom/features/bookings/Booker/components/hooks/useAvailableTimeSlots"; import type { BookerEvent } from "@calcom/features/bookings/types"; import { Calendar } from "@calcom/features/calendars/weeklyview"; import type { CalendarEvent } from "@calcom/features/calendars/weeklyview/types/events"; -import type { CalendarAvailableTimeslots } from "@calcom/features/calendars/weeklyview/types/state"; import { localStorage } from "@calcom/lib/webstorage"; import type { useScheduleForEventReturnType } from "../utils/event"; @@ -34,24 +34,7 @@ export const LargeCalendar = ({ const eventDuration = selectedEventDuration || event?.data?.length || 30; - const availableSlots = useMemo(() => { - const availableTimeslots: CalendarAvailableTimeslots = {}; - if (!schedule) return availableTimeslots; - if (!schedule.slots) return availableTimeslots; - - for (const day in schedule.slots) { - availableTimeslots[day] = schedule.slots[day].map((slot) => { - const { time, ...rest } = slot; - return { - start: dayjs(time).toDate(), - end: dayjs(time).add(eventDuration, "minutes").toDate(), - ...rest, - }; - }); - } - - return availableTimeslots; - }, [schedule, eventDuration]); + const availableSlots = useAvailableTimeSlots({ schedule, eventDuration }); const startDate = selectedDate ? dayjs(selectedDate).toDate() : dayjs().toDate(); const endDate = dayjs(startDate) diff --git a/packages/features/bookings/Booker/components/hooks/useAvailableTimeSlots.ts b/packages/features/bookings/Booker/components/hooks/useAvailableTimeSlots.ts new file mode 100644 index 0000000000..b88856c06b --- /dev/null +++ b/packages/features/bookings/Booker/components/hooks/useAvailableTimeSlots.ts @@ -0,0 +1,30 @@ +import { useMemo } from "react"; + +import dayjs from "@calcom/dayjs"; +import type { CalendarAvailableTimeslots } from "@calcom/features/calendars/weeklyview/types/state"; +import type { IGetAvailableSlots } from "@calcom/trpc/server/routers/viewer/slots/util"; + +interface UseAvailableTimeSlotsProps { + eventDuration: number; + schedule?: IGetAvailableSlots; +} + +export const useAvailableTimeSlots = ({ schedule, eventDuration }: UseAvailableTimeSlotsProps) => { + return useMemo(() => { + const availableTimeslots: CalendarAvailableTimeslots = {}; + if (!schedule || !schedule.slots) return availableTimeslots; + + for (const day in schedule.slots) { + availableTimeslots[day] = schedule.slots[day].map((slot) => { + const { time, ...rest } = slot; + return { + start: dayjs(time).toDate(), + end: dayjs(time).add(eventDuration, "minutes").toDate(), + ...rest, + }; + }); + } + + return availableTimeslots; + }, [schedule, eventDuration]); +}; diff --git a/packages/features/bookings/Booker/components/hooks/useInitializeWeekStart.ts b/packages/features/bookings/Booker/components/hooks/useInitializeWeekStart.ts new file mode 100644 index 0000000000..c2d3a38b22 --- /dev/null +++ b/packages/features/bookings/Booker/components/hooks/useInitializeWeekStart.ts @@ -0,0 +1,17 @@ +import { useEffect } from "react"; + +import dayjs from "@calcom/dayjs"; +import { useBookerStoreContext } from "@calcom/features/bookings/Booker/BookerStoreProvider"; + +export const useInitializeWeekStart = (isPlatform: boolean, isCalendarView: boolean) => { + const today = dayjs(); + const weekStart = today.startOf("week").format("YYYY-MM-DD"); + const setSelectedDate = useBookerStoreContext((state) => state.setSelectedDate); + + useEffect(() => { + if (isPlatform && isCalendarView) { + setSelectedDate({ date: weekStart, omitUpdatingParams: true }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); +}; diff --git a/packages/features/calendar-view/LargeCalendar.tsx b/packages/features/calendar-view/LargeCalendar.tsx new file mode 100644 index 0000000000..0659df79da --- /dev/null +++ b/packages/features/calendar-view/LargeCalendar.tsx @@ -0,0 +1,79 @@ +import { useMemo, useEffect } from "react"; + +import dayjs from "@calcom/dayjs"; +import { useBookerStoreContext } from "@calcom/features/bookings/Booker/BookerStoreProvider"; +import { useAvailableTimeSlots } from "@calcom/features/bookings/Booker/components/hooks/useAvailableTimeSlots"; +import type { BookerEvent } from "@calcom/features/bookings/types"; +import { Calendar } from "@calcom/features/calendars/weeklyview"; +import type { CalendarEvent } from "@calcom/features/calendars/weeklyview/types/events"; +import { localStorage } from "@calcom/lib/webstorage"; + +import { useOverlayCalendarStore } from "../bookings/Booker/components/OverlayCalendar/store"; +import type { useScheduleForEventReturnType } from "../bookings/Booker/utils/event"; +import { getQueryParam } from "../bookings/Booker/utils/query-param"; + +export const LargeCalendar = ({ + extraDays, + schedule, + isLoading, + event, +}: { + extraDays: number; + schedule?: useScheduleForEventReturnType["data"]; + isLoading: boolean; + event: { + data?: Pick | null; + }; +}) => { + const selectedDate = useBookerStoreContext((state) => state.selectedDate); + const selectedEventDuration = useBookerStoreContext((state) => state.selectedDuration); + const overlayEvents = useOverlayCalendarStore((state) => state.overlayBusyDates); + const displayOverlay = + getQueryParam("overlayCalendar") === "true" || localStorage?.getItem("overlayCalendarSwitchDefault"); + + const eventDuration = selectedEventDuration || event?.data?.length || 30; + + const availableSlots = useAvailableTimeSlots({ schedule, eventDuration }); + + const startDate = selectedDate ? dayjs(selectedDate).toDate() : dayjs().toDate(); + const endDate = dayjs(startDate) + .add(extraDays - 1, "day") + .toDate(); + + // HACK: force rerender when overlay events change + // Sine we dont use react router here we need to force rerender (ATOM SUPPORT) + // eslint-disable-next-line @typescript-eslint/no-empty-function + useEffect(() => {}, [displayOverlay]); + + const overlayEventsForDate = useMemo(() => { + if (!overlayEvents || !displayOverlay) return []; + return overlayEvents.map((event, id) => { + return { + id, + start: dayjs(event.start).toDate(), + end: dayjs(event.end).toDate(), + title: "Busy", + options: { + status: "ACCEPTED", + }, + } as CalendarEvent; + }); + }, [overlayEvents, displayOverlay]); + + return ( +
+ +
+ ); +}; diff --git a/packages/features/troubleshooter/components/LargeCalendar.tsx b/packages/features/troubleshooter/components/LargeCalendar.tsx index b4d30ee571..28ba9f2935 100644 --- a/packages/features/troubleshooter/components/LargeCalendar.tsx +++ b/packages/features/troubleshooter/components/LargeCalendar.tsx @@ -2,8 +2,8 @@ import { useSession } from "next-auth/react"; import { useMemo } from "react"; import dayjs from "@calcom/dayjs"; +import { useAvailableTimeSlots } from "@calcom/features/bookings/Booker/components/hooks/useAvailableTimeSlots"; import { Calendar } from "@calcom/features/calendars/weeklyview"; -import type { CalendarAvailableTimeslots } from "@calcom/features/calendars/weeklyview/types/state"; import { BookingStatus } from "@calcom/prisma/enums"; import { trpc } from "@calcom/trpc"; @@ -48,22 +48,7 @@ export const LargeCalendar = ({ extraDays }: { extraDays: number }) => { .add(extraDays - 1, "day") .toDate(); - const availableSlots = useMemo(() => { - const availableTimeslots: CalendarAvailableTimeslots = {}; - if (!schedule) return availableTimeslots; - if (!schedule?.slots) return availableTimeslots; - - for (const day in schedule.slots) { - availableTimeslots[day] = schedule.slots[day].map((slot) => ({ - start: dayjs(slot.time).toDate(), - end: dayjs(slot.time) - .add(event?.duration ?? 30, "minutes") - .toDate(), - })); - } - - return availableTimeslots; - }, [schedule, event]); + const availableSlots = useAvailableTimeSlots({ schedule, eventDuration: event?.duration ?? 30 }); const events = useMemo(() => { if (!busyEvents?.busy) return []; diff --git a/packages/platform/atoms/booker/BookerPlatformWrapper.tsx b/packages/platform/atoms/booker/BookerPlatformWrapper.tsx index f58e9ba33e..65a90e7209 100644 --- a/packages/platform/atoms/booker/BookerPlatformWrapper.tsx +++ b/packages/platform/atoms/booker/BookerPlatformWrapper.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react-hooks/exhaustive-deps */ import { useQueryClient } from "@tanstack/react-query"; // eslint-disable-next-line no-restricted-imports import debounce from "lodash/debounce"; @@ -594,7 +595,7 @@ export const BookerPlatformWrapper = ( ); }; -function formatUsername(username: string | string[]): string { +export function formatUsername(username: string | string[]): string { if (typeof username === "string") { return username; } diff --git a/packages/platform/atoms/calendar-view/index.ts b/packages/platform/atoms/calendar-view/index.ts new file mode 100644 index 0000000000..57f223bbec --- /dev/null +++ b/packages/platform/atoms/calendar-view/index.ts @@ -0,0 +1 @@ +export { CalendarViewPlatformWrapper } from "./wrappers/CalendarViewPlatformWrapper"; diff --git a/packages/platform/atoms/calendar-view/wrappers/CalendarViewPlatformWrapper.tsx b/packages/platform/atoms/calendar-view/wrappers/CalendarViewPlatformWrapper.tsx new file mode 100644 index 0000000000..a94855f0bc --- /dev/null +++ b/packages/platform/atoms/calendar-view/wrappers/CalendarViewPlatformWrapper.tsx @@ -0,0 +1,223 @@ +import { AtomsWrapper } from "@/components/atoms-wrapper"; +import { useMemo, useEffect, useState } from "react"; +import { shallow } from "zustand/shallow"; + +import dayjs from "@calcom/dayjs"; +import { + BookerStoreProvider, + useBookerStoreContext, + useInitializeBookerStoreContext, +} from "@calcom/features/bookings/Booker/BookerStoreProvider"; +import { Header } from "@calcom/features/bookings/Booker/components/Header"; +import { BookerSection } from "@calcom/features/bookings/Booker/components/Section"; +import { useBookerLayout } from "@calcom/features/bookings/Booker/components/hooks/useBookerLayout"; +import { useTimePreferences } from "@calcom/features/bookings/lib"; +import { LargeCalendar } from "@calcom/features/calendar-view/LargeCalendar"; +import { getUsernameList } from "@calcom/features/eventtypes/lib/defaultEvents"; +import { useTimesForSchedule } from "@calcom/features/schedules/lib/use-schedule/useTimesForSchedule"; +import { getRoutedTeamMemberIdsFromSearchParams } from "@calcom/lib/bookings/getRoutedTeamMemberIdsFromSearchParams"; +import { BookerLayouts } from "@calcom/prisma/zod-utils"; + +import { formatUsername } from "../../booker/BookerPlatformWrapper"; +import type { + BookerPlatformWrapperAtomPropsForIndividual, + BookerPlatformWrapperAtomPropsForTeam, +} from "../../booker/types"; +import { useGetBookingForReschedule } from "../../hooks/bookings/useGetBookingForReschedule"; +import { useAtomGetPublicEvent } from "../../hooks/event-types/public/useAtomGetPublicEvent"; +import { useEventType } from "../../hooks/event-types/public/useEventType"; +import { useTeamEventType } from "../../hooks/event-types/public/useTeamEventType"; +import { useAvailableSlots } from "../../hooks/useAvailableSlots"; + +const CalendarViewPlatformWrapperComponent = ( + props: BookerPlatformWrapperAtomPropsForIndividual | BookerPlatformWrapperAtomPropsForTeam +) => { + const { + eventSlug, + isTeamEvent, + hostsLimit, + allowUpdatingUrlParams = false, + teamMemberEmail, + crmAppSlug, + crmOwnerRecordType, + view = "MONTH_VIEW", + } = props; + + const teamId: number | undefined = props.isTeamEvent ? props.teamId : undefined; + const username = useMemo(() => { + if (props.username) { + return formatUsername(props.username); + } + return ""; + }, [props.username]); + + const { isPending } = useEventType(username, eventSlug, isTeamEvent); + const { isPending: isTeamPending } = useTeamEventType(teamId, eventSlug, isTeamEvent, hostsLimit); + + const setSelectedDuration = useBookerStoreContext((state) => state.setSelectedDuration); + const selectedDuration = useBookerStoreContext((state) => state.selectedDuration); + + const event = useAtomGetPublicEvent({ + username, + eventSlug: props.eventSlug, + isTeamEvent: props.isTeamEvent, + teamId, + selectedDuration, + }); + + const bookerLayout = useBookerLayout(event.data?.profile?.bookerLayouts); + + const [bookerState, _setBookerState] = useBookerStoreContext( + (state) => [state.state, state.setState], + shallow + ); + const selectedDate = useBookerStoreContext((state) => state.selectedDate); + const date = dayjs(selectedDate).format("YYYY-MM-DD"); + const monthCount = + ((bookerLayout.layout !== BookerLayouts.WEEK_VIEW && bookerState === "selecting_time") || + bookerLayout.layout === BookerLayouts.COLUMN_VIEW) && + dayjs(date).add(1, "month").month() !== + dayjs(date).add(bookerLayout.columnViewExtraDays.current, "day").month() + ? 2 + : undefined; + const month = useBookerStoreContext((state) => state.month); + const [dayCount] = useBookerStoreContext((state) => [state.dayCount, state.setDayCount], shallow); + + const prefetchNextMonth = + (bookerLayout.layout === BookerLayouts.WEEK_VIEW && + !!bookerLayout.extraDays && + dayjs(date).month() !== dayjs(date).add(bookerLayout.extraDays, "day").month()) || + (bookerLayout.layout === BookerLayouts.COLUMN_VIEW && + dayjs(date).month() !== dayjs(date).add(bookerLayout.columnViewExtraDays.current, "day").month()); + + const [startTime, endTime] = useTimesForSchedule({ + month, + monthCount, + dayCount, + prefetchNextMonth, + selectedDate, + }); + + useEffect(() => { + setSelectedDuration(props.duration ?? null); + }, [props.duration, setSelectedDuration]); + + const { timezone } = useTimePreferences(); + const isDynamic = useMemo(() => { + return getUsernameList(username ?? "").length > 1; + }, [username]); + + const [routingParams, setRoutingParams] = useState<{ + routedTeamMemberIds?: number[]; + _shouldServeCache?: boolean; + skipContactOwner?: boolean; + isBookingDryRun?: boolean; + }>({}); + + useEffect(() => { + const searchParams = props.routingFormSearchParams + ? new URLSearchParams(props.routingFormSearchParams) + : new URLSearchParams(window.location.search); + + const routedTeamMemberIds = getRoutedTeamMemberIdsFromSearchParams(searchParams); + const skipContactOwner = searchParams.get("cal.skipContactOwner") === "true"; + + const _cacheParam = searchParams?.get("cal.cache"); + const _shouldServeCache = _cacheParam ? _cacheParam === "true" : undefined; + const isBookingDryRun = + searchParams?.get("cal.isBookingDryRun")?.toLowerCase() === "true" || + searchParams?.get("cal.sandbox")?.toLowerCase() === "true"; + setRoutingParams({ + ...(skipContactOwner ? { skipContactOwner } : {}), + ...(routedTeamMemberIds ? { routedTeamMemberIds } : {}), + ...(_shouldServeCache ? { _shouldServeCache } : {}), + ...(isBookingDryRun ? { isBookingDryRun } : {}), + }); + }, [props.routingFormSearchParams]); + const bookingData = useBookerStoreContext((state) => state.bookingData); + const setBookingData = useBookerStoreContext((state) => state.setBookingData); + const layout = BookerLayouts[view]; + + useGetBookingForReschedule({ + uid: props.rescheduleUid ?? props.bookingUid ?? "", + onSuccess: (data) => { + setBookingData(data); + }, + }); + + useInitializeBookerStoreContext({ + ...props, + teamMemberEmail, + crmAppSlug, + crmOwnerRecordType, + crmRecordId: props.crmRecordId, + eventId: event?.data?.id, + rescheduleUid: props.rescheduleUid ?? null, + bookingUid: props.bookingUid ?? null, + layout: layout, + org: props.entity?.orgSlug, + username, + bookingData, + isPlatform: true, + allowUpdatingUrlParams, + }); + + const schedule = useAvailableSlots({ + usernameList: getUsernameList(username), + eventTypeId: event?.data?.id ?? 0, + startTime, + endTime, + timeZone: timezone, + duration: selectedDuration ?? undefined, + rescheduleUid: props.rescheduleUid, + teamMemberEmail: props.teamMemberEmail ?? undefined, + ...(props.isTeamEvent + ? { + isTeamEvent: props.isTeamEvent, + teamId: teamId, + } + : {}), + enabled: + Boolean(teamId || username) && + Boolean(month) && + Boolean(timezone) && + (props.isTeamEvent ? !isTeamPending : !isPending) && + Boolean(event?.data?.id), + orgSlug: props.entity?.orgSlug ?? undefined, + eventTypeSlug: isDynamic ? "dynamic" : eventSlug || "", + ...routingParams, + }); + + return ( + + +
+ + + + + + ); +}; + +export const CalendarViewPlatformWrapper = ( + props: BookerPlatformWrapperAtomPropsForIndividual | BookerPlatformWrapperAtomPropsForTeam +) => { + return ( + + + + ); +}; diff --git a/packages/platform/atoms/event-types/wrappers/EventTypePlatformWrapper.tsx b/packages/platform/atoms/event-types/wrappers/EventTypePlatformWrapper.tsx index 81634ae83d..fc9fa64438 100644 --- a/packages/platform/atoms/event-types/wrappers/EventTypePlatformWrapper.tsx +++ b/packages/platform/atoms/event-types/wrappers/EventTypePlatformWrapper.tsx @@ -3,6 +3,7 @@ import { useQueryClient } from "@tanstack/react-query"; import { useRef, useState, useEffect, forwardRef, useImperativeHandle, useCallback } from "react"; +import { BookerStoreProvider } from "@calcom/features/bookings/Booker/BookerStoreProvider"; import type { ChildrenEventType } from "@calcom/features/eventtypes/components/ChildrenEventTypeSelect"; import { EventType as EventTypeComponent } from "@calcom/features/eventtypes/components/EventType"; import ManagedEventTypeDialog from "@calcom/features/eventtypes/components/dialogs/ManagedEventDialog"; @@ -417,20 +418,22 @@ export const EventTypePlatformWrapper = forwardRef< if (!eventTypeQueryData) return null; return ( - + + + ); }); diff --git a/packages/platform/atoms/index.ts b/packages/platform/atoms/index.ts index 9cad136808..7622eb877f 100644 --- a/packages/platform/atoms/index.ts +++ b/packages/platform/atoms/index.ts @@ -41,3 +41,4 @@ export { useCreateTeamEventType } from "./hooks/event-types/private/useCreateTea export { useOrganizationBookings } from "./hooks/organizations/bookings/useOrganizationBookings"; export { useOrganizationUserBookings } from "./hooks/organizations/bookings/useOrganizationUserBookings"; +export { CalendarViewPlatformWrapper as CalendarView } from "./calendar-view/index"; diff --git a/packages/platform/atoms/selected-calendars/wrappers/SelectedCalendarsSettingsPlatformWrapper.tsx b/packages/platform/atoms/selected-calendars/wrappers/SelectedCalendarsSettingsPlatformWrapper.tsx index becd316df1..bfa88f5789 100644 --- a/packages/platform/atoms/selected-calendars/wrappers/SelectedCalendarsSettingsPlatformWrapper.tsx +++ b/packages/platform/atoms/selected-calendars/wrappers/SelectedCalendarsSettingsPlatformWrapper.tsx @@ -15,12 +15,12 @@ import { Dropdown, DropdownMenuContent, DropdownMenuTrigger } from "@calcom/ui/c import { Switch } from "@calcom/ui/components/form"; import { List } from "@calcom/ui/components/list"; +import * as Connect from "../../connect"; import { AppleConnect } from "../../connect/apple/AppleConnect"; import { useAddSelectedCalendar } from "../../hooks/calendars/useAddSelectedCalendar"; import { useDeleteCalendarCredentials } from "../../hooks/calendars/useDeleteCalendarCredentials"; import { useRemoveSelectedCalendar } from "../../hooks/calendars/useRemoveSelectedCalendar"; import { useConnectedCalendars } from "../../hooks/useConnectedCalendars"; -import { Connect } from "../../index"; import { AtomsWrapper } from "../../src/components/atoms-wrapper"; import { useToast } from "../../src/components/ui/use-toast"; import { SelectedCalendarsSettings } from "../SelectedCalendarsSettings"; diff --git a/packages/platform/examples/base/src/components/Navbar/index.tsx b/packages/platform/examples/base/src/components/Navbar/index.tsx index 051ad00697..035de96cfb 100644 --- a/packages/platform/examples/base/src/components/Navbar/index.tsx +++ b/packages/platform/examples/base/src/components/Navbar/index.tsx @@ -3,6 +3,7 @@ import Link from "next/link"; const poppins = Poppins({ subsets: ["latin"], weight: ["400", "800"] }); +// eslint-disable-next-line @typescript-eslint/no-unused-vars export function Navbar({ username }: { username?: string }) { return (