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 Modal from './ui/Modal'; 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; } interface Props { resourceUuid: string | null; resourceName: string; onClose: () => void; } const HOUR = 3600; /** * مسدودسازی موردی یک منبع. * * عمداً از «استثنای تقویم» جداست و همین‌جا هم گفته می‌شود: آن الگوی کاری منبع را عوض * می‌کند و ماندگار است، این فقط یک بازهٔ مشخص را می‌بندد. اپراتوری که این تفاوت را * نداند، تعطیلی یک بعدازظهر را برای همیشه در تقویم ثبت می‌کند. */ export default function ResourceBlocksModal({ resourceUuid, resourceName, onClose }: Props) { 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 ( بستن } >

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

setReason(e.target.value)} placeholder="مثلاً: سرویس دوره‌ای دستگاه" />
{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 ?? '—'}
)) )}
); }