import { useState } from 'react' import { CheckCircle2, Clock, Sparkles, User, ListChecks, Settings2, Save, Wrench, X as XIcon, Send } from 'lucide-react' import { MOCK_HK_TASKS } from '../data/mockData' import type { HousekeepingTask } from '../types' import { cn } from '../lib/utils' import { Badge } from '../components/ui/Badge' function Toggle({ on, onChange }: { on: boolean; onChange: () => void }) { return ( ) } type Column = 'pending' | 'in_progress' | 'done' const COLUMNS: { id: Column; label: string; icon: React.ElementType; color: string }[] = [ { id: 'pending', label: 'Ожидают', icon: Clock, color: 'text-amber-600 dark:text-amber-400' }, { id: 'in_progress', label: 'В процессе', icon: Sparkles, color: 'text-blue-600 dark:text-blue-400' }, { id: 'done', label: 'Готово', icon: CheckCircle2, color: 'text-emerald-600 dark:text-emerald-400' }, ] const PRIORITY_COLORS = { high: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-300', normal: 'bg-slate-100 text-slate-700 dark:bg-slate-700 dark:text-slate-300', low: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300', } const PRIORITY_LABELS = { high: 'Срочно', normal: 'Обычный', low: 'Низкий' } const TYPE_COLORS = { cleaning: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300', inspection: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-300', maintenance: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300', } const TYPE_LABELS = { cleaning: 'Уборка', inspection: 'Проверка', maintenance: 'Ремонт', } export function HousekeepingPage() { const [tasks, setTasks] = useState(MOCK_HK_TASKS) const [activeTab, setActiveTab] = useState<'tasks' | 'plans'>('tasks') const [planSaved, setPlanSaved] = useState(false) // Cleaning plan settings const [plans, setPlans] = useState({ checkoutAuto: true, checkoutPriority: 'high' as 'high' | 'normal', checkoutInspection: true, dailyEnabled: true, dailyIntervalDays: 1, dailyStartFromDay: 1, onDemandEnabled: true, onDemandPriority: 'normal' as 'high' | 'normal' | 'low', deepCleanEnabled: false, deepCleanEveryDays: 7, inspectionAfterClean: true, autoAssign: false, }) const setP = (k: K, v: typeof plans[K]) => setPlans(prev => ({ ...prev, [k]: v })) const savePlans = () => { setPlanSaved(true) setTimeout(() => setPlanSaved(false), 2000) } const updateStatus = (id: string, status: HousekeepingTask['status']) => { setTasks(prev => prev.map(t => t.id === id ? { ...t, status, completedAt: status === 'done' ? new Date().toISOString() : undefined } : t, )) } const addMaintenanceNote = (id: string, note: string) => { setTasks(prev => prev.map(t => t.id === id ? { ...t, maintenanceNote: note } : t)) } const total = tasks.length const done = tasks.filter(t => t.status === 'done').length return (
{/* Header */}

Уборка и обслуживание

{activeTab === 'tasks' && (
{done} / {total} завершено
)}
{/* Tabs */}
{([ { id: 'tasks' as const, label: 'Задачи на сегодня', icon: ListChecks }, { id: 'plans' as const, label: 'Планы уборки', icon: Settings2 }, ]).map(t => ( ))}
{/* ── Tasks tab ── */} {activeTab === 'tasks' && (
{COLUMNS.map(col => { const colTasks = tasks.filter(t => t.status === col.id) const Icon = col.icon return (

{col.label}

{colTasks.length}
{colTasks.map(task => ( ))} {colTasks.length === 0 && (

Пусто

)}
) })}
)} {/* ── Plans tab ── */} {activeTab === 'plans' && (
{/* Checkout cleaning */}

Уборка при выезде

Автоматически создавать задачу на уборку, как только гость освобождает номер

setP('checkoutAuto', !plans.checkoutAuto)} />
{plans.checkoutAuto && (
{([['high', 'Срочно'], ['normal', 'Обычный']] as const).map(([v, l]) => ( ))}

Инспекция после уборки

Создавать задачу проверки для старшей горничной

setP('checkoutInspection', !plans.checkoutInspection)} />
)}
{/* Daily cleaning */}

Ежедневная уборка

Регулярная уборка в номерах с проживающими гостями

setP('dailyEnabled', !plans.dailyEnabled)} />
{plans.dailyEnabled && (
{[1, 2, 3, 7].map(n => ( ))}
setP('dailyStartFromDay', Math.max(1, parseInt(e.target.value) || 1))} />

Уборка начнётся на {plans.dailyStartFromDay}-й день проживания

)}
{/* On-demand cleaning */}

Уборка по запросу гостя

Гость может запросить уборку через QR-код или мобильное приложение

setP('onDemandEnabled', !plans.onDemandEnabled)} />
{plans.onDemandEnabled && (
{([['high', 'Срочно'], ['normal', 'Обычный'], ['low', 'Низкий']] as const).map(([v, l]) => ( ))}
)}
{/* Deep cleaning */}

Генеральная уборка

Глубокая уборка с чисткой мебели, мытьём окон и полной сменой постельного белья

setP('deepCleanEnabled', !plans.deepCleanEnabled)} />
{plans.deepCleanEnabled && (
setP('deepCleanEveryDays', Math.max(1, parseInt(e.target.value) || 7))} /> дней
)}
{/* Inspection after cleaning */}

Проверка после уборки

После завершения любой уборки создавать задачу инспекции для старшей горничной

setP('inspectionAfterClean', !plans.inspectionAfterClean)} />
{/* Auto assign */}

Автоназначение горничной

Автоматически назначать ответственную горничную по расписанию смен (без этой опции — задачи назначаются вручную)

setP('autoAssign', !plans.autoAssign)} />
)}
) } function TaskCard({ task, onStatusChange, onMaintenanceNote }: { task: HousekeepingTask onStatusChange: (id: string, status: HousekeepingTask['status']) => void onMaintenanceNote: (id: string, note: string) => void }) { const [reportOpen, setReportOpen] = useState(false) const [reportText, setReportText] = useState('') const submitReport = () => { if (!reportText.trim()) return onMaintenanceNote(task.id, reportText.trim()) setReportText('') setReportOpen(false) } return (
№{task.roomNumber} {PRIORITY_LABELS[task.priority]}
{TYPE_LABELS[task.type]}
{task.notes && (

{task.notes}

)} {task.maintenanceNote && (

{task.maintenanceNote}

)} {task.assignedToName && (
{task.assignedToName}
)} {task.completedAt && (

Завершено в {new Date(task.completedAt).toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' })}

)} {/* Maintenance report form */} {reportOpen && (

Сообщить о поломке