Bayhaqy commited on
Commit
bf542dc
·
verified ·
1 Parent(s): a678992

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +215 -0
app.py ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import pandas as pd
4
+
5
+ # ======= Constants =======
6
+ EXCEL_FILE = "database.xlsx"
7
+ SHEET_DATA = "Data"
8
+ SHEET_USERS = "Users"
9
+
10
+ # ======= Global Data Store =======
11
+ # Fungsi untuk load data dari Excel jika ada
12
+ def load_data():
13
+ global df, users_df
14
+ if os.path.exists(EXCEL_FILE):
15
+ try:
16
+ xls = pd.ExcelFile(EXCEL_FILE)
17
+ if SHEET_DATA in xls.sheet_names:
18
+ df = pd.read_excel(xls, sheet_name=SHEET_DATA)
19
+ else:
20
+ df = pd.DataFrame(columns=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"])
21
+ if SHEET_USERS in xls.sheet_names:
22
+ users_df = pd.read_excel(xls, sheet_name=SHEET_USERS)
23
+ else:
24
+ users_df = pd.DataFrame([{"USERNAME": "ADMIN", "PASSWORD": "ADMIN"}])
25
+ except Exception as e:
26
+ print(f"Error loading Excel: {e}")
27
+ df = pd.DataFrame(columns=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"])
28
+ users_df = pd.DataFrame([{"USERNAME": "ADMIN", "PASSWORD": "ADMIN"}])
29
+ else:
30
+ df = pd.DataFrame(columns=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"])
31
+ users_df = pd.DataFrame([{"USERNAME": "ADMIN", "PASSWORD": "ADMIN"}])
32
+
33
+ # Fungsi untuk simpan data ke Excel
34
+ def save_data():
35
+ global df, users_df
36
+ with pd.ExcelWriter(EXCEL_FILE, engine='openpyxl', mode='w') as writer:
37
+ df.to_excel(writer, index=False, sheet_name=SHEET_DATA)
38
+ users_df.to_excel(writer, index=False, sheet_name=SHEET_USERS)
39
+
40
+ # Load data di awal
41
+ load_data()
42
+
43
+ # ======= Helper Functions =======
44
+
45
+ def to_upper(df_input):
46
+ return df_input.applymap(lambda x: str(x).upper().strip() if pd.notnull(x) else x)
47
+
48
+ def get_active_data():
49
+ return df[df["REMARK"].str.upper() != "DELETE"].reset_index(drop=True)
50
+
51
+ def login(username, password):
52
+ username = username.strip().upper()
53
+ password = password.strip()
54
+ is_valid = not users_df[(users_df["USERNAME"] == username) & (users_df["PASSWORD"] == password)].empty
55
+ if is_valid:
56
+ return "", gr.update(visible=False), gr.update(visible=True), get_active_data(), show_users()
57
+ return "Invalid login", gr.update(visible=True), gr.update(visible=False), pd.DataFrame(), pd.DataFrame()
58
+
59
+ def bulk_submit(dataframe):
60
+ global df
61
+ new_df = pd.DataFrame(dataframe).dropna(how="all")
62
+ if new_df.empty:
63
+ return get_active_data()
64
+ new_df = to_upper(new_df)
65
+ required = ["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"]
66
+ new_df = new_df[required].dropna()
67
+ pk_cols = required
68
+ merged = pd.merge(new_df, df[pk_cols], on=pk_cols, how="left", indicator=True)
69
+ df_filtered = new_df[merged["_merge"] == "left_only"]
70
+ df = pd.concat([df, df_filtered], ignore_index=True)
71
+ save_data() # Simpan setelah update data
72
+ return get_active_data()
73
+
74
+ def delete_selected_rows(selected_df):
75
+ global df
76
+ try:
77
+ if selected_df.empty:
78
+ return "Tidak ada baris yang dipilih", get_active_data()
79
+ for _, row in selected_df.iterrows():
80
+ mask = (
81
+ (df["USERNAME"] == row["USERNAME"]) &
82
+ (df["COUNTRYCODE"] == row["COUNTRYCODE"]) &
83
+ (df["SBUCODE"] == row["SBUCODE"]) &
84
+ (df["BRANDCODE"] == row["BRANDCODE"]) &
85
+ (df["CONCEPTCODE"] == row["CONCEPTCODE"]) &
86
+ (df["CHANNEL"] == row["CHANNEL"]) &
87
+ (df["REMARK"].str.upper() != "DELETE")
88
+ )
89
+ df.loc[mask, "REMARK"] = "DELETE"
90
+ save_data() # Simpan setelah update data
91
+ return "Berhasil dihapus.", get_active_data()
92
+ except Exception as e:
93
+ return f"Error: {e}", get_active_data()
94
+
95
+ def add_user(username, password):
96
+ global users_df
97
+ username = username.strip().upper()
98
+ password = password.strip()
99
+ if not username or not password:
100
+ return "Username/password tidak boleh kosong", show_users()
101
+ if username in users_df["USERNAME"].values:
102
+ return "Username sudah ada", show_users()
103
+ users_df = pd.concat([users_df, pd.DataFrame([{"USERNAME": username, "PASSWORD": password}])], ignore_index=True)
104
+ save_data() # Simpan setelah update user
105
+ return f"User {username} ditambahkan", show_users()
106
+
107
+ def delete_user(username):
108
+ global users_df
109
+ username = username.strip().upper()
110
+ if username == "ADMIN":
111
+ return "ADMIN tidak boleh dihapus", show_users()
112
+ users_df = users_df[users_df["USERNAME"] != username].reset_index(drop=True)
113
+ save_data() # Simpan setelah update user
114
+ return f"User {username} dihapus", show_users()
115
+
116
+ def show_users():
117
+ return users_df.copy()
118
+
119
+ def show_guide():
120
+ return """
121
+
122
+ ### Panduan Penggunaan Aplikasi
123
+
124
+
125
+ 1.
126
+ **Login**
127
+
128
+
129
+ - Gunakan username dan password untuk masuk.
130
+
131
+
132
+ 2.
133
+ **Input Data**
134
+
135
+
136
+ - Lihat data aktif.
137
+
138
+ - Input data baru dengan kolom lengkap.
139
+
140
+ - Pilih baris dan klik "Delete Selected Rows" untuk tandai delete.
141
+
142
+
143
+ 3.
144
+ **Manajemen User**
145
+
146
+
147
+ - Tambah dan hapus user (kecuali ADMIN).
148
+
149
+
150
+ 4.
151
+ **Data yang dihapus tidak benar-benar dihapus**, hanya ditandai `REMARK = DELETE`. """
152
+
153
+ # ======= UI Layout =======
154
+
155
+ with gr.Blocks() as app:
156
+ gr.Markdown("## Login")
157
+ login_box = gr.Column(visible=True)
158
+ with login_box:
159
+ user = gr.Textbox(label="Username")
160
+ pw = gr.Textbox(label="Password", type="password")
161
+ btn_login = gr.Button("Login")
162
+ login_msg = gr.Textbox(visible=True, interactive=False, show_label=False)
163
+
164
+ tab_section = gr.Tabs(visible=False)
165
+ with tab_section:
166
+ with gr.Tab("Input Data"):
167
+ gr.Markdown("### Data Aktif")
168
+ df_list = gr.Dataframe(
169
+ label="List Data Aktif",
170
+ interactive=False,
171
+ column_widths=["auto"]*7,
172
+ wrap=True,
173
+ show_copy_button=True,
174
+ show_download_button=True,
175
+ show_fullscreen_button=True,
176
+ show_search=True,
177
+ show_row_numbers=True,
178
+ pinned_columns=["USERNAME"]
179
+ )
180
+ selected_df = gr.Dataframe(visible=False)
181
+ gr.Line()
182
+ gr.Markdown("### Input Data Baru")
183
+ df_input = gr.Dataframe(
184
+ headers=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"],
185
+ row_count=5,
186
+ col_count=(7, "fixed"),
187
+ label="Form Input"
188
+ )
189
+ btn_submit = gr.Button("Submit Data")
190
+ btn_delete = gr.Button("Delete Selected Rows")
191
+ delete_msg = gr.Textbox(visible=True, interactive=False, show_label=False)
192
+
193
+ with gr.Tab("User Management"):
194
+ gr.Markdown("### Kelola User")
195
+ new_user = gr.Textbox(label="New Username")
196
+ new_pass = gr.Textbox(label="New Password")
197
+ btn_add = gr.Button("Add User")
198
+ del_user = gr.Textbox(label="Delete Username")
199
+ btn_del = gr.Button("Delete User")
200
+ user_msg = gr.Textbox(visible=True, interactive=False, show_label=False)
201
+ user_table = gr.Dataframe(label="User List", interactive=False)
202
+
203
+ with gr.Tab("User Guide"):
204
+ gr.Markdown(show_guide())
205
+
206
+ # ==== Events ====
207
+ btn_login.click(fn=login, inputs=[user, pw], outputs=[login_msg, login_box, tab_section, df_list, user_table])
208
+ btn_submit.click(fn=bulk_submit, inputs=[df_input], outputs=[df_list])
209
+ df_list.select(fn=lambda df, evt: df.iloc[[evt.index]] if evt.index is not None else pd.DataFrame(),
210
+ inputs=[df_list], outputs=[selected_df])
211
+ btn_delete.click(fn=delete_selected_rows, inputs=[selected_df], outputs=[delete_msg, df_list])
212
+ btn_add.click(fn=add_user, inputs=[new_user, new_pass], outputs=[user_msg, user_table])
213
+ btn_del.click(fn=delete_user, inputs=[del_user], outputs=[user_msg, user_table])
214
+
215
+ app.launch(auth=lambda u, p: (u.upper(), p) in zip(users_df["USERNAME"], users_df["PASSWORD"]))