Spaces:
Sleeping
Sleeping
import os | |
import base64 | |
import streamlit as st | |
from app.db import supabase | |
def auth_view(): | |
"""Render Supabase authentication with Login, Register, and Forgot Password tabs.""" | |
# Wrapper (centered) for all auth content | |
left, center, right = st.columns([1, 2, 1]) | |
with center: | |
# Header: smaller PNP logo and centered title | |
# Path logo | |
logo_path = os.path.join("assets", "pnp-logo.png") | |
# Convert ke base64 biar bisa di-embed langsung | |
def get_base64_image(path): | |
with open(path, "rb") as f: | |
return base64.b64encode(f.read()).decode() | |
encoded_logo = get_base64_image(logo_path) | |
# Render dalam satu div center | |
st.markdown( | |
f""" | |
<div style="text-align:center;"> | |
<img src="data:image/png;base64,{encoded_logo}" width="100"> | |
<h1 style="margin-top:0.25rem;">PNP bot</h1> | |
</div> | |
""", | |
unsafe_allow_html=True | |
) | |
# Auth tabs inside wrapper | |
tab_login, tab_register, tab_forgot = st.tabs(["Login", "Register", "Forgot Password"]) | |
with tab_login: | |
with st.form("login_form"): | |
email = st.text_input("Email") | |
password = st.text_input("Password", type="password") | |
submitted = st.form_submit_button("Login") | |
if submitted: | |
# Demo password fallback | |
shared_pw = os.getenv("APP_DEMO_PASSWORD") | |
if shared_pw and password == shared_pw: | |
st.session_state["user"] = {"id": "demo-user", "email": email or "[email protected]"} | |
st.success("Login demo berhasil") | |
st.rerun() | |
try: | |
auth_res = supabase.auth.sign_in_with_password({ | |
"email": email, | |
"password": password, | |
}) | |
user = getattr(auth_res, "user", None) | |
if user: | |
st.session_state["user"] = {"id": user.id, "email": getattr(user, "email", email)} | |
session_obj = getattr(auth_res, "session", None) | |
if session_obj: | |
st.session_state["sb_session"] = { | |
"access_token": getattr(session_obj, "access_token", None), | |
"refresh_token": getattr(session_obj, "refresh_token", None), | |
} | |
st.success("Login berhasil") | |
st.rerun() | |
else: | |
st.error("Email atau password salah.") | |
except Exception as e: | |
st.error(f"Gagal login: {e}") | |
with tab_register: | |
st.caption("Buat akun baru. Anda akan menerima email konfirmasi.") | |
with st.form("register_form"): | |
r_email = st.text_input("Email", key="reg_email") | |
r_password = st.text_input("Password", type="password", key="reg_password") | |
r_password2 = st.text_input("Konfirmasi Password", type="password", key="reg_password2") | |
submitted_r = st.form_submit_button("Register") | |
if submitted_r: | |
if r_password != r_password2: | |
st.error("Password tidak sama.") | |
else: | |
try: | |
# Prefer explicit env, then generic site URL, then production URL | |
redirect_url = os.getenv( | |
"SUPABASE_EMAIL_REDIRECT", | |
os.getenv("NEXT_PUBLIC_SITE_URL", "https://yozora721-pnp-chatbot-v1.hf.space"), | |
) + "/reset_password" | |
supabase.auth.sign_up({ | |
"email": r_email, | |
"password": r_password, | |
"options": {"email_redirect_to": redirect_url} | |
}) | |
st.success("Registrasi berhasil. Silakan cek email untuk konfirmasi.") | |
except Exception as e: | |
st.error(f"Gagal registrasi: {e}") | |
with tab_forgot: | |
st.caption("Kirim tautan reset password ke email Anda.") | |
with st.form("forgot_form"): | |
f_email = st.text_input("Email", key="forgot_email") | |
submitted_f = st.form_submit_button("Kirim Link Reset") | |
if submitted_f: | |
try: | |
# Prefer explicit env, then generic site URL, then production URL | |
redirect_url = os.getenv( | |
"SUPABASE_EMAIL_REDIRECT", | |
os.getenv("NEXT_PUBLIC_SITE_URL", "https://yozora721-pnp-chatbot-v1.hf.space"), | |
) + "/reset_password" | |
supabase.auth.reset_password_for_email(f_email, {"redirect_to": redirect_url}) | |
st.success("Email reset password telah dikirim. Periksa kotak masuk Anda.") | |
except Exception as e: | |
st.error(f"Gagal mengirim email reset password: {e}") | |