DeepLearning101 commited on
Commit
21615f5
·
verified ·
1 Parent(s): 6bd11fd

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +87 -0
app.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import pandas as pd
4
+ import resend
5
+ from supabase import create_client, Client
6
+
7
+ # --- 設定 ---
8
+ SUPABASE_URL = os.getenv("SUPABASE_URL")
9
+ SUPABASE_KEY = os.getenv("SUPABASE_KEY")
10
+ RESEND_API_KEY = os.getenv("RESEND_API_KEY")
11
+ PUBLIC_SPACE_URL = "https://deeplearning101-ciecietaipei.hf.space" # ⚠️ 請換成您 Space A 的網址
12
+
13
+ supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
14
+ resend.api_key = RESEND_API_KEY
15
+
16
+ def get_bookings():
17
+ # 加入 email 和 remarks 欄位
18
+ response = supabase.table("bookings").select("*").order("created_at", desc=True).execute()
19
+ if not response.data: return pd.DataFrame()
20
+ df = pd.DataFrame(response.data)
21
+ # 確保欄位存在,避免報錯
22
+ cols = ['id', 'date', 'time', 'name', 'tel', 'email', 'pax', 'remarks', 'status']
23
+ for c in cols:
24
+ if c not in df.columns: df[c] = ""
25
+ return df[cols]
26
+
27
+ def send_confirmation_email(booking_id):
28
+ """發送確認信邏輯"""
29
+ try:
30
+ # 1. 抓取訂位資料
31
+ res = supabase.table("bookings").select("*").eq("id", booking_id).execute()
32
+ if not res.data: return "❌ 找不到該訂單"
33
+ booking = res.data[0]
34
+
35
+ email = booking.get('email')
36
+ if not email or "@" not in email: return "❌ 客人未填寫有效 Email"
37
+
38
+ # 2. 產生確認連結 (指向 Space A)
39
+ confirm_link = f"{PUBLIC_SPACE_URL}/?id={booking_id}&action=confirm"
40
+
41
+ # 3. 寄信 (HTML)
42
+ params = {
43
+ "from": "Cié Cié Taipei <onboarding@resend.dev>", # 若沒買網域,先用 Resend 預設的
44
+ "to": [email],
45
+ "subject": f"[{booking['date']}] Cié Cié Taipei 訂位確認",
46
+ "html": f"""
47
+ <div style="padding: 20px; background: #111; color: #d4af37; font-family: sans-serif;">
48
+ <h2>訂位保留確認</h2>
49
+ <p>{booking['name']} 您好,我們已為您保留座位:</p>
50
+ <ul>
51
+ <li>日期:{booking['date']}</li>
52
+ <li>時間:{booking['time']}</li>
53
+ <li>人數:{booking['pax']} 位</li>
54
+ </ul>
55
+ <p>請點擊下方按鈕確認出席:</p>
56
+ <a href="{confirm_link}" style="background: #d4af37; color: black; padding: 10px 20px; text-decoration: none; border-radius: 5px; font-weight: bold;">✅ 我會出席 (Confirm)</a>
57
+ <br><br>
58
+ <p style="color: #666; font-size: 12px;">若需取消,請直接回覆此信或致電。</p>
59
+ </div>
60
+ """
61
+ }
62
+ resend.Emails.send(params)
63
+
64
+ # 4. 更新狀態為「已發信」
65
+ supabase.table("bookings").update({"status": "已發確認信"}).eq("id", booking_id).execute()
66
+ return f"✅ 已發送確認信給 {booking['name']} ({email})"
67
+
68
+ except Exception as e:
69
+ return f"❌ 發信失敗: {str(e)}"
70
+
71
+ # --- 介面 ---
72
+ with gr.Blocks(title="Admin") as demo:
73
+ gr.Markdown("# 🍷 訂位管理後台")
74
+ refresh_btn = gr.Button("🔄 重新整理")
75
+ booking_table = gr.Dataframe(interactive=False)
76
+
77
+ with gr.Row():
78
+ id_input = gr.Number(label="訂單 ID", precision=0)
79
+ action_btn = gr.Button("📧 發送確認信 (Send Email)", variant="primary")
80
+
81
+ log_output = gr.Textbox(label="執行結果")
82
+
83
+ refresh_btn.click(get_bookings, outputs=booking_table)
84
+ action_btn.click(send_confirmation_email, inputs=id_input, outputs=log_output)
85
+
86
+ if __name__ == "__main__":
87
+ demo.launch()