import React, { useState } from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { toast } from 'sonner'; import { TrashIcon } from '@heroicons/react/24/outline'; import PersianDateInput from '../ui/PersianDateInput'; import { api, ApiError, type ApiResponse } from '../../lib/api'; import { formatDate, isoToUnix, unixToIso } from '../../lib/utils'; interface Block { uuid: string; starts_at: number; ends_at: number; segment_name: string | null; } const HOUR = 3600; /** * غیرفعال‌سازی موقتِ یک منبع — بستن یک بازهٔ زمانی مشخص. * * عمداً از «استثنای تقویم» جداست و همین‌جا هم گفته می‌شود: آن الگوی کاری منبع را عوض * می‌کند و ماندگار است، این فقط یک بازهٔ مشخص را می‌بندد. اپراتوری که این تفاوت را * نداند، تعطیلی یک بعدازظهر را برای همیشه در تقویم ثبت می‌کند. * * پیش‌تر مودالی بود که از ردیف جدولِ منابع باز می‌شد؛ حالا یکی از تب‌های خودِ منبع * است، کنار بقیهٔ تنظیماتش. */ export default function ResourceBlocksPanel({ resourceUuid, canUpdate }: { resourceUuid?: string; canUpdate: boolean; }) { const qc = useQueryClient(); const key = ['resource-blocks', resourceUuid]; const [day, setDay] = useState(() => unixToIso(Math.floor(Date.now() / 1000) + 86400)); const [fromHour, setFromHour] = useState(9); const [toHour, setToHour] = useState(13); const [reason, setReason] = useState(''); const { data, isLoading } = useQuery({ queryKey: key, queryFn: () => api.get>(`/api/v1/resource/${resourceUuid}/blocks`), enabled: !!resourceUuid, }); const blocks = data?.data ?? []; const create = useMutation({ mutationFn: (body: { starts_at: number; ends_at: number; reason: string }) => api.post>(`/api/v1/resource/${resourceUuid}/blocks`, body), onSuccess: () => { toast.success('بازه بسته شد'); qc.invalidateQueries({ queryKey: key }); setReason(''); }, // ۴۰۹ یعنی آن بازه نوبت دارد؛ پیام سرور دقیقاً می‌گوید اول چه باید کرد. onError: (e) => toast.error(e instanceof ApiError ? e.message : 'بستن بازه ناموفق بود'), }); const remove = useMutation({ mutationFn: (uuid: string) => api.delete>(`/api/v1/resource-block/${uuid}`), onSuccess: () => { toast.success('بازه دوباره باز شد'); qc.invalidateQueries({ queryKey: key }); }, onError: (e) => toast.error(e instanceof ApiError ? e.message : 'حذف ناموفق بود'), }); const dayStart = isoToUnix(day) ?? 0; const rangeInvalid = toHour <= fromHour; return (

غیرفعال‌سازی موقت

یک بازهٔ مشخص را می‌بندد و تا وقتی حذفش نکنید می‌ماند. برای تغییر الگوی کاری منبع (مثلاً «پنجشنبه‌ها تعطیل») از تب «تعطیلات و استثنا» استفاده کنید، نه از اینجا.

{canUpdate && (
{rangeInvalid && (

ساعت پایان باید بعد از ساعت شروع باشد.

)}
)}

بازه‌های بسته‌شده

{isLoading ? (
) : blocks.length === 0 ? (

این منبع هیچ بازهٔ بسته‌شده‌ای ندارد.

) : (
{blocks.map((block) => (
{formatDate(block.starts_at)} {new Date(block.starts_at * 1000).toLocaleTimeString('fa-IR', { hour: '2-digit', minute: '2-digit' })} {' – '} {new Date(block.ends_at * 1000).toLocaleTimeString('fa-IR', { hour: '2-digit', minute: '2-digit' })} {block.segment_name ?? '—'} {canUpdate && ( )}
))}
)}
); }