TIF_E41253317/app.py

113 lines
3.9 KiB
Python

"""
app.py
======
Entry point aplikasi. Alurnya:
1. Cek login (utils.auth.require_login) -- kalau belum login, form login
ditampilkan dan eksekusi dihentikan di titik itu (st.stop()).
2. Kalau sudah login: load all_results.pkl (di-cache lewat data_loader).
3. Bangun daftar halaman sesuai role yang login, lalu jalankan navigasi.
Sengaja TIDAK memakai folder bawaan `pages/` milik Streamlit, karena itu
akan otomatis menampilkan semua halaman ke semua orang tanpa peduli role.
Sebagai gantinya dipakai st.navigation() yang daftar halamannya dibangun
secara dinamis di bawah, tergantung role -- jadi halaman "Perbandingan
Konfigurasi" memang tidak pernah dikirim ke pemilik toko, bukan cuma
disembunyikan di tampilan.
"""
import streamlit as st
from utils import auth
from utils import ui_components
from utils.data_loader import load_all_results
from views import beranda, detail_peramalan, edit_profil, manajemen_user, perbandingan_konfigurasi
SHOW_PERBANDINGAN_KONFIGURASI = False # Set True kalau mau halaman "Perbandingan Konfigurasi" muncul di menu admin.
st.set_page_config(
page_title="Peramalan Permintaan Produk",
page_icon="📈",
layout="wide",
)
# CSS global (berlaku di SEMUA halaman & popup, termasuk yang muncul di
# dalam st.dialog) -- lihat docstring inject_global_css() untuk detail
# kenapa ini harus dipanggil di sini, bukan diulang di tiap halaman.
ui_components.inject_global_css()
# --- 1. Gerbang login -------------------------------------------------------
if not auth.is_logged_in():
login_page = st.Page(auth.render_login_form, title="Masuk", url_path="login")
st.navigation([login_page]).run()
st.stop()
# --- 2. Load data model (cached) --------------------------------------------
try:
all_results = load_all_results()
except FileNotFoundError as e:
st.error(str(e))
st.caption("Pastikan file `data/all_results.pkl` sudah ada di folder proyek.")
st.stop()
except ValueError as e:
st.error(str(e))
st.stop()
# Simpan di session_state supaya semua halaman bisa akses tanpa load ulang.
# session_state adalah tempat Streamlit menyimpan data selama session pengguna.
st.session_state["all_results"] = all_results
# --- 3. Bangun daftar halaman sesuai role ------------------------------------
role = auth.get_current_role()
detail_page = st.Page(detail_peramalan.render, title="Detail Peramalan", icon="📈", url_path="detail-peramalan")
# Disimpan di session_state supaya views/beranda.py bisa panggil
# st.switch_page(detail_page) langsung dari tombol "Lihat detail",
# tanpa perlu import app.py (yang akan bikin circular import).
st.session_state["_page_detail_peramalan"] = detail_page
pages = [
st.Page(beranda.render, title="Beranda", icon="🏠", url_path="beranda", default=True),
detail_page,
]
if role == "admin":
if SHOW_PERBANDINGAN_KONFIGURASI:
pages.append(
st.Page(
perbandingan_konfigurasi.render,
title="Perbandingan Konfigurasi",
icon="⚖️",
url_path="perbandingan-konfigurasi",
)
)
pages.append(
st.Page(
manajemen_user.render_manajemen_user,
title="Manajemen User",
icon="👥",
url_path="manajemen-user",
)
)
# "Edit Profil" tampil untuk SEMUA role (admin maupun pemilik) -- taruh
# paling akhir supaya tidak mengganggu urutan menu utama di atas.
pages.append(
st.Page(edit_profil.render_edit_profil, title="Edit Profil", icon="⚙️", url_path="edit-profil")
)
# --- Sidebar: info user + tombol keluar (di atas menu navigasi) -------------
with st.sidebar:
st.markdown(f"**{auth.get_display_name()}**")
badge = "👤 Admin" if role == "admin" else "👤 Pemilik Toko"
st.caption(badge)
if st.button("➜]   Keluar", width="stretch"):
auth.logout()
st.rerun()
st.divider()
# --- Jalankan navigasi -------------------------------------------------------
nav = st.navigation(pages)
nav.run()