Bayhaqy's picture
Update app.py
410327e verified
import gradio as gr
import pandas as pd
import os
# ========== Constants ==========
EXCEL_FILE = "data_store.xlsx"
DATA_SHEET = "DATA"
USER_SHEET = "USERS"
# ========== Load or Create Data ==========
def load_data():
if os.path.exists(EXCEL_FILE):
xls = pd.read_excel(EXCEL_FILE, sheet_name=None)
df_data = xls.get(DATA_SHEET, pd.DataFrame(columns=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"]))
df_users = xls.get(USER_SHEET, pd.DataFrame([{"USERNAME": "ADMIN", "PASSWORD": "ADMIN"}]))
else:
df_data = pd.DataFrame(columns=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"])
df_users = pd.DataFrame([{"USERNAME": "ADMIN", "PASSWORD": "ADMIN"}])
save_data(df_data, df_users)
return df_data, df_users
def save_data(data_df, users_df):
with pd.ExcelWriter(EXCEL_FILE, engine='openpyxl', mode='w') as writer:
data_df.to_excel(writer, index=False, sheet_name=DATA_SHEET)
users_df.to_excel(writer, index=False, sheet_name=USER_SHEET)
# ========== Initial Data ==========
df, users_df = load_data()
# ========== Helpers ==========
def to_upper(df_input):
return df_input.applymap(lambda x: str(x).upper().strip() if pd.notnull(x) else x)
def get_active_data():
return df[df["REMARK"].str.upper() != "DELETE"].reset_index(drop=True)
def login(username, password):
username, password = username.strip().upper(), password.strip()
is_valid = not users_df[(users_df["USERNAME"] == username) & (users_df["PASSWORD"] == password)].empty
if is_valid:
return "", gr.update(visible=False), gr.update(visible=True), get_active_data(), show_users()
return "Invalid login", gr.update(visible=True), gr.update(visible=False), pd.DataFrame(), pd.DataFrame()
def bulk_submit(dataframe):
global df
new_df = pd.DataFrame(dataframe).dropna(how="all")
if new_df.empty:
return get_active_data()
new_df = to_upper(new_df)
required = ["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"]
new_df = new_df[required].dropna()
pk_cols = required
merged = pd.merge(new_df, df[pk_cols], on=pk_cols, how="left", indicator=True)
df_filtered = new_df[merged["_merge"] == "left_only"]
df = pd.concat([df, df_filtered], ignore_index=True)
save_data(df, users_df)
return get_active_data()
def delete_selected_rows(selected_df):
global df
try:
if selected_df.empty:
return "Tidak ada baris yang dipilih", get_active_data()
for _, row in selected_df.iterrows():
mask = (
(df["USERNAME"] == row["USERNAME"]) &
(df["COUNTRYCODE"] == row["COUNTRYCODE"]) &
(df["SBUCODE"] == row["SBUCODE"]) &
(df["BRANDCODE"] == row["BRANDCODE"]) &
(df["CONCEPTCODE"] == row["CONCEPTCODE"]) &
(df["CHANNEL"] == row["CHANNEL"]) &
(df["REMARK"].str.upper() != "DELETE")
)
df.loc[mask, "REMARK"] = "DELETE"
save_data(df, users_df)
return "Berhasil dihapus.", get_active_data()
except Exception as e:
return f"Error: {e}", get_active_data()
def add_user(username, password):
global users_df
username, password = username.strip().upper(), password.strip()
if not username or not password:
return "Username/password tidak boleh kosong", show_users()
if username in users_df["USERNAME"].values:
return "Username sudah ada", show_users()
users_df = pd.concat([users_df, pd.DataFrame([{"USERNAME": username, "PASSWORD": password}])], ignore_index=True)
save_data(df, users_df)
return f"User {username} ditambahkan", show_users()
def delete_user(username):
global users_df
username = username.strip().upper()
if username == "ADMIN":
return "ADMIN tidak boleh dihapus", show_users()
users_df = users_df[users_df["USERNAME"] != username].reset_index(drop=True)
save_data(df, users_df)
return f"User {username} dihapus", show_users()
def show_users():
return users_df.copy()
def show_guide():
return """
### Panduan Penggunaan Aplikasi
1. **Login**
- Gunakan username dan password.
2. **Input Data**
- Lihat data aktif.
- Input data baru dengan kolom lengkap.
- Pilih baris dan klik "Delete Selected Rows" untuk tandai delete.
3. **Manajemen User**
- Tambah dan hapus user (kecuali ADMIN).
4. **Data yang dihapus tidak benar-benar dihapus**, hanya ditandai `REMARK = DELETE`.
"""
# ========== UI ==========
with gr.Blocks() as app:
gr.Markdown("## Login")
login_box = gr.Column(visible=True)
with login_box:
user = gr.Textbox(label="Username")
pw = gr.Textbox(label="Password", type="password")
btn_login = gr.Button("Login")
login_msg = gr.Textbox(visible=True, interactive=False, show_label=False)
tab_section = gr.Tabs(visible=False)
with tab_section:
with gr.Tab("Input Data"):
gr.Markdown("### Data Aktif")
df_list = gr.Dataframe(
label="List Data Aktif",
interactive=False,
column_widths=["auto"]*7,
wrap=True,
show_copy_button=True,
# show_download_button=True,
show_fullscreen_button=True,
show_search=True,
show_row_numbers=True,
pinned_columns=["USERNAME"]
)
selected_df = gr.Dataframe(visible=False)
gr.Markdown("---")
gr.Markdown("### Input Data Baru")
df_input = gr.Dataframe(
headers=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"],
row_count=5,
col_count=(7, "fixed"),
label="Form Input"
)
btn_submit = gr.Button("Submit Data")
btn_delete = gr.Button("Delete Selected Rows")
delete_msg = gr.Textbox(visible=True, interactive=False, show_label=False)
with gr.Tab("User Management"):
gr.Markdown("### Kelola User")
new_user = gr.Textbox(label="New Username")
new_pass = gr.Textbox(label="New Password")
btn_add = gr.Button("Add User")
del_user = gr.Textbox(label="Delete Username")
btn_del = gr.Button("Delete User")
user_msg = gr.Textbox(visible=True, interactive=False, show_label=False)
user_table = gr.Dataframe(label="User List", interactive=False)
with gr.Tab("User Guide"):
gr.Markdown(show_guide())
# ==== Events ====
btn_login.click(fn=login, inputs=[user, pw], outputs=[login_msg, login_box, tab_section, df_list, user_table])
btn_submit.click(fn=bulk_submit, inputs=[df_input], outputs=[df_list])
df_list.select(fn=lambda df, evt: df.iloc[[evt.index]] if evt.index is not None else pd.DataFrame(),
inputs=[df_list], outputs=[selected_df])
btn_delete.click(fn=delete_selected_rows, inputs=[selected_df], outputs=[delete_msg, df_list])
btn_add.click(fn=add_user, inputs=[new_user, new_pass], outputs=[user_msg, user_table])
btn_del.click(fn=delete_user, inputs=[del_user], outputs=[user_msg, user_table])
app.launch()