File size: 7,401 Bytes
bf542dc
 
32051a4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bf542dc
 
 
 
 
 
 
32051a4
bf542dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32051a4
bf542dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32051a4
bf542dc
 
 
 
 
 
32051a4
bf542dc
 
 
 
 
32051a4
bf542dc
 
 
 
 
 
 
 
32051a4
bf542dc
 
 
 
 
32051a4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bf542dc
 
 
 
 
 
 
 
 
 
 
 
32051a4
 
 
 
 
 
 
4aea5eb
32051a4
 
 
 
 
 
410327e
bf542dc
 
 
 
e5fe1fb
bf542dc
 
 
 
 
 
 
 
 
 
 
 
 
 
e5fe1fb
bf542dc
32051a4
 
bf542dc
32051a4
 
bf542dc
e5fe1fb
32051a4
bf542dc
 
 
 
e5fe1fb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
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()