TIF_E41253317/views/edit_profil.py

127 lines
5.3 KiB
Python

"""
edit_profil.py
===============
Halaman untuk user (admin ATAUPUN pemilik) mengubah profil akunnya
sendiri: username, nama tampilan, dan ganti password.
Dibagi 2 bagian terpisah (2 form independen):
1. "Informasi Akun" -> ubah username & nama tampilan.
Username BOLEH diubah, TAPI wajib divalidasi supaya tidak bentrok
dengan username yang sudah dipakai user lain.
2. "Ganti Password" -> tetap wajib isi password lama (verifikasi diri
sendiri), tidak berubah dari sebelumnya.
Setelah berhasil (di bagian manapun): tampil popup "Berhasil", lalu
form kembali ke tampilan awal -- pola yang sama seperti Manajemen User.
"""
from __future__ import annotations
import streamlit as st
from utils import auth
@st.dialog("✅ Berhasil")
def _dialog_sukses(pesan: str) -> None:
st.write(pesan)
if st.button("Oke", type="primary", width="stretch", key="btn_ep_sukses_ok"):
st.rerun()
def render_edit_profil() -> None:
st.markdown("### Edit Profil")
st.caption(f"Login sebagai **{auth.get_display_name()}** ({auth.get_current_role()})")
# Popup sukses (kalau ada pesan "dititipkan" dari submit sebelumnya)
pending_success = st.session_state.pop("_ep_success_msg", None)
if pending_success:
_dialog_sukses(pending_success)
# >>> Trik versi key: dipakai di KEDUA form supaya, begitu salah satu
# form berhasil disimpan, semua input (termasuk yang belum sempat
# disubmit di form satunya) ikut kembali kosong/ke nilai awal.
form_version = st.session_state.get("_ep_form_version", 0)
username_sekarang = auth.get_current_username()
nama_sekarang = auth.get_display_name()
# ------------------------------------------------------------------
# Bagian 1: Informasi Akun (username & nama tampilan)
# ------------------------------------------------------------------
with st.form(f"form_info_akun_{form_version}", border=True):
st.markdown("**Informasi Akun**")
# >>> FIX: Streamlit TIDAK MENGIZINKAN on_change di widget dalam
# st.form (cuma boleh di st.form_submit_button) -- makanya strip
# spasi username dipindah ke sini, dijalankan pas tombol "Simpan"
# ditekan (bukan real-time saat mengetik seperti di Tambah User).
username_baru = st.text_input("Username", value=username_sekarang)
nama_baru = st.text_input("Nama Tampilan", value=nama_sekarang)
submitted_info = st.form_submit_button("Simpan Informasi Akun", type="primary")
if submitted_info:
username_baru = username_baru.replace(" ", "")
berhasil, pesan = auth.update_own_profile(
username_lama=username_sekarang,
username_baru=username_baru,
nama_baru=nama_baru,
)
if berhasil:
st.session_state["_ep_form_version"] = form_version + 1
st.session_state["_ep_success_msg"] = pesan
st.rerun()
else:
st.error(pesan)
# ------------------------------------------------------------------
# Bagian 2: Ganti Password (tetap wajib password lama)
# ------------------------------------------------------------------
with st.form(f"form_ganti_password_{form_version}", border=True):
st.markdown("**Ganti Password**")
password_lama = st.text_input(
"Password saat ini",
type="password",
placeholder="Masukkan password yang sedang Anda pakai",
)
password_baru = st.text_input(
"Password baru",
type="password",
placeholder="Wajib ada huruf & angka",
)
konfirmasi_password_baru = st.text_input(
"Konfirmasi password baru",
type="password",
placeholder="Ulangi password baru",
)
submitted_pw = st.form_submit_button("Simpan Password Baru", type="primary")
if submitted_pw:
username_login_ini = auth.get_current_username()
# >>> FIX: urutan pengecekan disamakan dengan urutan kolom di
# form (password lama ada paling atas -> dicek paling dulu).
# Sebelumnya kecocokan password baru/konfirmasi dicek DULUAN,
# jadi kalau password lama JUGA salah, pesan yang muncul cuma
# soal password baru tidak cocok -- padahal password lama yang
# salah itu lebih mendasar dan seharusnya diberi tahu lebih dulu.
if not password_lama or not password_baru or not konfirmasi_password_baru:
st.error("Semua kolom wajib diisi.")
elif not auth.verify_password(username_login_ini, password_lama):
st.error("Password lama yang Anda masukkan salah.")
elif password_baru != konfirmasi_password_baru:
st.error("Password baru dan konfirmasinya tidak sama.")
else:
berhasil, pesan = auth.change_own_password(
username=username_login_ini,
old_password=password_lama,
new_password=password_baru,
)
if berhasil:
st.session_state["_ep_form_version"] = form_version + 1
st.session_state["_ep_success_msg"] = pesan
st.rerun()
else:
st.error(pesan)