Add Guests module: API integration + passport identification
- Migration 009: add passport_series, passport_number, rating to guests table - Backend route /api/hotels/:slug/guests: list, get (with history), create/upsert by passport, update, delete - Frontend GuestsPage: loads from API, passport tab in modal, add guest form, search by passport - api.ts: add guests API methods and GuestApiType Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -266,6 +266,24 @@ export const api = {
|
||||
req<Hotel>('PATCH', `/api/hotels/${slug}`, toHotelPayload(data)),
|
||||
},
|
||||
|
||||
// ── Guests ────────────────────────────────────────────────────────────────
|
||||
guests: {
|
||||
list: (slug: string, q?: string) =>
|
||||
req<GuestApiType[]>('GET', `/api/hotels/${slug}/guests${q ? `?q=${encodeURIComponent(q)}` : ''}`),
|
||||
|
||||
get: (slug: string, id: string) =>
|
||||
req<GuestApiType>('GET', `/api/hotels/${slug}/guests/${id}`),
|
||||
|
||||
create: (slug: string, data: GuestPayload) =>
|
||||
req<GuestApiType>('POST', `/api/hotels/${slug}/guests`, data),
|
||||
|
||||
update: (slug: string, id: string, data: Partial<GuestPayload>) =>
|
||||
req<GuestApiType>('PATCH', `/api/hotels/${slug}/guests/${id}`, data),
|
||||
|
||||
delete: (slug: string, id: string) =>
|
||||
req<void>('DELETE', `/api/hotels/${slug}/guests/${id}`),
|
||||
},
|
||||
|
||||
// ── NetUP IPTV ────────────────────────────────────────────────────────────
|
||||
netup: {
|
||||
getSettings: (slug: string) =>
|
||||
@@ -373,6 +391,59 @@ export interface HotelPayload {
|
||||
checkInTime?: string; checkOutTime?: string
|
||||
}
|
||||
|
||||
export interface GuestApiType {
|
||||
id: string
|
||||
hotelId: string
|
||||
firstName: string
|
||||
lastName: string
|
||||
email: string | null
|
||||
phone: string | null
|
||||
passport: string | null
|
||||
passportSeries: string | null
|
||||
passportNumber: string | null
|
||||
birthDate: string | null
|
||||
nationality: string | null
|
||||
gender: string | null
|
||||
city: string | null
|
||||
notes: string
|
||||
tags: string[]
|
||||
loyaltyTier: string
|
||||
loyaltyPoints: number
|
||||
rating: number
|
||||
totalStays: number
|
||||
totalSpent: number
|
||||
lastVisit: string | null
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
history?: {
|
||||
id: string
|
||||
checkIn: string
|
||||
checkOut: string
|
||||
status: string
|
||||
totalAmount: number | null
|
||||
paidAmount: number
|
||||
roomNumber: string | null
|
||||
roomType: string | null
|
||||
}[]
|
||||
}
|
||||
|
||||
export interface GuestPayload {
|
||||
first_name?: string
|
||||
last_name?: string
|
||||
email?: string
|
||||
phone?: string
|
||||
passport?: string
|
||||
passport_series?: string
|
||||
passport_number?: string
|
||||
birth_date?: string
|
||||
nationality?: string
|
||||
gender?: string
|
||||
city?: string
|
||||
notes?: string
|
||||
tags?: string[]
|
||||
rating?: number
|
||||
}
|
||||
|
||||
function toHotelPayload(h: HotelPayload): Record<string, unknown> {
|
||||
const out: Record<string, unknown> = {}
|
||||
if (h.name !== undefined) out.name = h.name
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user