GphaHoa commited on
Commit
be7c03b
·
verified ·
1 Parent(s): bb5277b

Delete src

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +0 -213
src/streamlit_app.py DELETED
@@ -1,213 +0,0 @@
1
- import streamlit as st
2
- from supabase import create_client
3
- from datetime import datetime
4
- from zoneinfo import ZoneInfo
5
- from supabase_auth.errors import AuthApiError
6
- import time
7
-
8
- # ========== CONFIG ==========
9
- st.set_page_config(
10
- page_title="Personal Diary",
11
- page_icon="📔",
12
- layout="wide"
13
- )
14
-
15
- supabase = create_client(
16
- st.secrets["SUPABASE_URL"],
17
- st.secrets["SUPABASE_KEY"]
18
- )
19
-
20
- # ========== STYLE ==========
21
- st.markdown("""
22
- <style>
23
- .diary-card {
24
- padding: 1rem;
25
- border-radius: 12px;
26
- background-color: #f8f9fa;
27
- margin-bottom: 1rem;
28
- }
29
- .small-text {
30
- font-size: 0.8rem;
31
- color: #6c757d;
32
- }
33
- </style>
34
- """, unsafe_allow_html=True)
35
-
36
- def signup(email, password):
37
- return supabase.auth.sign_up({
38
- "email": email,
39
- "password": password
40
- })
41
-
42
-
43
- # ========== HEADER ==========
44
- st.title("📔 Personal Diary")
45
- st.caption("Ghi chép suy nghĩ mỗi ngày – phiên bản demo")
46
-
47
- # ========== LOGIN ==========
48
- if "user" not in st.session_state:
49
- st.subheader("🔐 Tài khoản")
50
-
51
- tab_login, tab_signup = st.tabs(["Đăng nhập", "Đăng ký"])
52
-
53
- # ===== LOGIN =====
54
- with tab_login:
55
- email = st.text_input("Email", key="login_email")
56
- password = st.text_input("Mật khẩu", type="password", key="login_pw")
57
-
58
- if st.button("➡️ Đăng nhập", use_container_width=True):
59
- res = supabase.auth.sign_in_with_password({
60
- "email": email,
61
- "password": password
62
- })
63
-
64
- if res.user:
65
- st.session_state.user = res.user
66
- st.success("Đăng nhập thành công")
67
- st.rerun()
68
- else:
69
- st.error("Sai email hoặc mật khẩu")
70
-
71
- # ===== SIGNUP =====
72
- with tab_signup:
73
- email = st.text_input("Email đăng ký", key="signup_email")
74
- password = st.text_input(
75
- "Mật khẩu (tối thiểu 6 ký tự)",
76
- type="password",
77
- key="signup_pw"
78
- )
79
-
80
- # init cooldown
81
- if "signup_cooldown_until" not in st.session_state:
82
- st.session_state.signup_cooldown_until = 0
83
-
84
- now = time.time()
85
- cooldown_left = int(st.session_state.signup_cooldown_until - now)
86
-
87
- if cooldown_left > 0:
88
- st.warning(f"⏳ Vui lòng thử lại sau {cooldown_left} giây")
89
-
90
- signup_disabled = cooldown_left > 0
91
-
92
- if st.button(
93
- "🆕 Tạo tài khoản",
94
- use_container_width=True,
95
- disabled=signup_disabled
96
- ):
97
- try:
98
- res = signup(email, password)
99
-
100
- if res.user:
101
- st.session_state.user = res.user
102
- st.success("Đăng ký thành công 🎉")
103
- st.rerun()
104
- else:
105
- st.error("Không thể đăng ký")
106
-
107
- except AuthApiError as e:
108
- msg = str(e)
109
-
110
- # Bắt lỗi rate limit 60s
111
- if "only request this after" in msg:
112
- # Mặc định 60s nếu parse không được
113
- wait_seconds = 60
114
-
115
- # cố gắng parse số giây từ message
116
- import re
117
-
118
- match = re.search(r"after (\d+) seconds", msg)
119
- if match:
120
- wait_seconds = int(match.group(1))
121
-
122
- st.session_state.signup_cooldown_until = time.time() + wait_seconds
123
- st.error(f"🚫 Bạn đã thử quá nhiều lần. Vui lòng đợi {wait_seconds} giây rồi thử lại.")
124
- st.rerun()
125
- else:
126
- st.error("Lỗi đăng ký: " + msg)
127
-
128
-
129
- # ========== MAIN APP ==========
130
- else:
131
- user = st.session_state.user
132
-
133
- # Top bar
134
- top_left, top_right = st.columns([4, 1])
135
- with top_left:
136
- st.markdown(f"👋 Xin chào **{user.email}**")
137
- with top_right:
138
- if st.button("🚪 Đăng xuất", use_container_width=True):
139
- st.session_state.clear()
140
- st.rerun()
141
-
142
- st.divider()
143
-
144
- # Main layout
145
- left, right = st.columns([2, 3])
146
-
147
- # ===== LEFT: WRITE =====
148
- with left:
149
- st.subheader("✍️ Viết nhật ký")
150
-
151
- content = st.text_area(
152
- "Hôm nay bạn nghĩ gì?",
153
- height=250,
154
- placeholder="Viết suy nghĩ của bạn ở đây..."
155
- )
156
-
157
- if st.button("💾 Lưu nhật ký", use_container_width=True):
158
- if content.strip():
159
- supabase.table("journals").insert({
160
- "user_id": user.id,
161
- "content": content,
162
- "created_at": datetime.utcnow().isoformat()
163
- }).execute()
164
-
165
- st.success("Đã lưu nhật ký ✨")
166
- st.rerun()
167
- else:
168
- st.warning("Nội dung đang trống")
169
-
170
- # ===== RIGHT: LIST =====
171
- with right:
172
- st.subheader("📜 Nhật ký của bạn")
173
-
174
- data = supabase.table("journals") \
175
- .select("*") \
176
- .eq("user_id", user.id) \
177
- .order("created_at", desc=True) \
178
- .execute()
179
-
180
- if not data.data:
181
- st.info("Chưa có nhật ký nào")
182
- else:
183
- for row in data.data:
184
- # Format ngày cho gọn
185
- created_dt = datetime.fromisoformat(
186
- row["created_at"].replace("Z", "+00:00")
187
- ).astimezone(ZoneInfo("Asia/Ho_Chi_Minh"))
188
-
189
- date_label = created_dt.strftime("%d/%m/%Y – %H:%M")
190
-
191
- # Dropdown theo ngày
192
- with st.expander(f"📅 {date_label}", expanded=False):
193
-
194
- new_content = st.text_area(
195
- "Nội dung",
196
- row["content"],
197
- key=row["id"],
198
- height=120
199
- )
200
-
201
- col_u, col_d = st.columns(2)
202
-
203
- if col_u.button("✏️ Cập nhật", key=f"u{row['id']}"):
204
- supabase.table("journals").update({
205
- "content": new_content,
206
- "updated_at": datetime.utcnow().isoformat()
207
- }).eq("id", row["id"]).execute()
208
- st.rerun()
209
-
210
- if col_d.button("🗑️ Xoá", key=f"d{row['id']}"):
211
- supabase.table("journals").delete() \
212
- .eq("id", row["id"]).execute()
213
- st.rerun()