diff --git a/apps/web/components/apps/routing-forms/TestFormDialog.test.tsx b/apps/web/components/apps/routing-forms/TestFormDialog.test.tsx index 1dbeec8d5b..f001a6f16a 100644 --- a/apps/web/components/apps/routing-forms/TestFormDialog.test.tsx +++ b/apps/web/components/apps/routing-forms/TestFormDialog.test.tsx @@ -64,9 +64,6 @@ vi.mock("@calcom/web/modules/shell/Shell", () => ({ ShellMain: vi.fn(), })); -vi.mock("@calcom/lib/hooks/useApp", () => ({ - default: vi.fn(), -})); /** * Avoids the error due to Formbricks */ diff --git a/apps/web/components/dialog/EditLocationDialog.tsx b/apps/web/components/dialog/EditLocationDialog.tsx index 27fb333380..37a3cba4b3 100644 --- a/apps/web/components/dialog/EditLocationDialog.tsx +++ b/apps/web/components/dialog/EditLocationDialog.tsx @@ -15,7 +15,7 @@ import { OrganizerDefaultConferencingAppType, } from "@calcom/app-store/locations"; import { Dialog } from "@calcom/features/components/controlled-dialog"; -import PhoneInput from "@calcom/features/components/phone-input"; +import PhoneInput from "@calcom/web/components/phone-input"; import type { LocationOption } from "@calcom/features/form/components/LocationSelect"; import LocationSelect from "@calcom/features/form/components/LocationSelect"; import { useLocale } from "@calcom/lib/hooks/useLocale"; diff --git a/packages/features/components/phone-input/PhoneInput.tsx b/apps/web/components/phone-input/PhoneInput.tsx similarity index 100% rename from packages/features/components/phone-input/PhoneInput.tsx rename to apps/web/components/phone-input/PhoneInput.tsx diff --git a/packages/features/components/phone-input/index.ts b/apps/web/components/phone-input/index.ts similarity index 100% rename from packages/features/components/phone-input/index.ts rename to apps/web/components/phone-input/index.ts diff --git a/apps/web/modules/bookings/components/BookEventForm/BookingFields.tsx b/apps/web/modules/bookings/components/BookEventForm/BookingFields.tsx index a64b3b7718..dde938795f 100644 --- a/apps/web/modules/bookings/components/BookEventForm/BookingFields.tsx +++ b/apps/web/modules/bookings/components/BookEventForm/BookingFields.tsx @@ -8,7 +8,7 @@ import { DefaultEventLocationTypeEnum } from "@calcom/app-store/locations"; import { useBookerStore } from "@calcom/features/bookings/Booker/store"; import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking"; import getLocationOptionsForSelect from "@calcom/features/bookings/lib/getLocationOptionsForSelect"; -import { FormBuilderField } from "@calcom/features/form-builder/FormBuilderField"; +import { FormBuilderField } from "@calcom/web/modules/form-builder/components/FormBuilderField"; import { fieldTypesConfigMap } from "@calcom/features/form-builder/fieldTypes"; import { fieldsThatSupportLabelAsSafeHtml } from "@calcom/features/form-builder/fieldsThatSupportLabelAsSafeHtml"; import { SystemField } from "@calcom/lib/bookings/SystemField"; diff --git a/apps/web/modules/ee/workflows/components/AddActionDialog.tsx b/apps/web/modules/ee/workflows/components/AddActionDialog.tsx index bfc2cfd36d..5e727c232c 100644 --- a/apps/web/modules/ee/workflows/components/AddActionDialog.tsx +++ b/apps/web/modules/ee/workflows/components/AddActionDialog.tsx @@ -6,7 +6,7 @@ import { Controller, useForm } from "react-hook-form"; import { z } from "zod"; import { Dialog } from "@calcom/features/components/controlled-dialog"; -import PhoneInput from "@calcom/features/components/phone-input"; +import PhoneInput from "@calcom/web/components/phone-input"; import { WORKFLOW_ACTIONS } from "@calcom/features/ee/workflows/lib/constants"; import { onlyLettersNumbersSpaces } from "@calcom/features/ee/workflows/lib/schema"; import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants"; diff --git a/apps/web/modules/ee/workflows/components/TestPhoneCallDialog.tsx b/apps/web/modules/ee/workflows/components/TestPhoneCallDialog.tsx index 6164c99b7e..0320b527b7 100644 --- a/apps/web/modules/ee/workflows/components/TestPhoneCallDialog.tsx +++ b/apps/web/modules/ee/workflows/components/TestPhoneCallDialog.tsx @@ -2,7 +2,7 @@ import { useState } from "react"; import type { UseFormReturn } from "react-hook-form"; import { Dialog } from "@calcom/features/components/controlled-dialog"; -import PhoneInput from "@calcom/features/components/phone-input"; +import PhoneInput from "@calcom/web/components/phone-input"; import { getEventTypeIdForCalAiTest } from "@calcom/features/ee/workflows/lib/actionHelperFunctions"; import type { FormValues } from "@calcom/features/ee/workflows/lib/types"; import { useLocale } from "@calcom/lib/hooks/useLocale"; diff --git a/apps/web/modules/ee/workflows/components/WorkflowStepContainer.tsx b/apps/web/modules/ee/workflows/components/WorkflowStepContainer.tsx index 13836eb885..6175f5c3d8 100644 --- a/apps/web/modules/ee/workflows/components/WorkflowStepContainer.tsx +++ b/apps/web/modules/ee/workflows/components/WorkflowStepContainer.tsx @@ -8,7 +8,7 @@ import "react-phone-number-input/style.css"; import type { RetellAgentWithDetails } from "@calcom/features/calAIPhone/providers/retellAI"; import { Dialog } from "@calcom/features/components/controlled-dialog"; -import PhoneInput from "@calcom/features/components/phone-input"; +import PhoneInput from "@calcom/web/components/phone-input"; import { isSMSAction, isWhatsappAction, diff --git a/apps/web/modules/event-types/components/locations/DefaultLocationSettings.tsx b/apps/web/modules/event-types/components/locations/DefaultLocationSettings.tsx index 2127852e36..0b21a47b46 100644 --- a/apps/web/modules/event-types/components/locations/DefaultLocationSettings.tsx +++ b/apps/web/modules/event-types/components/locations/DefaultLocationSettings.tsx @@ -9,7 +9,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale"; import classNames from "@calcom/ui/classNames"; import { TextField } from "@calcom/ui/components/form"; -import LocationInput from "@calcom/features/eventtypes/components/locations/LocationInput"; +import LocationInput from "./LocationInput"; import LocationOptionContainer from "./LocationSettingsContainer"; const DefaultLocationSettings = ({ diff --git a/apps/web/modules/event-types/components/locations/HostLocations.tsx b/apps/web/modules/event-types/components/locations/HostLocations.tsx index a1c7ab7e75..220236e8e5 100644 --- a/apps/web/modules/event-types/components/locations/HostLocations.tsx +++ b/apps/web/modules/event-types/components/locations/HostLocations.tsx @@ -15,7 +15,7 @@ import { isStaticLocationType, } from "@calcom/app-store/locations"; import { getAppFromSlug } from "@calcom/app-store/utils"; -import PhoneInput from "@calcom/features/components/phone-input"; +import PhoneInput from "@calcom/web/components/phone-input"; import invertLogoOnDark from "@calcom/lib/invertLogoOnDark"; import type { LocationOption } from "@calcom/features/form/components/LocationSelect"; import LocationSelect from "@calcom/features/form/components/LocationSelect"; diff --git a/packages/features/eventtypes/components/locations/LocationInput.tsx b/apps/web/modules/event-types/components/locations/LocationInput.tsx similarity index 93% rename from packages/features/eventtypes/components/locations/LocationInput.tsx rename to apps/web/modules/event-types/components/locations/LocationInput.tsx index b0485526df..73f417596b 100644 --- a/packages/features/eventtypes/components/locations/LocationInput.tsx +++ b/apps/web/modules/event-types/components/locations/LocationInput.tsx @@ -1,13 +1,13 @@ import { useFormContext, Controller } from "react-hook-form"; import type { EventLocationType } from "@calcom/app-store/locations"; -import PhoneInput from "@calcom/features/components/phone-input"; +import PhoneInput from "@calcom/web/components/phone-input"; import type { FormValues } from "@calcom/features/eventtypes/lib/types"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import classNames from "@calcom/ui/classNames"; import { TextField } from "@calcom/ui/components/form"; -import type { LocationInputCustomClassNames } from "./types"; +import type { LocationInputCustomClassNames } from "@calcom/features/eventtypes/components/locations/types"; const LocationInput = (props: { eventLocationType: EventLocationType; diff --git a/apps/web/modules/event-types/components/locations/Locations.tsx b/apps/web/modules/event-types/components/locations/Locations.tsx index 6a6637a1fe..5907be54ff 100644 --- a/apps/web/modules/event-types/components/locations/Locations.tsx +++ b/apps/web/modules/event-types/components/locations/Locations.tsx @@ -23,7 +23,7 @@ import { showToast } from "@calcom/ui/components/toast"; import CalVideoSettings from "./CalVideoSettings"; import DefaultLocationSettings from "./DefaultLocationSettings"; -import LocationInput from "@calcom/features/eventtypes/components/locations/LocationInput"; +import LocationInput from "./LocationInput"; export type TEventTypeLocation = Pick; export type TLocationOptions = Pick["locationOptions"]; diff --git a/apps/web/modules/event-types/components/tabs/ai/AIEventController.tsx b/apps/web/modules/event-types/components/tabs/ai/AIEventController.tsx index 71e82b5c69..c94955df2f 100644 --- a/apps/web/modules/event-types/components/tabs/ai/AIEventController.tsx +++ b/apps/web/modules/event-types/components/tabs/ai/AIEventController.tsx @@ -7,10 +7,10 @@ import { z } from "zod"; import { getTemplateFieldsSchema } from "@calcom/features/calAIPhone/getTemplateFieldsSchema"; import { templateFieldsMap } from "@calcom/features/calAIPhone/template-fields-map"; import type { TemplateType } from "@calcom/features/calAIPhone/zod-utils"; -import PhoneInput from "@calcom/features/components/phone-input"; +import PhoneInput from "@calcom/web/components/phone-input"; import LicenseRequired from "~/ee/common/components/LicenseRequired"; import type { EventTypeSetup, FormValues } from "@calcom/features/eventtypes/lib/types"; -import { ComponentForField } from "@calcom/features/form-builder/FormBuilderField"; +import { ComponentForField } from "@calcom/web/modules/form-builder/components/FormBuilderField"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import classNames from "@calcom/ui/classNames"; diff --git a/packages/features/form-builder/Components.tsx b/apps/web/modules/form-builder/components/Components.tsx similarity index 98% rename from packages/features/form-builder/Components.tsx rename to apps/web/modules/form-builder/components/Components.tsx index ed72d16e3c..4a43c42ab3 100644 --- a/packages/features/form-builder/Components.tsx +++ b/apps/web/modules/form-builder/components/Components.tsx @@ -6,7 +6,7 @@ import type { TextLikeComponentProps, } from "@calcom/app-store/routing-forms/components/react-awesome-query-builder/widgets"; import Widgets from "@calcom/app-store/routing-forms/components/react-awesome-query-builder/widgets"; -import PhoneInput from "@calcom/features/components/phone-input"; +import PhoneInput from "@calcom/web/components/phone-input"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import type { fieldSchema, variantsConfigSchema, FieldType } from "@calcom/prisma/zod-utils"; import { AddressInput } from "@calcom/ui/components/address"; @@ -18,8 +18,8 @@ import { RadioGroup, RadioField } from "@calcom/ui/components/radio"; import { Tooltip } from "@calcom/ui/components/tooltip"; import { ComponentForField } from "./FormBuilderField"; -import { propsTypes } from "./propsTypes"; -import { preprocessNameFieldDataWithVariant } from "./utils"; +import { propsTypes } from "@calcom/features/form-builder/propsTypes"; +import { preprocessNameFieldDataWithVariant } from "@calcom/features/form-builder/utils"; export const isValidValueProp: Record boolean> = { boolean: (val) => typeof val === "boolean", diff --git a/packages/features/form-builder/FormBuilderField.test.tsx b/apps/web/modules/form-builder/components/FormBuilderField.test.tsx similarity index 95% rename from packages/features/form-builder/FormBuilderField.test.tsx rename to apps/web/modules/form-builder/components/FormBuilderField.test.tsx index ea804eb0e8..8bfcc41808 100644 --- a/packages/features/form-builder/FormBuilderField.test.tsx +++ b/apps/web/modules/form-builder/components/FormBuilderField.test.tsx @@ -59,7 +59,7 @@ describe("FormBuilderField", () => { }); const component = { - getFieldInput: ({ label }) => screen.getByRole("textbox", { name: label }) as HTMLInputElement, + getFieldInput: ({ label }: { label: string }) => screen.getByRole("textbox", { name: label }) as HTMLInputElement, fillFieldInput: ({ label, value }: { label: string; value: string }) => { fireEvent.change(component.getFieldInput({ label }), { target: { value } }); }, diff --git a/packages/features/form-builder/FormBuilderField.tsx b/apps/web/modules/form-builder/components/FormBuilderField.tsx similarity index 97% rename from packages/features/form-builder/FormBuilderField.tsx rename to apps/web/modules/form-builder/components/FormBuilderField.tsx index f2930b4782..f9aaf76826 100644 --- a/packages/features/form-builder/FormBuilderField.tsx +++ b/apps/web/modules/form-builder/components/FormBuilderField.tsx @@ -11,14 +11,14 @@ import { Label } from "@calcom/ui/components/form"; import { Icon } from "@calcom/ui/components/icon"; import { Components, isValidValueProp } from "./Components"; -import { fieldTypesConfigMap } from "./fieldTypes"; -import { fieldsThatSupportLabelAsSafeHtml } from "./fieldsThatSupportLabelAsSafeHtml"; -import type { fieldsSchema } from "./schema"; +import { fieldTypesConfigMap } from "@calcom/features/form-builder/fieldTypes"; +import { fieldsThatSupportLabelAsSafeHtml } from "@calcom/features/form-builder/fieldsThatSupportLabelAsSafeHtml"; +import type { fieldsSchema } from "@calcom/features/form-builder/schema"; import { useShouldBeDisabledDueToPrefill, getFieldNameFromErrorMessage, -} from "./useShouldBeDisabledDueToPrefill"; -import { getTranslatedConfig as getTranslatedVariantsConfig } from "./utils/variantsConfig"; +} from "@calcom/features/form-builder/useShouldBeDisabledDueToPrefill"; +import { getTranslatedConfig as getTranslatedVariantsConfig } from "@calcom/features/form-builder/utils/variantsConfig"; // helper to render markdown label safely const renderLabel = (field: Partial) => { diff --git a/packages/app-store/_components/AppCard.tsx b/packages/app-store/_components/AppCard.tsx index a24a594f73..1069dd64d3 100644 --- a/packages/app-store/_components/AppCard.tsx +++ b/packages/app-store/_components/AppCard.tsx @@ -115,7 +115,6 @@ export default function AppCard({ ) : ( ; @@ -14,28 +12,23 @@ type AppData = Pick void; returnTo?: string; teamId?: number; }) { const { t } = useLocale(); - const { data: fetchedApp } = useApp(appId, { enabled: !appProp }); - const app = appProp ?? fetchedApp; const mutation = useAddAppMutation(null, { returnTo, @@ -49,10 +42,6 @@ export default function OmniInstallAppButton({ }, }); - if (!app) { - return null; - } - return ( ; +export type PublicEvent = NonNullable; export type BookerEventQuery = { isSuccess: boolean; diff --git a/packages/features/eventtypes/lib/types.ts b/packages/features/eventtypes/lib/types.ts index 07c7b43281..06695d54c5 100644 --- a/packages/features/eventtypes/lib/types.ts +++ b/packages/features/eventtypes/lib/types.ts @@ -1,21 +1,25 @@ -import { z } from "zod"; - +import type { ConnectedApps } from "@calcom/app-store/_utils/getConnectedApps"; import type { EventLocationType } from "@calcom/app-store/locations"; import type { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils"; +import type { TemplateType } from "@calcom/features/calAIPhone/zod-utils"; import type { ChildrenEventType } from "@calcom/features/eventtypes/lib/childrenEventType"; import type { IntervalLimit } from "@calcom/lib/intervalLimits/intervalLimitSchema"; import type { AttributesQueryValue } from "@calcom/lib/raqb/types"; import type { EventTypeTranslation } from "@calcom/prisma/client"; -import { type PeriodType, SchedulingType } from "@calcom/prisma/enums"; -import type { BookerLayoutSettings } from "@calcom/prisma/zod-utils"; -import type { customInputSchema } from "@calcom/prisma/zod-utils"; -import type { eventTypeBookingFields } from "@calcom/prisma/zod-utils"; -import type { eventTypeColor } from "@calcom/prisma/zod-utils"; -import type { RouterOutputs, RouterInputs } from "@calcom/trpc/react"; +import type { MembershipRole, PeriodType, SchedulingType } from "@calcom/prisma/enums"; +import type { + BookerLayoutSettings, + CustomInputSchema, + customInputSchema, + EventTypeLocation, + EventTypeMetadata, + eventTypeBookingFields, + eventTypeColor, +} from "@calcom/prisma/zod-utils"; import type { RecurringEvent } from "@calcom/types/Calendar"; -import { MembershipRole } from "@calcom/prisma/enums"; import type { UserProfile } from "@calcom/types/UserProfile"; - +import type { z } from "zod"; +import type { EventType } from "./getEventTypeById"; export type CustomInputParsed = typeof customInputSchema._output; export type AvailabilityOption = { @@ -24,9 +28,9 @@ export type AvailabilityOption = { isDefault: boolean; isManaged?: boolean; }; -export type EventTypeSetupProps = RouterOutputs["viewer"]["eventTypes"]["get"]; -export type EventTypeSetup = RouterOutputs["viewer"]["eventTypes"]["get"]["eventType"]; -export type EventTypeApps = RouterOutputs["viewer"]["apps"]["integrations"]; +export type EventTypeSetupProps = EventType; +export type EventTypeSetup = EventType["eventType"]; +export type EventTypeApps = ConnectedApps; export type HostLocation = { id?: string; userId: number; @@ -223,7 +227,223 @@ export type EventTypeHosts = { weight: number | null; groupId: string | null; }[]; -export type EventTypeUpdateInput = RouterInputs["viewer"]["eventTypesHeavy"]["update"]; + +// ============================================================================ +// EVENT TYPE UPDATE INPUT TYPES +// ============================================================================ +// These types define the shape of event type update operations and should be +// consumed by both the features package and tRPC routers. +// ============================================================================ + +export type HashedLinkInput = { + link: string; + expiresAt?: Date | null; + maxUsageCount?: number | null; + usageCount?: number | null; +}; + +export type AiPhoneCallConfig = { + generalPrompt: string; + enabled: boolean; + beginMessage: string | null; + yourPhoneNumber: string; + numberToCall: string; + guestName?: string | null; + guestEmail?: string | null; + guestCompany?: string | null; + templateType: TemplateType; +}; + +export type HostLocationInput = { + id?: string; + userId: number; + eventTypeId: number; + type: string; + credentialId?: number | null; + link?: string | null; + address?: string | null; + phoneNumber?: string | null; +}; + +export type HostInput = { + userId: number; + profileId?: number | null; + isFixed?: boolean; + priority?: number | null; + weight?: number | null; + scheduleId?: number | null; + groupId?: string | null; + location?: HostLocationInput | null; +}; + +export type HostGroupInput = { + id: string; + name: string; +}; + +export type ChildInput = { + owner: { + id: number; + name: string; + email: string; + eventTypeSlugs: string[]; + }; + hidden: boolean; +}; + +export type DestinationCalendarInput = { + integration: string; + externalId: string; +} | null; + +export type RecurringEventInput = { + dtstart?: Date; + interval: number; + count: number; + freq: number; + until?: Date; + tzid?: string; +} | null; + +export type EventTypeColorInput = { + lightEventTypeColor: string; + darkEventTypeColor: string; +} | null; + +/** + * Booking field type - minimal type definition for fields that need to be accessed. + * Only includes properties that are actually read in server code. + * Does NOT use an index signature to maintain compatibility with API v2 DTO classes. + */ +export type BookingFieldInput = { + name: string; + hidden?: boolean; + required?: boolean; + type?: string; +}; + +/** + * RR Segment query value - using index signature for complex RAQB structure. + * The values need to be indexable (string keys) for downstream usage. + */ +export type RRSegmentQueryValueInput = { + [key: string]: unknown; +} | null; + +/** + * Explicit type definition for event type update input. + * + * This type is defined explicitly rather than using z.infer<> on a complex + * schema chain to significantly reduce TypeScript type-checking time. + * The schema still validates all fields at runtime. + * + * All fields are optional (from .partial()) except `id` which is required. + */ +export type EventTypeUpdateInput = { + // Required field + id: number; + + // Fields from EventTypeSchema (all optional due to .partial()) + periodType?: PeriodType; + schedulingType?: SchedulingType | null; + title?: string; + slug?: string; + description?: string | null; + interfaceLanguage?: string | null; + position?: number; + locations?: EventTypeLocation[] | null; + length?: number; + offsetStart?: number; + hidden?: boolean; + userId?: number | null; + profileId?: number | null; + teamId?: number | null; + useEventLevelSelectedCalendars?: boolean; + eventName?: string | null; + parentId?: number | null; + bookingFields?: BookingFieldInput[] | null; + timeZone?: string | null; + periodStartDate?: Date | null; + periodEndDate?: Date | null; + periodDays?: number | null; + periodCountCalendarDays?: boolean | null; + lockTimeZoneToggleOnBookingPage?: boolean; + lockedTimeZone?: string | null; + requiresConfirmation?: boolean; + requiresConfirmationWillBlockSlot?: boolean; + requiresConfirmationForFreeEmail?: boolean; + requiresBookerEmailVerification?: boolean; + canSendCalVideoTranscriptionEmails?: boolean; + autoTranslateDescriptionEnabled?: boolean; + autoTranslateInstantMeetingTitleEnabled?: boolean; + recurringEvent?: RecurringEventInput; + disableGuests?: boolean; + hideCalendarNotes?: boolean; + hideCalendarEventDetails?: boolean; + minimumBookingNotice?: number; + beforeEventBuffer?: number; + afterEventBuffer?: number; + seatsPerTimeSlot?: number | null; + onlyShowFirstAvailableSlot?: boolean; + showOptimizedSlots?: boolean | null; + disableCancelling?: boolean | null; + disableRescheduling?: boolean | null; + minimumRescheduleNotice?: number | null; + seatsShowAttendees?: boolean | null; + seatsShowAvailabilityCount?: boolean | null; + scheduleId?: number | null; + allowReschedulingCancelledBookings?: boolean | null; + price?: number; + currency?: string; + slotInterval?: number | null; + metadata?: EventTypeMetadata; + successRedirectUrl?: string | null; + forwardParamsSuccessRedirect?: boolean | null; + redirectUrlOnNoRoutingFormResponse?: string | null; + bookingLimits?: IntervalLimit | null; + durationLimits?: IntervalLimit | null; + isInstantEvent?: boolean; + instantMeetingExpiryTimeOffsetInSeconds?: number; + instantMeetingScheduleId?: number | null; + instantMeetingParameters?: string[]; + assignAllTeamMembers?: boolean; + assignRRMembersUsingSegment?: boolean; + rrSegmentQueryValue?: RRSegmentQueryValueInput; + useEventTypeDestinationCalendarEmail?: boolean; + isRRWeightsEnabled?: boolean; + maxLeadThreshold?: number | null; + includeNoShowInRRCalculation?: boolean; + allowReschedulingPastBookings?: boolean; + hideOrganizerEmail?: boolean; + maxActiveBookingsPerBooker?: number | null; + maxActiveBookingPerBookerOfferReschedule?: boolean; + customReplyToEmail?: string | null; + eventTypeColor?: EventTypeColorInput; + rescheduleWithSameRoundRobinHost?: boolean; + secondaryEmailId?: number | null; + useBookerTimezone?: boolean; + restrictionScheduleId?: number | null; + bookingRequiresAuthentication?: boolean; + rrHostSubsetEnabled?: boolean; + createdAt?: Date | null; + updatedAt?: Date | null; + + // Extended fields (all optional due to .partial()) + aiPhoneCallConfig?: AiPhoneCallConfig; + calVideoSettings?: CalVideoSettings; + calAiPhoneScript?: string; + customInputs?: CustomInputSchema[]; + destinationCalendar?: DestinationCalendarInput; + users?: number[]; + children?: ChildInput[]; + hosts?: HostInput[]; + schedule?: number | null; + instantMeetingSchedule?: number | null; + multiplePrivateLinks?: (string | HashedLinkInput)[]; + hostGroups?: HostGroupInput[]; + enablePerHostLocations?: boolean; +}; + export type TabMap = { advanced: React.ReactNode; ai?: React.ReactNode; @@ -286,13 +506,13 @@ export interface EventTypePlatformWrapperRef { handleFormSubmit: (callbacks?: { onSuccess?: () => void; onError?: (error: Error) => void }) => void; } -export interface CalVideoSettings { - disableRecordingForOrganizer?: boolean; - disableRecordingForGuests?: boolean; - enableAutomaticTranscription?: boolean; - enableAutomaticRecordingForOrganizer?: boolean; - disableTranscriptionForGuests?: boolean; - disableTranscriptionForOrganizer?: boolean; - redirectUrlOnExit?: string; - requireEmailForGuests?: boolean; -} +export type CalVideoSettings = { + disableRecordingForGuests?: boolean | null; + disableRecordingForOrganizer?: boolean | null; + enableAutomaticTranscription?: boolean | null; + enableAutomaticRecordingForOrganizer?: boolean | null; + disableTranscriptionForGuests?: boolean | null; + disableTranscriptionForOrganizer?: boolean | null; + redirectUrlOnExit?: string | null; + requireEmailForGuests?: boolean | null; +} | null; diff --git a/packages/features/form-builder/index.ts b/packages/features/form-builder/index.ts deleted file mode 100644 index bcc791db6f..0000000000 --- a/packages/features/form-builder/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -// TODO: FormBuilder makes more sense in @calcom/ui but it has an additional thing that other components don't have -// It has zod schema associated with it and I currently can't import zod in there. -// Move it later there maybe? @sean -export { FormBuilderField } from "./FormBuilderField"; diff --git a/packages/features/pbac/client/context/PermissionProvider.tsx b/packages/features/pbac/client/context/PermissionProvider.tsx deleted file mode 100644 index d66a573aa3..0000000000 --- a/packages/features/pbac/client/context/PermissionProvider.tsx +++ /dev/null @@ -1,20 +0,0 @@ -export function PermissionProvider({ children }: { children: React.ReactNode }) { - // const { data: permissions, isLoading } = trpc.viewer.pbac.getUserPermissions.useQuery(undefined, { - // // Since permissions don't change often, we can cache them for a while - // staleTime: 5 * 60 * 1000, // 5 minutes - // }); - - // const setTeamPermissions = usePermissionStore((state) => state.setTeamPermissions); - - // useEffect(() => { - // if (permissions) { - // setTeamPermissions(permissions); - // } - // }, [permissions, setTeamPermissions]); - - // if (true) { - // return null; - // } - - return <>{children}; -} diff --git a/packages/features/schedules/components/ScheduleComponent.tsx b/packages/features/schedules/components/ScheduleComponent.tsx index e395709768..5c4d7631b7 100644 --- a/packages/features/schedules/components/ScheduleComponent.tsx +++ b/packages/features/schedules/components/ScheduleComponent.tsx @@ -18,7 +18,6 @@ import dayjs from "@calcom/dayjs"; import { defaultDayRange as DEFAULT_DAY_RANGE } from "@calcom/lib/availability"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { weekdayNames } from "@calcom/lib/weekday"; -import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery"; import type { TimeRange } from "@calcom/types/schedule"; import cn from "@calcom/ui/classNames"; import { Button } from "@calcom/ui/components/button"; diff --git a/packages/trpc/server/routers/viewer/eventTypes/types.ts b/packages/trpc/server/routers/viewer/eventTypes/types.ts index 2c93435502..2d4e9cd7cb 100644 --- a/packages/trpc/server/routers/viewer/eventTypes/types.ts +++ b/packages/trpc/server/routers/viewer/eventTypes/types.ts @@ -1,253 +1,27 @@ -import { z } from "zod"; - -import type { TemplateType } from "@calcom/features/calAIPhone/zod-utils"; import { templateTypeEnum } from "@calcom/features/calAIPhone/zod-utils"; -import { MAX_SEATS_PER_TIME_SLOT } from "@calcom/lib/constants"; -import type { PeriodType, SchedulingType } from "@calcom/prisma/enums"; import type { - CustomInputSchema, - EventTypeMetadata, - IntervalLimit, - EventTypeLocation, -} from "@calcom/prisma/zod-utils"; + AiPhoneCallConfig, + CalVideoSettings, + ChildInput, + DestinationCalendarInput, + EventTypeUpdateInput, + HashedLinkInput, + HostGroupInput, + HostInput, +} from "@calcom/features/eventtypes/lib/types"; +import { MAX_SEATS_PER_TIME_SLOT } from "@calcom/lib/constants"; import { customInputSchema, EventTypeMetaDataSchema, - rrSegmentQueryValueSchema, - eventTypeLocations, - recurringEventType, - intervalLimitsType, eventTypeBookingFields, eventTypeColor, + eventTypeLocations, + intervalLimitsType, + recurringEventType, + rrSegmentQueryValueSchema, } from "@calcom/prisma/zod-utils"; - -// ============================================================================ -// EXPLICIT TYPE DEFINITIONS -// ============================================================================ -// These explicit types prevent TypeScript from having to infer complex types -// through chains of .extend(), .partial(), .merge() etc. This significantly -// reduces type-checking time by giving TypeScript the answer directly. -// ============================================================================ - -type HashedLinkInput = { - link: string; - expiresAt?: Date | null; - maxUsageCount?: number | null; - usageCount?: number | null; -}; - -type AiPhoneCallConfig = { - generalPrompt: string; - enabled: boolean; - beginMessage: string | null; - yourPhoneNumber: string; - numberToCall: string; - guestName?: string | null; - guestEmail?: string | null; - guestCompany?: string | null; - templateType: TemplateType; -}; - -type CalVideoSettings = { - disableRecordingForGuests?: boolean | null; - disableRecordingForOrganizer?: boolean | null; - enableAutomaticTranscription?: boolean | null; - enableAutomaticRecordingForOrganizer?: boolean | null; - disableTranscriptionForGuests?: boolean | null; - disableTranscriptionForOrganizer?: boolean | null; - redirectUrlOnExit?: string | null; - requireEmailForGuests?: boolean | null; -} | null; - -type HostLocationInput = { - id?: string; - userId: number; - eventTypeId: number; - type: string; - credentialId?: number | null; - link?: string | null; - address?: string | null; - phoneNumber?: string | null; -}; - -type HostInput = { - userId: number; - profileId?: number | null; - isFixed?: boolean; - priority?: number | null; - weight?: number | null; - scheduleId?: number | null; - groupId?: string | null; - location?: HostLocationInput | null; -}; - -type HostGroupInput = { - id: string; - name: string; -}; - -type ChildInput = { - owner: { - id: number; - name: string; - email: string; - eventTypeSlugs: string[]; - }; - hidden: boolean; -}; - -type DestinationCalendarInput = { - integration: string; - externalId: string; -} | null; - -type RecurringEventInput = { - dtstart?: Date; - interval: number; - count: number; - freq: number; - until?: Date; - tzid?: string; -} | null; - -type EventTypeColorInput = { - lightEventTypeColor: string; - darkEventTypeColor: string; -} | null; - -/** - * Booking field type - minimal type definition for fields that need to be accessed. - * Only includes properties that are actually read in server code. - * Does NOT use an index signature to maintain compatibility with API v2 DTO classes. - */ -type BookingFieldInput = { - name: string; - hidden?: boolean; - required?: boolean; - type?: string; -}; - -/** - * RR Segment query value - using index signature for complex RAQB structure. - * The values need to be indexable (string keys) for downstream usage. - */ -type RRSegmentQueryValueInput = { - [key: string]: unknown; -} | null; - -/** - * Explicit type definition for event type update input. - * - * This type is defined explicitly rather than using z.infer<> on a complex - * schema chain to significantly reduce TypeScript type-checking time. - * The schema still validates all fields at runtime. - * - * All fields are optional (from .partial()) except `id` which is required. - */ -export type TUpdateInputSchema = { - // Required field - id: number; - - // Fields from EventTypeSchema (all optional due to .partial()) - periodType?: PeriodType; - schedulingType?: SchedulingType | null; - title?: string; - slug?: string; - description?: string | null; - interfaceLanguage?: string | null; - position?: number; - locations?: EventTypeLocation[] | null; - length?: number; - offsetStart?: number; - hidden?: boolean; - userId?: number | null; - profileId?: number | null; - teamId?: number | null; - useEventLevelSelectedCalendars?: boolean; - eventName?: string | null; - parentId?: number | null; - bookingFields?: BookingFieldInput[] | null; - timeZone?: string | null; - periodStartDate?: Date | null; - periodEndDate?: Date | null; - periodDays?: number | null; - periodCountCalendarDays?: boolean | null; - lockTimeZoneToggleOnBookingPage?: boolean; - lockedTimeZone?: string | null; - requiresConfirmation?: boolean; - requiresConfirmationWillBlockSlot?: boolean; - requiresConfirmationForFreeEmail?: boolean; - requiresBookerEmailVerification?: boolean; - canSendCalVideoTranscriptionEmails?: boolean; - autoTranslateDescriptionEnabled?: boolean; - autoTranslateInstantMeetingTitleEnabled?: boolean; - recurringEvent?: RecurringEventInput; - disableGuests?: boolean; - hideCalendarNotes?: boolean; - hideCalendarEventDetails?: boolean; - minimumBookingNotice?: number; - beforeEventBuffer?: number; - afterEventBuffer?: number; - seatsPerTimeSlot?: number | null; - onlyShowFirstAvailableSlot?: boolean; - showOptimizedSlots?: boolean | null; - disableCancelling?: boolean | null; - disableRescheduling?: boolean | null; - minimumRescheduleNotice?: number | null; - seatsShowAttendees?: boolean | null; - seatsShowAvailabilityCount?: boolean | null; - scheduleId?: number | null; - allowReschedulingCancelledBookings?: boolean | null; - price?: number; - currency?: string; - slotInterval?: number | null; - metadata?: EventTypeMetadata; - successRedirectUrl?: string | null; - forwardParamsSuccessRedirect?: boolean | null; - redirectUrlOnNoRoutingFormResponse?: string | null; - bookingLimits?: IntervalLimit | null; - durationLimits?: IntervalLimit | null; - isInstantEvent?: boolean; - instantMeetingExpiryTimeOffsetInSeconds?: number; - instantMeetingScheduleId?: number | null; - instantMeetingParameters?: string[]; - assignAllTeamMembers?: boolean; - assignRRMembersUsingSegment?: boolean; - rrSegmentQueryValue?: RRSegmentQueryValueInput; - useEventTypeDestinationCalendarEmail?: boolean; - isRRWeightsEnabled?: boolean; - maxLeadThreshold?: number | null; - includeNoShowInRRCalculation?: boolean; - allowReschedulingPastBookings?: boolean; - hideOrganizerEmail?: boolean; - maxActiveBookingsPerBooker?: number | null; - maxActiveBookingPerBookerOfferReschedule?: boolean; - customReplyToEmail?: string | null; - eventTypeColor?: EventTypeColorInput; - rescheduleWithSameRoundRobinHost?: boolean; - secondaryEmailId?: number | null; - useBookerTimezone?: boolean; - restrictionScheduleId?: number | null; - bookingRequiresAuthentication?: boolean; - rrHostSubsetEnabled?: boolean; - createdAt?: Date | null; - updatedAt?: Date | null; - - // Extended fields (all optional due to .partial()) - aiPhoneCallConfig?: AiPhoneCallConfig; - calVideoSettings?: CalVideoSettings; - calAiPhoneScript?: string; - customInputs?: CustomInputSchema[]; - destinationCalendar?: DestinationCalendarInput; - users?: number[]; - children?: ChildInput[]; - hosts?: HostInput[]; - schedule?: number | null; - instantMeetingSchedule?: number | null; - multiplePrivateLinks?: (string | HashedLinkInput)[]; - hostGroups?: HostGroupInput[]; - enablePerHostLocations?: boolean; -}; +import { z } from "zod"; +export type TUpdateInputSchema = EventTypeUpdateInput; // ============================================================================ // ZOD SCHEMAS