feat: photos for tech tasks, 3 priorities, remove cleaning status from context menu

- Remove 'Убирается' (cleaning) from manually selectable HK statuses in calendar context menu — it now only shows automatically when a task is in_progress
- Reduce priorities from 4 to 3: remove 'high', keep urgent/medium/low across context menu, tech tasks modal, and HousekeepingTask type
- Add photo upload to technical tasks: upload via camera button per task, display thumbnails with hover-to-remove, stored as TEXT[] in DB (migration 026)
- Fix HousekeepingPage WS handler to filter by category — no longer adds maintenance tasks to housekeeping board
- Add 'tasks' folder support to upload route

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-24 10:38:51 +03:00
parent 4b337a3b85
commit e51d776b3a
10 changed files with 155 additions and 73 deletions

View File

@@ -7,7 +7,7 @@ import { cn } from '../../lib/utils'
const today = () => format(new Date(), 'yyyy-MM-dd')
export type HkPriority = 'urgent' | 'high' | 'medium' | 'low'
export type HkPriority = 'urgent' | 'medium' | 'low'
interface RoomContextMenuProps {
room: Room
@@ -21,15 +21,13 @@ interface RoomContextMenuProps {
}
const HK_ITEMS: { status: HousekeepingStatus; label: string; icon: React.ReactNode; color: string }[] = [
{ status: 'clean', label: 'Чисто', icon: <Sparkles size={14} />, color: 'text-emerald-600 dark:text-emerald-400' },
{ status: 'inspect', label: 'Проверить', icon: <ClipboardList size={14} />, color: 'text-amber-600 dark:text-amber-400' },
{ status: 'cleaning', label: 'Убирается', icon: <ClipboardList size={14} />, color: 'text-blue-500 dark:text-blue-400' },
{ status: 'dirty', label: 'Убрать', icon: <ClipboardList size={14} />, color: 'text-red-500 dark:text-red-400' },
{ status: 'clean', label: 'Чисто', icon: <Sparkles size={14} />, color: 'text-emerald-600 dark:text-emerald-400' },
{ status: 'inspect', label: 'Проверить', icon: <ClipboardList size={14} />, color: 'text-amber-600 dark:text-amber-400' },
{ status: 'dirty', label: 'Убрать', icon: <ClipboardList size={14} />, color: 'text-red-500 dark:text-red-400' },
]
const PRIORITY_ITEMS: { value: HkPriority; label: string; color: string }[] = [
{ value: 'urgent', label: 'Срочно', color: 'text-red-600 dark:text-red-400' },
{ value: 'high', label: 'Высокий', color: 'text-orange-600 dark:text-orange-400' },
{ value: 'medium', label: 'Средний', color: 'text-yellow-600 dark:text-yellow-400' },
{ value: 'low', label: 'Низкий', color: 'text-slate-500 dark:text-slate-400' },
]
@@ -83,7 +81,7 @@ export function RoomContextMenu({ room, x, y, onClose, onStatusChange, onHkStatu
}
const handleHkClick = (status: HousekeepingStatus) => {
if (status === 'dirty' || status === 'cleaning') {
if (status === 'dirty') {
// Show priority sub-form
setPendingHkStatus(status)
setSubForm('hk_priority')
@@ -234,7 +232,7 @@ export function RoomContextMenu({ room, x, y, onClose, onStatusChange, onHkStatu
{item.icon}
{item.label}
{room.housekeepingStatus === item.status && <span className="ml-auto text-[10px] text-slate-400"></span>}
{(item.status === 'dirty' || item.status === 'cleaning') && <ChevronRight size={12} className="ml-auto text-slate-400 opacity-50" />}
{item.status === 'dirty' && <ChevronRight size={12} className="ml-auto text-slate-400 opacity-50" />}
</button>
))
)}