feat: wire up loyalty + chat — register routes, API types, connect LoyaltyPage, add ChatWidget to layout

This commit is contained in:
2026-03-26 10:15:29 +03:00
parent 8ede920e5d
commit 113971f854
9 changed files with 964 additions and 63 deletions

View File

@@ -287,6 +287,34 @@ export const api = {
req<void>('DELETE', `/api/hotels/${slug}/schedule/${userId}/${date}`),
},
// ── Loyalty ───────────────────────────────────────────────────────────────
loyalty: {
getSettings: (slug: string) =>
req<LoyaltySettings>('GET', `/api/hotels/${slug}/loyalty/settings`),
saveSettings: (slug: string, data: Partial<LoyaltySettings>) =>
req<LoyaltySettings>('PATCH', `/api/hotels/${slug}/loyalty/settings`, data),
listGuests: (slug: string, q?: string) =>
req<LoyaltyGuestApi[]>('GET', `/api/hotels/${slug}/loyalty/guests${q ? `?q=${encodeURIComponent(q)}` : ''}`),
addPoints: (slug: string, guestId: string, data: { amount: number; reason: string; notes?: string }) =>
req<LoyaltyGuestApi>('POST', `/api/hotels/${slug}/loyalty/guests/${guestId}/points`, data),
listTransactions: (slug: string, limit = 50) =>
req<LoyaltyTransaction[]>('GET', `/api/hotels/${slug}/loyalty/transactions?limit=${limit}`),
},
// ── Chat ──────────────────────────────────────────────────────────────────
chat: {
listRooms: (slug: string) =>
req<ChatRoom[]>('GET', `/api/hotels/${slug}/chat/rooms`),
getMessages: (slug: string, roomId: string, limit = 50) =>
req<ChatMessage[]>('GET', `/api/hotels/${slug}/chat/rooms/${roomId}/messages?limit=${limit}`),
sendMessage: (slug: string, roomId: string, text: string) =>
req<ChatMessage>('POST', `/api/hotels/${slug}/chat/rooms/${roomId}/messages`, { text }),
markRead: (slug: string, roomId: string) =>
req<{ ok: boolean }>('PATCH', `/api/hotels/${slug}/chat/rooms/${roomId}/read`),
openDirect: (slug: string, otherUserId: string) =>
req<{ room_id: string }>('POST', `/api/hotels/${slug}/chat/direct/${otherUserId}`),
},
// ── Hotels ────────────────────────────────────────────────────────────────
hotels: {
get: (slug: string) =>
@@ -867,6 +895,56 @@ export interface RatePeriodPayload {
days_of_week?: number[] | null
}
export interface LoyaltySettings {
isActive: boolean
pointsPerRuble: number
pointValue: number
expiryMonths: number
}
export interface LoyaltyGuestApi {
id: string
name: string
email: string | null
phone: string | null
loyaltyPoints: number
loyaltyTier: string
totalSpent: number
}
export interface LoyaltyTransaction {
id: string
guestId: string
guestName: string
amount: number
reason: string
notes: string | null
staffName: string | null
createdAt: string
}
export interface ChatRoom {
id: string
type: 'general' | 'direct'
name: string | null
unreadCount: number
lastMessage: string | null
lastMessageAt: string | null
lastSender: string | null
otherUserName: string | null
otherUserId: string | null
}
export interface ChatMessage {
id: string
roomId: string
senderId: string
senderName: string
senderRole: string
text: string
createdAt: string
}
function toHotelPayload(h: HotelPayload): Record<string, unknown> {
const out: Record<string, unknown> = {}
if (h.name !== undefined) out.name = h.name