diff --git a/assets/admin/components/holidays/NationalHolidaysCard.test.tsx b/assets/admin/components/holidays/NationalHolidaysCard.test.tsx
new file mode 100644
index 00000000..58190f69
--- /dev/null
+++ b/assets/admin/components/holidays/NationalHolidaysCard.test.tsx
@@ -0,0 +1,71 @@
+import { describe, it, expect, vi, beforeEach } from 'vitest';
+import { screen, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import { renderWithProviders } from '../../test/utils';
+
+vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }));
+
+const setOverride = { mutate: vi.fn(), isPending: false };
+const removeOverride = { mutate: vi.fn(), isPending: false };
+
+let holidays: Array<{ uuid: string; date: number; title: string }> = [];
+let overrides: Array<{ uuid: string; date: number; is_working: boolean }> = [];
+
+vi.mock('../../hooks/useResourceCalendar', () => ({
+ useHolidays: () => ({ holidays, overrides, loading: false, setOverride, removeOverride }),
+}));
+
+import NationalHolidaysCard from './NationalHolidaysCard';
+
+const NOWRUZ = { uuid: 'h-1', date: 1774040400, title: 'نوروز' };
+
+describe('NationalHolidaysCard', () => {
+ beforeEach(() => {
+ holidays = [NOWRUZ];
+ overrides = [];
+ vi.clearAllMocks();
+ });
+
+ it('تعطیلات رسمی سال را نشان میدهد', () => {
+ renderWithProviders();
+
+ expect(screen.getByText(/نوروز/)).toBeInTheDocument();
+ expect(screen.getByText('تعطیل')).toBeInTheDocument();
+ });
+
+ /** محیطی که آن روز کار میکند، تعطیلیِ سراسری را برای خودش خنثی میکند. */
+ it('با یک کلیک روز را برای این محیط باز میکند', async () => {
+ const user = userEvent.setup();
+ renderWithProviders();
+
+ await user.click(screen.getByRole('button', { name: 'این روز باز است' }));
+
+ expect(setOverride.mutate).toHaveBeenCalledWith({ date: NOWRUZ.date, is_working: true });
+ });
+
+ it('روزی که استثنا خورده، «باز» است و میشود دوباره تعطیلش کرد', async () => {
+ overrides = [{ uuid: 'o-1', date: NOWRUZ.date, is_working: true }];
+ const user = userEvent.setup();
+ renderWithProviders();
+
+ expect(screen.getByText('باز')).toBeInTheDocument();
+ await user.click(screen.getByRole('button', { name: 'تعطیل کن' }));
+
+ expect(removeOverride.mutate).toHaveBeenCalledWith('o-1');
+ });
+
+ /** ساخت و حذفِ خودِ تعطیلی کارِ مدیر سیستم است؛ اینجا فقط استثنا زده میشود. */
+ it('بدون مجوز ویرایش، هیچ دکمهای نمیدهد', () => {
+ renderWithProviders();
+
+ expect(screen.queryByRole('button')).not.toBeInTheDocument();
+ expect(screen.getByText('تنظیمات ← تعطیلات رسمی')).toHaveAttribute('href', '/admin/holidays');
+ });
+
+ it('سالِ بدون تعطیلی را صریح میگوید', async () => {
+ holidays = [];
+ renderWithProviders();
+
+ await waitFor(() => expect(screen.getByText(/تعطیلی رسمی ثبت نشده است/)).toBeInTheDocument());
+ });
+});
diff --git a/assets/admin/components/holidays/NationalHolidaysCard.tsx b/assets/admin/components/holidays/NationalHolidaysCard.tsx
new file mode 100644
index 00000000..7574d861
--- /dev/null
+++ b/assets/admin/components/holidays/NationalHolidaysCard.tsx
@@ -0,0 +1,84 @@
+import React, { useMemo } from 'react';
+import { Link } from 'react-router-dom';
+import { useHolidays } from '../../hooks/useResourceCalendar';
+import { formatDate, currentJalaliYear } from '../../lib/utils';
+
+/**
+ * تعطیلات رسمیِ سال، همانجایی که تعطیلی اختصاصی تعریف میشود.
+ *
+ * تقویم رسمی یک بار مرکزی ثبت میشود و هر پزشک و هر منبع از آن ارث میبرد؛ اینجا فقط
+ * دیده میشود و — اگر این محیط آن روز باز باشد — با یک سوییچ خنثی میشود. ساخت و حذفِ
+ * خودِ تعطیلی کارِ مدیر سیستم است، نه کلینیک.
+ *
+ * یک کامپوننت برای دو مصرفکننده: تب تعطیلات پزشک و تب تعطیلات منبع. دو نسخه یعنی دو
+ * رفتار که با هم واگرا میشوند.
+ */
+export default function NationalHolidaysCard({ canUpdate, year = currentJalaliYear() }: {
+ canUpdate: boolean;
+ year?: number;
+}) {
+ const { holidays, overrides, loading, setOverride, removeOverride } = useHolidays(year);
+
+ const overrideByDate = useMemo(
+ () => new Map(overrides.map((o) => [o.date, o])),
+ [overrides],
+ );
+
+ return (
+
+
تعطیلات رسمی {year}
+
+ اینها برای همهٔ پزشکان و منابع اعمال میشوند. اگر این محیط روزی را باز است،
+ همینجا استثنا بزنید — مدیریت کاملشان در{' '}
+ تنظیمات ← تعطیلات رسمی.
+
+
+ {loading ? (
+ در حال بارگذاری...
+ ) : holidays.length === 0 ? (
+