MBG0903 commited on
Commit
a2918cb
Β·
verified Β·
1 Parent(s): 8678067

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +270 -0
app.py ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import secrets
3
+ import string
4
+ from datetime import datetime
5
+
6
+ # ----------------------------
7
+ # In-memory stores (prototype)
8
+ # ----------------------------
9
+ # Sample "bookings database"
10
+ BOOKINGS = [
11
+ {
12
+ "booking_ref": "RZQ12345",
13
+ "last_name": "Khan",
14
+ "checkin_date": "2026-02-10",
15
+ "first_name": "Aamir",
16
+ "email": "aamir.khan@example.com",
17
+ "phone": "+673-8000000",
18
+ "room_type": "Deluxe King",
19
+ "nights": 2,
20
+ },
21
+ {
22
+ "booking_ref": "RZQ67890",
23
+ "last_name": "Tan",
24
+ "checkin_date": "2026-02-11",
25
+ "first_name": "Mei",
26
+ "email": "mei.tan@example.com",
27
+ "phone": "+673-8111111",
28
+ "room_type": "Executive Twin",
29
+ "nights": 3,
30
+ },
31
+ ]
32
+
33
+ # precheckin_code -> record
34
+ PRECHECKIN_RECORDS = {}
35
+
36
+
37
+ # ----------------------------
38
+ # Helpers
39
+ # ----------------------------
40
+ def _find_booking(booking_ref: str, last_name: str, checkin_date: str):
41
+ booking_ref = (booking_ref or "").strip().upper()
42
+ last_name = (last_name or "").strip().lower()
43
+ checkin_date = (checkin_date or "").strip()
44
+
45
+ for b in BOOKINGS:
46
+ if (
47
+ b["booking_ref"].upper() == booking_ref
48
+ and b["last_name"].lower() == last_name
49
+ and b["checkin_date"] == checkin_date
50
+ ):
51
+ return b
52
+ return None
53
+
54
+
55
+ def _generate_code(prefix="RZQ"):
56
+ # Human-friendly: RZQ-ABCDE1 (no confusing chars)
57
+ alphabet = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
58
+ token = "".join(secrets.choice(alphabet) for _ in range(6))
59
+ return f"{prefix}-{token}"
60
+
61
+
62
+ def _now():
63
+ return datetime.now().strftime("%Y-%m-%d %H:%M")
64
+
65
+
66
+ # ----------------------------
67
+ # Core actions
68
+ # ----------------------------
69
+ def verify_booking(booking_ref, last_name, checkin_date):
70
+ b = _find_booking(booking_ref, last_name, checkin_date)
71
+ if not b:
72
+ return (
73
+ gr.update(visible=True, value="❌ Booking not found. Please check details."),
74
+ gr.update(visible=False),
75
+ gr.update(value=None),
76
+ )
77
+
78
+ summary = (
79
+ f"βœ… Booking Found\n\n"
80
+ f"Name: {b['first_name']} {b['last_name']}\n"
81
+ f"Booking Ref: {b['booking_ref']}\n"
82
+ f"Check-in Date: {b['checkin_date']}\n"
83
+ f"Room Type: {b['room_type']}\n"
84
+ f"Nights: {b['nights']}\n"
85
+ )
86
+ return (
87
+ gr.update(visible=True, value=summary),
88
+ gr.update(visible=True),
89
+ gr.update(value=b), # store booking dict in hidden state
90
+ )
91
+
92
+
93
+ def complete_checkin(mode, booking_state, arrival_time, bed_pref, special_request, id_file):
94
+ """
95
+ mode: "Pre-Arrival" or "On-Arrival"
96
+ booking_state: dict from verify_booking
97
+ id_file: uploaded file (optional). We don't OCR in v1; we simply mark as 'provided'.
98
+ """
99
+ if not booking_state:
100
+ return "❌ Please verify your booking first.", "", gr.update(visible=False)
101
+
102
+ code = _generate_code("RZQ")
103
+ record = {
104
+ "code": code,
105
+ "mode": mode,
106
+ "status": "Pre-Checked-In" if mode == "Pre-Arrival" else "Checked-In (On-Arrival)",
107
+ "created_at": _now(),
108
+ "guest_name": f"{booking_state['first_name']} {booking_state['last_name']}",
109
+ "booking_ref": booking_state["booking_ref"],
110
+ "checkin_date": booking_state["checkin_date"],
111
+ "room_type": booking_state["room_type"],
112
+ "arrival_time": arrival_time or "",
113
+ "bed_pref": bed_pref or "",
114
+ "special_request": special_request or "",
115
+ "id_provided": bool(id_file),
116
+ "id_filename": getattr(id_file, "name", "") if id_file else "",
117
+ }
118
+ PRECHECKIN_RECORDS[code] = record
119
+
120
+ guest_msg = (
121
+ "βœ… Check-in submitted successfully.\n\n"
122
+ f"Your Express Check-In Code: {code}\n"
123
+ "Please show this code at the front desk for quick key collection."
124
+ )
125
+
126
+ staff_view = (
127
+ f"--- FRONT DESK VIEW ---\n"
128
+ f"Code: {record['code']}\n"
129
+ f"Status: {record['status']}\n"
130
+ f"Guest: {record['guest_name']}\n"
131
+ f"Booking Ref: {record['booking_ref']}\n"
132
+ f"Check-in Date: {record['checkin_date']}\n"
133
+ f"Room Type: {record['room_type']}\n"
134
+ f"Arrival Time: {record['arrival_time']}\n"
135
+ f"Bed Preference: {record['bed_pref']}\n"
136
+ f"Special Request: {record['special_request']}\n"
137
+ f"ID Provided: {'Yes' if record['id_provided'] else 'No'}\n"
138
+ f"Submitted At: {record['created_at']}\n"
139
+ )
140
+
141
+ return guest_msg, staff_view, gr.update(visible=True)
142
+
143
+
144
+ def staff_lookup(code):
145
+ code = (code or "").strip().upper()
146
+ rec = PRECHECKIN_RECORDS.get(code)
147
+ if not rec:
148
+ return "❌ Code not found. Please check the code or ask guest to re-submit."
149
+
150
+ view = (
151
+ f"βœ… Record Found\n\n"
152
+ f"Code: {rec['code']}\n"
153
+ f"Status: {rec['status']}\n"
154
+ f"Guest: {rec['guest_name']}\n"
155
+ f"Booking Ref: {rec['booking_ref']}\n"
156
+ f"Check-in Date: {rec['checkin_date']}\n"
157
+ f"Room Type: {rec['room_type']}\n"
158
+ f"Arrival Time: {rec['arrival_time']}\n"
159
+ f"Bed Preference: {rec['bed_pref']}\n"
160
+ f"Special Request: {rec['special_request']}\n"
161
+ f"ID Provided: {'Yes' if rec['id_provided'] else 'No'}\n"
162
+ f"Submitted At: {rec['created_at']}\n"
163
+ )
164
+ return view
165
+
166
+
167
+ def reset_form():
168
+ return (
169
+ "", "", "", # booking ref, last name, date
170
+ gr.update(value="", visible=False), # verify result
171
+ gr.update(visible=False), # details accordion
172
+ None, # booking state
173
+ "Pre-Arrival", # mode
174
+ "", "", "", # arrival_time, bed_pref, special_request
175
+ None, # id_file
176
+ "", "", # guest_msg, staff_preview
177
+ gr.update(visible=False), # staff preview container
178
+ )
179
+
180
+
181
+ # ----------------------------
182
+ # UI
183
+ # ----------------------------
184
+ with gr.Blocks(title="Hotel Self Check-In Prototype (Pre-Arrival / On-Arrival)") as demo:
185
+ gr.Markdown(
186
+ """
187
+ # 🏨 Smart Self Check-In (Prototype)
188
+ Complete your check-in in under 2 minutes β€” **Pre-Arrival** or **On-Arrival**.
189
+
190
+ **Note:** This is a demo prototype using sample bookings and a temporary in-memory store.
191
+ """
192
+ )
193
+
194
+ with gr.Tab("Guest: Self Check-In"):
195
+ mode = gr.Radio(["Pre-Arrival", "On-Arrival"], value="Pre-Arrival", label="Check-In Mode")
196
+
197
+ with gr.Row():
198
+ booking_ref = gr.Textbox(label="Booking Reference", placeholder="e.g., RZQ12345")
199
+ last_name = gr.Textbox(label="Last Name", placeholder="e.g., Khan")
200
+ checkin_date = gr.Textbox(label="Check-in Date (YYYY-MM-DD)", placeholder="e.g., 2026-02-10")
201
+
202
+ verify_btn = gr.Button("Verify Booking", variant="primary")
203
+ verify_result = gr.Textbox(label="Verification Result", visible=False, lines=7)
204
+
205
+ booking_state = gr.State(None)
206
+
207
+ details_box = gr.Accordion("Step 2: Check-in Details", open=True, visible=False)
208
+ with details_box:
209
+ arrival_time = gr.Textbox(label="Expected Arrival Time (optional)", placeholder="e.g., 18:30")
210
+ bed_pref = gr.Dropdown(
211
+ ["No preference", "King", "Twin", "High floor", "Near elevator (if available)"],
212
+ value="No preference",
213
+ label="Preference (optional)",
214
+ )
215
+ special_request = gr.Textbox(
216
+ label="Special Requests (optional)",
217
+ placeholder="e.g., baby cot, late check-out request, allergy notes",
218
+ lines=3,
219
+ )
220
+ id_file = gr.File(label="Upload ID (optional for v1)", file_types=["image", "pdf"])
221
+
222
+ submit_btn = gr.Button("Submit Check-In", variant="primary")
223
+
224
+ guest_msg = gr.Textbox(label="Guest Confirmation", lines=6)
225
+ staff_preview = gr.Textbox(label="(Demo) Front Desk Preview", lines=12)
226
+ staff_preview_container = gr.Column(visible=False)
227
+
228
+ reset_btn = gr.Button("Reset")
229
+
230
+ # Wiring
231
+ verify_btn.click(
232
+ verify_booking,
233
+ inputs=[booking_ref, last_name, checkin_date],
234
+ outputs=[verify_result, details_box, booking_state],
235
+ )
236
+
237
+ submit_btn.click(
238
+ complete_checkin,
239
+ inputs=[mode, booking_state, arrival_time, bed_pref, special_request, id_file],
240
+ outputs=[guest_msg, staff_preview, staff_preview_container],
241
+ )
242
+
243
+ reset_btn.click(
244
+ reset_form,
245
+ inputs=[],
246
+ outputs=[
247
+ booking_ref, last_name, checkin_date,
248
+ verify_result, details_box, booking_state,
249
+ mode, arrival_time, bed_pref, special_request, id_file,
250
+ guest_msg, staff_preview, staff_preview_container
251
+ ],
252
+ )
253
+
254
+ gr.Markdown(
255
+ """
256
+ ### Sample bookings to test
257
+ - Booking Ref: **RZQ12345**, Last Name: **Khan**, Date: **2026-02-10**
258
+ - Booking Ref: **RZQ67890**, Last Name: **Tan**, Date: **2026-02-11**
259
+ """
260
+ )
261
+
262
+ with gr.Tab("Front Desk: Verify Code"):
263
+ gr.Markdown("Enter the guest's **Express Check-In Code** to retrieve their pre-check-in record.")
264
+ staff_code = gr.Textbox(label="Express Check-In Code", placeholder="e.g., RZQ-ABC123")
265
+ staff_lookup_btn = gr.Button("Lookup", variant="primary")
266
+ staff_view = gr.Textbox(label="Front Desk Result", lines=14)
267
+
268
+ staff_lookup_btn.click(staff_lookup, inputs=[staff_code], outputs=[staff_view])
269
+
270
+ demo.launch()