refactor: move timezone-select, settings, and insights components from packages/features to apps/web/modules (#27227)

* refactor: move timezone-select, settings, and insights components from packages/features to apps/web/modules

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix

* fix

* wip

* wip

* wip

* wip

* wip

* wip

* wip

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Benny JooandDevin AI authored and GitHub committed 2026-01-26 12:05:18 +00:00
1 parent 216e871b22
commit 15268bcfb4
31 files changed
+103 -98

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@ import { TrpcProvider } from "app/_trpc/trpc-provider";
import { SessionProvider } from "next-auth/react";
import CacheProvider from "react-inlinesvg/provider";
import { WebPushProvider } from "@calcom/features/notifications/WebPushContext";
import { WebPushProvider } from "@calcom/web/modules/notifications/components/WebPushContext";
import { NotificationSoundHandler } from "@calcom/web/components/notification-sound-handler";
import useIsBookingPage from "@lib/hooks/useIsBookingPage";
@@ -6,7 +6,7 @@ import { z } from "zod";
import dayjs from "@calcom/dayjs";
import { useTimePreferences } from "@calcom/features/bookings/lib";
import { TimezoneSelect } from "@calcom/features/components/timezone-select";
import { TimezoneSelect } from "@calcom/web/modules/timezone/components/TimezoneSelect";
import { FULL_NAME_LENGTH_MAX_LIMIT } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
@@ -1,6 +1,6 @@
import dayjs from "@calcom/dayjs";
import { useTimePreferences } from "@calcom/features/bookings/lib/timePreferences";
import { TimezoneSelect } from "@calcom/features/components/timezone-select";
import { TimezoneSelect } from "@calcom/web/modules/timezone/components/TimezoneSelect";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { DatePicker, SettingsToggle } from "@calcom/ui/components/form";
import { DatePickerWithRange as DateRangePicker } from "@calcom/ui/components/form/date-range-picker/DateRangePicker";
@@ -24,7 +24,7 @@ import { ScrollableWithGradients } from "./ScrollableWithGradients";
import { useBookerTime } from "@calcom/features/bookings/Booker/components/hooks/useBookerTime";
const WebTimezoneSelect = dynamic(
() => import("@calcom/features/components/timezone-select").then((mod) => mod.TimezoneSelect),
() => import("@calcom/web/modules/timezone/components/TimezoneSelect").then((mod) => mod.TimezoneSelect),
{
ssr: false,
}
@@ -22,7 +22,7 @@ const LoadingState = () => {
const WebTimezoneSelect = dynamic(
() =>
import("@calcom/features/components/timezone-select").then(
import("@calcom/web/modules/timezone/components/TimezoneSelect").then(
(mod) => mod.TimezoneSelect
),
{
@@ -5,7 +5,7 @@ import { useRouter } from "next/navigation";
import { useEffect } from "react";
import { Controller, useForm } from "react-hook-form";
import { TimezoneSelect } from "@calcom/features/components/timezone-select";
import { TimezoneSelect } from "@calcom/web/modules/timezone/components/TimezoneSelect";
import LicenseRequired from "~/ee/common/components/LicenseRequired";
import { DisableAutofillOnBookingPageSwitch } from "~/ee/organizations/components/DisableAutofillOnBookingPageSwitch";
import { DisablePhoneOnlySMSNotificationsSwitch } from "~/ee/organizations/components/DisablePhoneOnlySMSNotificationsSwitch";
@@ -1,8 +1,8 @@
import { useEffect, useState } from "react";
import dayjs from "@calcom/dayjs";
import { TimezoneSelect } from "@calcom/features/components/timezone-select";
import type { ITimezone } from "@calcom/features/components/timezone-select";
import { TimezoneSelect } from "@calcom/web/modules/timezone/components/TimezoneSelect";
import type { ITimezone } from "@calcom/features/timezone/components/TimezoneSelectComponent";
import LicenseRequired from "~/ee/common/components/LicenseRequired";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -3,7 +3,7 @@
import { noop } from "lodash";
import { Controller, useForm } from "react-hook-form";
import { TimezoneSelect } from "@calcom/features/components/timezone-select";
import { TimezoneSelect } from "@calcom/web/modules/timezone/components/TimezoneSelect";
import { formatToLocalizedDate } from "@calcom/lib/dayjs";
import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
import { useLocale } from "@calcom/lib/hooks/useLocale";
+1 -1
View File
@@ -24,7 +24,7 @@ import {
} from "@calcom/features/bookings/Booker/utils/event";
import DatePicker from "@calcom/features/calendars/DatePicker";
import { Dialog } from "@calcom/features/components/controlled-dialog";
import { TimezoneSelect } from "@calcom/features/components/timezone-select";
import { TimezoneSelect } from "@calcom/web/modules/timezone/components/TimezoneSelect";
import type { Slot } from "@calcom/features/schedules/lib/use-schedule/types";
import { useNonEmptyScheduleDays } from "@calcom/features/schedules/lib/use-schedule/useNonEmptyScheduleDays";
import { useSlotsForDate } from "@calcom/features/schedules/lib/use-schedule/useSlotsForDate";
@@ -14,7 +14,7 @@ import {
import { Timezone as PlatformTimzoneSelect } from "@calcom/atoms/timezone";
import getLocationsOptionsForSelect from "@calcom/features/bookings/lib/getLocationOptionsForSelect";
import DestinationCalendarSelector from "@calcom/features/calendars/DestinationCalendarSelector";
import { TimezoneSelect as WebTimezoneSelect } from "@calcom/features/components/timezone-select";
import { TimezoneSelect as WebTimezoneSelect } from "@calcom/web/modules/timezone/components/TimezoneSelect";
import useLockedFieldsManager from "@calcom/features/ee/managed-event-types/hooks/useLockedFieldsManager";
import {
allowDisablingAttendeeConfirmationEmails,
@@ -4,7 +4,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Badge } from "@calcom/ui/components/badge";
import { Tooltip } from "@calcom/ui/components/tooltip";
import type { RoutingFormTableRow } from "@calcom/features/insights/lib/types";
import type { RoutingFormTableRow } from "@calcom/web/modules/insights/lib/types";
import { CellWithOverflowX } from "./CellWithOverflowX";
export function BookedByCell({
@@ -15,7 +15,7 @@ import {
} from "@calcom/ui/components/hover-card";
import { Icon } from "@calcom/ui/components/icon";
import type { RoutingFormTableRow } from "@calcom/features/insights/lib/types";
import type { RoutingFormTableRow } from "@calcom/web/modules/insights/lib/types";
import { BookingStatusBadge } from "./BookingStatusBadge";
export function BookingAtCell({ row, rowId }: { row: RoutingFormTableRow; rowId: number }) {
@@ -24,7 +24,7 @@ import { OrgTeamsFilter } from "../filters/OrgTeamsFilter";
import { useInsightsColumns } from "@calcom/web/modules/insights/hooks/useInsightsColumns";
import { useInsightsOrgTeams } from "@calcom/web/modules/insights/hooks/useInsightsOrgTeams";
import { useInsightsRoutingFacetedUniqueValues } from "@calcom/web/modules/insights/hooks/useInsightsRoutingFacetedUniqueValues";
import type { RoutingFormTableRow } from "@calcom/features/insights/lib/types";
import type { RoutingFormTableRow } from "@calcom/web/modules/insights/lib/types";
import { RoutingKPICards } from "./RoutingKPICards";
import { EmptyScreen } from "@calcom/ui/components/empty-screen";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -16,13 +16,13 @@ import { BookedByCell } from "../components/BookedByCell";
import { BookingAtCell } from "../components/BookingAtCell";
import { BookingStatusBadge } from "../components/BookingStatusBadge";
import { ResponseValueCell } from "../components/ResponseValueCell";
import type { HeaderRow, RoutingFormTableRow } from "@calcom/features/insights/lib/types";
import type { HeaderRow, RoutingFormTableRow } from "@calcom/web/modules/insights/lib/types";
import {
ZResponseMultipleValues,
ZResponseSingleValue,
ZResponseTextValue,
ZResponseNumericValue,
} from "@calcom/features/insights/lib/types";
} from "@calcom/web/modules/insights/lib/types";
export const useInsightsColumns = ({
headers,
@@ -6,7 +6,7 @@ import { BookingStatus } from "@calcom/prisma/enums";
import { trpc } from "@calcom/trpc/react";
import { bookingStatusToText } from "@calcom/features/insights/lib/bookingStatusToText";
import type { HeaderRow } from "@calcom/features/insights/lib/types";
import type { HeaderRow } from "@calcom/web/modules/insights/lib/types";
const statusOrder: Record<BookingStatus, number> = {
[BookingStatus.ACCEPTED]: 1,
@@ -13,7 +13,7 @@ interface WebPushContextProps {
unsubscribe: () => Promise<void>;
}
const WebPushContext = createContext<WebPushContextProps | null>(null);
export const WebPushContext = createContext<WebPushContextProps | null>(null);
interface ProviderProps {
children: React.ReactNode;
@@ -110,14 +110,6 @@ export function WebPushProvider({ children }: ProviderProps) {
return <WebPushContext.Provider value={contextValue}>{children}</WebPushContext.Provider>;
}
export function useWebPush() {
const context = useContext(WebPushContext);
if (!context) {
throw new Error("useWebPush must be used within a WebPushProvider");
}
return context;
}
const urlB64ToUint8Array = (base64String: string) => {
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
const base64 = (base64String + padding).replace(/\-/g, "+").replace(/_/g, "/");
@@ -0,0 +1,11 @@
import { useContext } from "react";
import { WebPushContext } from "../components/WebPushContext";
export function useWebPush() {
const context = useContext(WebPushContext);
if (!context) {
throw new Error("useWebPush must be used within a WebPushProvider");
}
return context;
}
@@ -5,7 +5,7 @@ import { useSession } from "next-auth/react";
import { useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { TimezoneSelect } from "@calcom/features/components/timezone-select";
import { TimezoneSelect } from "@calcom/web/modules/timezone/components/TimezoneSelect";
import SectionBottomActions from "@calcom/features/settings/SectionBottomActions";
import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader";
import { formatLocalizedDateTime } from "@calcom/lib/dayjs";
@@ -1,6 +1,6 @@
"use client";
import { useWebPush } from "@calcom/features/notifications/WebPushContext";
import { useWebPush } from "@calcom/web/modules/notifications/hooks/useWebPush";
import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button } from "@calcom/ui/components/button";
+3 -2
View File
@@ -3,13 +3,14 @@
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
import type { Dispatch, ReactElement, ReactNode, SetStateAction } from "react";
import React, { cloneElement } from "react";
import type React from "react";
import { cloneElement } from "react";
import { Toaster } from "sonner";
import { useRedirectToLoginIfUnauthenticated } from "@calcom/features/auth/lib/hooks/useRedirectToLoginIfUnauthenticated";
import { useRedirectToOnboardingIfNeeded } from "@calcom/features/auth/lib/hooks/useRedirectToOnboardingIfNeeded";
import { useFormbricks } from "@calcom/features/formbricks/formbricks-client";
import TimezoneChangeDialog from "@calcom/features/settings/TimezoneChangeDialog";
import TimezoneChangeDialog from "@calcom/web/modules/settings/components/TimezoneChangeDialog";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import classNames from "@calcom/ui/classNames";
import { Button } from "@calcom/ui/components/button";
@@ -1,7 +1,7 @@
import { useFieldArray, useForm, useFormContext } from "react-hook-form";
import dayjs from "@calcom/dayjs";
import { TimezoneSelect } from "@calcom/features/components/timezone-select";
import { TimezoneSelect } from "@calcom/web/modules/timezone/components/TimezoneSelect";
import DateOverrideInputDialog from "@calcom/features/schedules/components/DateOverrideInputDialog";
import DateOverrideList from "@calcom/features/schedules/components/DateOverrideList";
import Schedule from "@calcom/features/schedules/components/Schedule";
@@ -0,0 +1,60 @@
"use client";
import type { Timezones } from "@calcom/lib/timezone";
import { TimezoneSelectComponent } from "@calcom/features/timezone/components/TimezoneSelectComponent";
import { CALCOM_VERSION } from "@calcom/lib/constants";
import { trpc } from "@calcom/trpc/react";
import { useMemo } from "react";
import type { Props as SelectProps } from "react-timezone-select";
const SELECT_SEARCH_DATA: Timezones = [
{ label: "San Francisco", timezone: "America/Los_Angeles" },
{ label: "Sao Francisco do Sul", timezone: "America/Sao_Paulo" },
{ label: "San Francisco de Macoris", timezone: "America/Santo_Domingo" },
{ label: "San Francisco Gotera", timezone: "America/El_Salvador" },
{ label: "Eastern Time - US & Canada", timezone: "America/New_York" },
{ label: "Pacific Time - US & Canada", timezone: "America/Los_Angeles" },
{ label: "Central Time - US & Canada", timezone: "America/Chicago" },
{ label: "Mountain Time - US & Canada", timezone: "America/Denver" },
{ label: "Atlantic Time - Canada", timezone: "America/Halifax" },
{ label: "Eastern European Time", timezone: "Europe/Bucharest" },
{ label: "Central European Time", timezone: "Europe/Berlin" },
{ label: "Western European Time", timezone: "Europe/London" },
{ label: "Australian Eastern Time", timezone: "Australia/Sydney" },
{ label: "Japan Standard Time", timezone: "Asia/Tokyo" },
{ label: "India Standard Time", timezone: "Asia/Kolkata" },
{ label: "Gulf Standard Time", timezone: "Asia/Dubai" },
{ label: "South Africa Standard Time", timezone: "Africa/Johannesburg" },
{ label: "Brazil Time", timezone: "America/Sao_Paulo" },
{ label: "Hawaii-Aleutian Standard Time", timezone: "Pacific/Honolulu" },
];
export type TimezoneSelectProps = SelectProps & {
variant?: "default" | "minimal";
timezoneSelectCustomClassname?: string;
size?: "sm" | "md";
grow?: boolean;
};
export function TimezoneSelect(props: TimezoneSelectProps) {
const { data = [], isPending } = trpc.viewer.timezones.cityTimezones.useQuery(
{
CalComVersion: CALCOM_VERSION,
},
{
trpc: { context: { skipBatch: true } },
}
);
const cityTimezonesFormatted = useMemo(
() => data.map(({ city, timezone }) => ({ label: city, timezone })),
[data]
);
const combinedData = useMemo(
() => [...cityTimezonesFormatted, ...SELECT_SEARCH_DATA],
[cityTimezonesFormatted]
);
return <TimezoneSelectComponent data={combinedData} isPending={isPending} {...props} />;
}
@@ -5,7 +5,7 @@ import { useMemo, useState } from "react";
import { Controller, useForm, useFormContext } from "react-hook-form";
import { z } from "zod";
import { TimezoneSelect } from "@calcom/features/components/timezone-select";
import { TimezoneSelect } from "@calcom/web/modules/timezone/components/TimezoneSelect";
import { timeZoneSchema } from "@calcom/lib/dayjs/timeZone.schema";
import { emailSchema } from "@calcom/lib/emailSchema";
import { useLocale } from "@calcom/lib/hooks/useLocale";
+1 -1
View File
@@ -4,7 +4,7 @@ import { SessionProvider } from "next-auth/react";
import React from "react";
import CacheProvider from "react-inlinesvg/provider";
import { WebPushProvider } from "@calcom/features/notifications/WebPushContext";
import { WebPushProvider } from "@calcom/web/modules/notifications/components/WebPushContext";
import { trpc } from "@calcom/trpc/react";
import type { AppProps } from "@lib/app-providers";
@@ -1,7 +0,0 @@
export { TimezoneSelect, TimezoneSelectComponent } from "./TimezoneSelect";
export type {
ITimezone,
ITimezoneOption,
TimezoneSelectProps,
TimezoneSelectComponentProps,
} from "./TimezoneSelect";
@@ -1,66 +1,13 @@
"use client";
import { CALCOM_VERSION } from "@calcom/lib/constants";
import type { Timezones } from "@calcom/lib/timezone";
import { addTimezonesToDropdown, filterBySearchText, handleOptionLabel } from "@calcom/lib/timezone";
import { trpc } from "@calcom/trpc/react";
import classNames from "@calcom/ui/classNames";
import { getReactSelectProps, inputStyles } from "@calcom/ui/components/form";
import { useCallback, useMemo, useState } from "react";
import type { ITimezone, ITimezoneOption, Props as SelectProps } from "react-timezone-select";
import BaseSelect from "react-timezone-select";
const SELECT_SEARCH_DATA: Timezones = [
{ label: "San Francisco", timezone: "America/Los_Angeles" },
{ label: "Sao Francisco do Sul", timezone: "America/Sao_Paulo" },
{ label: "San Francisco de Macoris", timezone: "America/Santo_Domingo" },
{ label: "San Francisco Gotera", timezone: "America/El_Salvador" },
{ label: "Eastern Time - US & Canada", timezone: "America/New_York" },
{ label: "Pacific Time - US & Canada", timezone: "America/Los_Angeles" },
{ label: "Central Time - US & Canada", timezone: "America/Chicago" },
{ label: "Mountain Time - US & Canada", timezone: "America/Denver" },
{ label: "Atlantic Time - Canada", timezone: "America/Halifax" },
{ label: "Eastern European Time", timezone: "Europe/Bucharest" },
{ label: "Central European Time", timezone: "Europe/Berlin" },
{ label: "Western European Time", timezone: "Europe/London" },
{ label: "Australian Eastern Time", timezone: "Australia/Sydney" },
{ label: "Japan Standard Time", timezone: "Asia/Tokyo" },
{ label: "India Standard Time", timezone: "Asia/Kolkata" },
{ label: "Gulf Standard Time", timezone: "Asia/Dubai" },
{ label: "South Africa Standard Time", timezone: "Africa/Johannesburg" },
{ label: "Brazil Time", timezone: "America/Sao_Paulo" },
{ label: "Hawaii-Aleutian Standard Time", timezone: "Pacific/Honolulu" },
];
export type TimezoneSelectProps = SelectProps & {
variant?: "default" | "minimal";
timezoneSelectCustomClassname?: string;
size?: "sm" | "md";
grow?: boolean;
};
export function TimezoneSelect(props: TimezoneSelectProps) {
const { data = [], isPending } = trpc.viewer.timezones.cityTimezones.useQuery(
{
CalComVersion: CALCOM_VERSION,
},
{
trpc: { context: { skipBatch: true } },
}
);
const cityTimezonesFormatted = useMemo(
() => data.map(({ city, timezone }) => ({ label: city, timezone })),
[data]
);
const combinedData = useMemo(
() => [...cityTimezonesFormatted, ...SELECT_SEARCH_DATA],
[cityTimezonesFormatted]
);
return <TimezoneSelectComponent data={combinedData} isPending={isPending} {...props} />;
}
export type TimezoneSelectComponentProps = SelectProps & {
variant?: "default" | "minimal";
isPending: boolean;
@@ -1,7 +1,8 @@
"use client";
import type { SetStateAction, Dispatch } from "react";
import React, {
import React from "react";
import {
useMemo,
useState,
useEffect,
@@ -15,7 +16,7 @@ import { Controller, useFieldArray, useForm, useFormContext, useWatch } from "re
import dayjs from "@calcom/dayjs";
import { BookerStoreProvider } from "@calcom/features/bookings/Booker/BookerStoreProvider";
import { Dialog } from "@calcom/features/components/controlled-dialog";
import { TimezoneSelect as WebTimezoneSelect } from "@calcom/features/components/timezone-select";
import { TimezoneSelect as WebTimezoneSelect } from "@calcom/web/modules/timezone/components/TimezoneSelect";
import type {
BulkUpdatParams,
EventTypes,
+3 -3
View File
@@ -1,12 +1,12 @@
import { useMemo } from "react";
import { TimezoneSelectComponent as TimezoneSelect } from "@calcom/features/components/timezone-select";
import type { TimezoneSelectProps } from "@calcom/features/components/timezone-select";
import { TimezoneSelectComponent as TimezoneSelect } from "@calcom/features/timezone/components/TimezoneSelectComponent";
import type { TimezoneSelectComponentProps } from "@calcom/features/timezone/components/TimezoneSelectComponent";
import type { Timezone } from "@calcom/features/bookings/Booker/types";
import useGetCityTimezones from "../hooks/useGetCityTimezones";
import { filterPropsTimezones, formatTimezones } from "../src/lib/timeZones";
export function Timezone(props: TimezoneSelectProps & { timeZones?: Timezone[] }) {
export function Timezone(props: Omit<TimezoneSelectComponentProps, "data" | "isPending" | "isWebTimezoneSelect"> & { timeZones?: Timezone[] }) {
const { isLoading: isLoadingAvailableCityTimezones, data: availableCityTimezones } = useGetCityTimezones();
const cityTimeZones = useMemo(() => {
if (props.timeZones) {