feat: TTLockPage — import locks from TTHotel XLS file

- Parse .xls/.xlsx via SheetJS (xlsx package)
- Auto-match Door Name → room number; unmatched rows kept with empty room
- Preview table: green=matched, amber=unmatched, grey=already mapped
- Per-row room dropdown for manual correction before import
- room_id nullable in room_lock_mappings (migration 052)
- Conflict key changed from (hotel_id, room_id) to (hotel_id, lock_mac)
- LEFT JOIN in GET room-locks to show unmatched locks
- DELETE by UUID or MAC depending on whether room is assigned

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-01 23:08:24 +03:00
parent ea63dec525
commit 1ec3664886
4 changed files with 243 additions and 18 deletions

View File

@@ -622,7 +622,7 @@ export const api = {
getRoomLocks: (slug: string) =>
req<RoomLockMapping[]>('GET', `/api/hotels/${slug}/ttlock/room-locks`),
mapRoom: (slug: string, data: { roomId: string; lockMac: string; lockName?: string }) =>
mapRoom: (slug: string, data: { roomId?: string; lockMac: string; lockName?: string }) =>
req<{ ok: boolean }>('POST', `/api/hotels/${slug}/ttlock/room-locks`, data),
unmapRoom: (slug: string, roomId: string) =>