@@ -475,7 +475,7 @@ const RoundRobinHosts = ({
@@ -830,7 +830,7 @@ export const EventTeamAssignmentTab = ({
{t("assignment_description")}
@@ -865,7 +865,7 @@ export const EventTeamAssignmentTab = ({
-
+
{t("rr_distribution_method_description")}
diff --git a/packages/features/settings/outOfOffice/CreateOrEditOutOfOfficeModal.tsx b/packages/features/settings/outOfOffice/CreateOrEditOutOfOfficeModal.tsx
index 2f13c9226c..2e63292860 100644
--- a/packages/features/settings/outOfOffice/CreateOrEditOutOfOfficeModal.tsx
+++ b/packages/features/settings/outOfOffice/CreateOrEditOutOfOfficeModal.tsx
@@ -1,4 +1,4 @@
-import { useState } from "react";
+import { useMemo, useState } from "react";
import { Controller, useForm } from "react-hook-form";
import dayjs from "@calcom/dayjs";
@@ -11,6 +11,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery";
import classNames from "@calcom/ui/classNames";
+import { Alert } from "@calcom/ui/components/alert";
import { UpgradeTeamsBadge } from "@calcom/ui/components/badge";
import { Button } from "@calcom/ui/components/button";
import { DialogContent, DialogFooter, DialogHeader } from "@calcom/ui/components/dialog";
@@ -162,9 +163,28 @@ export const CreateOrEditOutOfOfficeEntryModal = ({
const watchedTeamUserId = watch("toTeamUserId");
const watchForUserId = watch("forUserId");
+ const watchedDateRange = watch("dateRange");
const watchedNotes = watch("notes");
const hasValidNotes = Boolean(watchedNotes?.trim());
+ // Fetch user's holiday settings to show warning if OOO dates overlap with holidays
+ const { data: holidaySettings } = trpc.viewer.holidays.getUserSettings.useQuery({});
+
+ // Check if selected dates overlap with any enabled holidays
+ const overlappingHolidays = useMemo(() => {
+ if (!holidaySettings?.countryCode || !watchedDateRange?.startDate || !watchedDateRange?.endDate) {
+ return [];
+ }
+
+ // Filter holidays that are enabled and fall within the date range
+ const startStr = dayjs(watchedDateRange.startDate).format("YYYY-MM-DD");
+ const endStr = dayjs(watchedDateRange.endDate).format("YYYY-MM-DD");
+
+ return (holidaySettings.holidays || [])
+ .filter((h) => h.enabled && h.date >= startStr && h.date <= endStr)
+ .map((h) => ({ date: h.date, holiday: { id: h.id, name: h.name } }));
+ }, [holidaySettings, watchedDateRange]);
+
const createOrEditOutOfOfficeEntry = trpc.viewer.ooo.outOfOfficeCreateOrUpdate.useMutation({
onSuccess: () => {
showToast(
@@ -310,6 +330,29 @@ export const CreateOrEditOutOfOfficeEntryModal = ({
)}
/>
+
+ {/* Holiday overlap warning */}
+ {overlappingHolidays.length > 0 && (
+
h.holiday.name)
+ .join(", "),
+ })
+ }
+ />
+ )}
{/* Reason Select */}
diff --git a/packages/features/settings/outOfOffice/HolidaysView.tsx b/packages/features/settings/outOfOffice/HolidaysView.tsx
new file mode 100644
index 0000000000..026affbab6
--- /dev/null
+++ b/packages/features/settings/outOfOffice/HolidaysView.tsx
@@ -0,0 +1,312 @@
+"use client";
+
+import { memo, useMemo, useCallback } from "react";
+
+import dayjs from "@calcom/dayjs";
+import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
+import type { RouterOutputs } from "@calcom/trpc/react";
+import { trpc } from "@calcom/trpc/react";
+import { Alert } from "@calcom/ui/components/alert";
+import { Button } from "@calcom/ui/components/button";
+import { EmptyScreen } from "@calcom/ui/components/empty-screen";
+import { Label, Select } from "@calcom/ui/components/form";
+import { Switch } from "@calcom/ui/components/form";
+import { SkeletonContainer, SkeletonText } from "@calcom/ui/components/skeleton";
+import { showToast } from "@calcom/ui/components/toast";
+
+import { OutOfOfficeToggleGroup } from "./OutOfOfficeToggleGroup";
+
+function HolidaysCTA() {
+ const { t } = useLocale();
+ return (
+
+
+
+
+ );
+}
+
+type HolidayWithStatus = RouterOutputs["viewer"]["holidays"]["getUserSettings"]["holidays"][number];
+type Country = { code: string; name: string };
+
+const CountrySelector = memo(function CountrySelector({
+ countries,
+ value,
+ onChange,
+ isLoading,
+}: {
+ countries: Country[];
+ value: string;
+ onChange: (value: string) => void;
+ isLoading: boolean;
+}) {
+ const { t } = useLocale();
+
+ const options = useMemo(
+ () => [
+ { value: "", label: t("no_holidays") },
+ ...countries.map((country) => ({
+ value: country.code,
+ label: country.name,
+ })),
+ ],
+ [countries, t]
+ );
+
+ const selectedOption = useMemo(() => {
+ if (!value) return { value: "", label: t("select_country") };
+ const country = countries.find((c) => c.code === value);
+ return { value, label: country?.name || value };
+ }, [value, countries, t]);
+
+ if (isLoading) {
+ return ;
+ }
+
+ return (
+