feat: add WiFi authorization module

- Backend: hotel_wifi_settings table (migration 046), CRUD routes
- Public API endpoint /api/wifi-auth/verify for captive portal
- Auth methods: room+lastname, room+birthdate, room+any, room_only
- Frontend: WiFiPage with settings, token management, setup guide
- Guide tabs: MikroTik, UniFi, Universal with copy-paste instructions
- Sidebar: WiFi item in Settings group

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-29 12:08:51 +03:00
parent 46524077a0
commit 0088457f51
7 changed files with 886 additions and 2 deletions

View File

@@ -581,6 +581,18 @@ export const api = {
testCheckin: (slug: string, roomId: string) =>
req<{ ok: boolean; message: string }>('POST', `/api/hotels/${slug}/netup/test-checkin`, { room_id: roomId }),
},
// ── WiFi Settings ─────────────────────────────────────────────────────────
wifi: {
get: (slug: string) =>
req<WifiSettings>('GET', `/api/hotels/${slug}/wifi-settings`),
update: (slug: string, data: Partial<Omit<WifiSettings, 'id' | 'hotelId' | 'apiToken'>>) =>
req<WifiSettings>('PATCH', `/api/hotels/${slug}/wifi-settings`, data),
regenerateToken: (slug: string) =>
req<{ apiToken: string }>('POST', `/api/hotels/${slug}/wifi-settings/regenerate-token`),
},
}
// ── Schedule ─────────────────────────────────────────────────────────────────
@@ -1029,6 +1041,17 @@ export interface Workstation {
devices: WorkstationDevice[] | null
}
export interface WifiSettings {
id: string
hotelId: string
enabled: boolean
apiToken: string
authMethod: 'room_lastname' | 'room_birthdate' | 'room_any' | 'room_only'
ssidName: string | null
welcomeText: string | null
sessionHours: number
}
function toHotelPayload(h: HotelPayload): Record<string, unknown> {
const out: Record<string, unknown> = {}
if (h.name !== undefined) out.name = h.name