feat: add category field to housekeeping tasks + TechnicalPage for maintenance tasks
- Add migration 025 to add `category` column (housekeeping/maintenance) to housekeeping_tasks - Backend: filter by ?category= in GET, store category in POST, allow patching category - API client: HkPayload + housekeeping.list() now support category param - HousekeepingPage: filters by category=housekeeping so maintenance tasks don't appear - RoomContextMenu: priority sub-form for dirty/cleaning status, tech task creation inline form - BookingCalendar: accepts onMaintenanceTaskCreate prop, passes priority to onRoomUpdate - CalendarPage: handleRoomUpdate creates task for dirty+cleaning (with priority), new handleMaintenanceTaskCreate for category=maintenance tasks - TechnicalPage: new page for viewing/creating/updating maintenance tasks - App.tsx: /technical route added - Sidebar: Тех. задачи nav item added under Управление Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import type { RentalObjectApi, RentalBookingApi } from '../lib/api'
|
||||
import { useHotelSocket } from '../hooks/useHotelSocket'
|
||||
import type { WsMessage } from '../hooks/useHotelSocket'
|
||||
import type { Room, Booking } from '../types'
|
||||
import type { HkPriority } from '../components/rooms/RoomContextMenu'
|
||||
import type { RentalBooking } from '../data/rentalData'
|
||||
|
||||
export type BookingLock = { checkIn: string; checkOut: string; lockedBy: string }
|
||||
@@ -153,18 +154,18 @@ export function CalendarPage() {
|
||||
send({ type: 'unlock', roomId })
|
||||
}, [send])
|
||||
|
||||
const handleRoomUpdate = useCallback(async (roomId: string, patch: Partial<Room>) => {
|
||||
const handleRoomUpdate = useCallback(async (roomId: string, patch: Partial<Room>, priority?: HkPriority) => {
|
||||
try {
|
||||
const updated = await api.rooms.update(slug, roomId, patch)
|
||||
setRooms(prev => prev.map(r => r.id === updated.id ? updated : r))
|
||||
// When manually marking room as dirty → auto-create a housekeeping task
|
||||
if (patch.housekeepingStatus === 'dirty') {
|
||||
if (patch.housekeepingStatus === 'dirty' || patch.housekeepingStatus === 'cleaning') {
|
||||
const today = new Date().toISOString().slice(0, 10)
|
||||
const task = await api.housekeeping.create(slug, {
|
||||
room_id: roomId,
|
||||
type: 'regular',
|
||||
priority: 'medium',
|
||||
priority: priority ?? 'medium',
|
||||
due_date: today,
|
||||
category: 'housekeeping',
|
||||
})
|
||||
send({ type: 'housekeeping_task_created', task: task as unknown as Record<string, unknown> })
|
||||
}
|
||||
@@ -173,6 +174,23 @@ export function CalendarPage() {
|
||||
}
|
||||
}, [slug, send])
|
||||
|
||||
const handleMaintenanceTaskCreate = useCallback(async (roomId: string, description: string, priority: HkPriority) => {
|
||||
try {
|
||||
const today = new Date().toISOString().slice(0, 10)
|
||||
const task = await api.housekeeping.create(slug, {
|
||||
room_id: roomId,
|
||||
type: 'maintenance',
|
||||
priority,
|
||||
notes: description,
|
||||
due_date: today,
|
||||
category: 'maintenance',
|
||||
})
|
||||
send({ type: 'housekeeping_task_created', task: task as unknown as Record<string, unknown> })
|
||||
} catch (err) {
|
||||
console.error('Failed to create maintenance task:', err)
|
||||
}
|
||||
}, [slug, send])
|
||||
|
||||
const handleRentalBookingCreate = useCallback(async (b: RentalBooking) => {
|
||||
try {
|
||||
const created = await api.rental.createBooking(slug, {
|
||||
@@ -208,6 +226,7 @@ export function CalendarPage() {
|
||||
onBookingUpdate={handleUpdate}
|
||||
onBookingBulkUpdate={handleBulkUpdate}
|
||||
onRoomUpdate={handleRoomUpdate}
|
||||
onMaintenanceTaskCreate={handleMaintenanceTaskCreate}
|
||||
fadingBookingIds={fadingBookings}
|
||||
rentalObjects={isRentalActive ? rentalObjects as unknown as import('../data/rentalData').RentalObject[] : undefined}
|
||||
rentalBookings={isRentalActive ? rentalBookings as unknown as RentalBooking[] : undefined}
|
||||
|
||||
Reference in New Issue
Block a user