diff --git a/bank_managment_system/QTFrontend.py b/bank_managment_system/QTFrontend.py index 443276df1fe..465de612842 100644 --- a/bank_managment_system/QTFrontend.py +++ b/bank_managment_system/QTFrontend.py @@ -4,6 +4,20 @@ import backend backend.connect_database() employee_data = None +# Page Constants (for reference) +HOME_PAGE = 0 +ADMIN_PAGE = 1 +EMPLOYEE_PAGE = 2 +ADMIN_MENU_PAGE = 3 +ADD_EMPLOYEE_PAGE = 4 +UPDATE_EMPLOYEE_PAGE1 = 5 +UPDATE_EMPLOYEE_PAGE2 = 6 +EMPLOYEE_LIST_PAGE = 7 +ADMIN_TOTAL_MONEY = 8 +# ------------------------------------------------------------------------------------------------------------- +# === Reusable UI Component Functions === +# ------------------------------------------------------------------------------------------------------------- + def create_styled_frame(parent, min_size=None, style=""): """Create a styled QFrame with optional minimum size and custom style.""" frame = QtWidgets.QFrame(parent) @@ -133,7 +147,23 @@ def on_reject(): button_box.rejected.connect(on_reject) dialog.exec_() +# ------------------------------------------------------------------------------------------------------------- +# === Page Creation Functions == +# ------------------------------------------------------------------------------------------------------------- +def create_page_with_header(parent, title_text): + """Create a page with a styled header and return the page + main layout.""" + page = QtWidgets.QWidget(parent) + main_layout = QtWidgets.QVBoxLayout(page) + main_layout.setContentsMargins(20, 20, 20, 20) + main_layout.setSpacing(20) + header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") + header_layout = QtWidgets.QVBoxLayout(header_frame) + title_label = create_styled_label(header_frame, title_text, font_size=30) + header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) + + main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) + return page, main_layout def get_employee_name(parent, name_field_text="Enter Employee Name"): page, main_layout = create_page_with_header(parent, "Employee Data Update") @@ -170,7 +200,7 @@ def on_search_button_clicked(): cur.execute("SELECT * FROM staff WHERE name = ?", (entered_name,)) employee_data = cur.fetchone() print(f"Employee Data: {employee_data}") - parent.setCurrentIndex(6) + parent.setCurrentIndex(UPDATE_EMPLOYEE_PAGE2) # if employee_data: # QtWidgets.QMessageBox.information(parent, "Employee Found", @@ -191,7 +221,7 @@ def on_search_button_clicked(): def create_login_page(parent ,title, name_field_text="Name :", password_field_text="Password :", submit_text="Submit",): """Create a login page with a title, name and password fields, and a submit button.""" - page, main_layout = create_page_with_header(parent, "Admin Menu") + page, main_layout = create_page_with_header(parent, title) # Content frame content_frame = create_styled_frame(page) @@ -293,21 +323,6 @@ def create_home_page(parent, on_admin_clicked, on_employee_clicked, on_exit_clic return page -def create_page_with_header(parent, title_text): - """Create a page with a styled header and return the page + main layout.""" - page = QtWidgets.QWidget(parent) - main_layout = QtWidgets.QVBoxLayout(page) - main_layout.setContentsMargins(20, 20, 20, 20) - main_layout.setSpacing(20) - - header_frame = create_styled_frame(page, style="background-color: #ffffff; border-radius: 10px; padding: 10px;") - header_layout = QtWidgets.QVBoxLayout(header_frame) - title_label = create_styled_label(header_frame, title_text, font_size=30) - header_layout.addWidget(title_label, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) - - main_layout.addWidget(header_frame, 0, QtCore.Qt.AlignTop) - return page, main_layout - def create_admin_menu_page(parent): page, main_layout = create_page_with_header(parent, "Admin Menu") @@ -342,7 +357,7 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool form_frame = create_styled_frame(content_frame, min_size=(340, 200), style="background-color: #ffffff; border-radius: 15px; padding: 10px;") form_layout = QtWidgets.QVBoxLayout(form_frame) - form_layout.setSpacing(20) + form_layout.setSpacing(10) # Define input fields fields = ["Name :", "Password :", "Salary :", "Position :"] @@ -378,10 +393,141 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool form_layout.addWidget(button_frame) content_layout.addWidget(form_frame, 0, QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) main_layout.addWidget(content_frame) + back_btn = QtWidgets.QPushButton("Back", content_frame) + back_btn.setStyleSheet(""" + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) + back_btn.clicked.connect(lambda: parent.setCurrentIndex(ADMIN_MENU_PAGE)) + main_layout.addWidget(back_btn, 0,alignment=QtCore.Qt.AlignLeft) if update_btn: return page, name_edit, password_edit, salary_edit, position_edit, update_button else: return page, name_edit, password_edit, salary_edit, position_edit, submit_button # Unpack as name_edit, password_edit, etc. + +def show_employee_list_page(parent, title): + page, main_layout = create_page_with_header(parent, title) + + content_frame = create_styled_frame(page, style="background-color: #f9f9f9; border-radius: 10px; padding: 15px;") + content_frame.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding) + content_layout = QtWidgets.QVBoxLayout(content_frame) + + # Table frame + table_frame = create_styled_frame(content_frame, style="background-color: #ffffff; border-radius: 8px; padding: 10px;") + table_layout = QtWidgets.QVBoxLayout(table_frame) + table_layout.setSpacing(0) + + # Header row + header_frame = create_styled_frame(table_frame, style="background-color: #f5f5f5; ; border-radius: 8px 8px 0 0; padding: 10px;") + header_layout = QtWidgets.QHBoxLayout(header_frame) + header_layout.setContentsMargins(10, 5, 10, 5) + headers = ["Name", "Position", "Salary"] + for i, header in enumerate(headers): + header_label = QtWidgets.QLabel(header, header_frame) + header_label.setStyleSheet("font-weight: bold; font-size: 14px; color: #333333; padding: 0px; margin: 0px;") + if i == 2: # Right-align salary header + header_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + else: + header_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + header_layout.addWidget(header_label, 1 if i < 2 else 0) # Stretch name and position, not salary + table_layout.addWidget(header_frame) + + # Employee rows + employees = backend.show_employees_for_update() + for row, employee in enumerate(employees): + row_frame = create_styled_frame(table_frame, style=f"background-color: {'#fafafa' if row % 2 else '#ffffff'}; padding: 8px;") + row_layout = QtWidgets.QHBoxLayout(row_frame) + row_layout.setContentsMargins(10, 5, 10, 5) + + # Name + name_label = QtWidgets.QLabel(employee[0], row_frame) + name_label.setStyleSheet("font-size: 14px; color: #333333; padding: 0px; margin: 0px;") + name_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + row_layout.addWidget(name_label, 1) + + # Position + position_label = QtWidgets.QLabel(employee[3], row_frame) + position_label.setStyleSheet("font-size: 14px; color: #333333; padding: 0px; margin: 0px;") + position_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) + row_layout.addWidget(position_label, 1) + + # Salary (formatted as currency) + salary_label = QtWidgets.QLabel(f"${float(employee[2]):,.2f}", row_frame) + salary_label.setStyleSheet("font-size: 14px; color: #333333; padding: 0px; margin: 0px;") + salary_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + row_layout.addWidget(salary_label, 0) + + table_layout.addWidget(row_frame) + + # Add stretch to prevent rows from expanding vertically + table_layout.addStretch() + + # Back button + back_button = QtWidgets.QPushButton("Back", content_frame) + back_button.setStyleSheet(""" + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) + back_button.clicked.connect(lambda: parent.setCurrentIndex(ADMIN_MENU_PAGE)) + + content_layout.addWidget(table_frame) + main_layout.addWidget(back_button, alignment=QtCore.Qt.AlignLeft) + main_layout.addWidget(content_frame) + + return page +def show_total_money(parent, title): + page, main_layout = create_page_with_header(parent, title) + + content_frame = create_styled_frame(page, style="background-color: #f9f9f9; border-radius: 10px; padding: 15px;") + content_layout = QtWidgets.QVBoxLayout(content_frame) + content_layout.setProperty("spacing", 10) + all = backend.all_money() + + # Total money label + total_money_label = QtWidgets.QLabel(f"Total Money: ${all}", content_frame) + total_money_label.setStyleSheet("font-size: 24px; font-weight: bold; color: #333333;") + content_layout.addWidget(total_money_label, alignment=QtCore.Qt.AlignCenter) + # Back button + back_button = QtWidgets.QPushButton("Back", content_frame) + back_button.setStyleSheet(""" + QPushButton { + background-color: #6c757d; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-size: 14px; + } + QPushButton:hover { + background-color: #5a6268; + } + """) + back_button.clicked.connect(lambda: parent.setCurrentIndex(ADMIN_MENU_PAGE)) + content_layout.addWidget(back_button, alignment=QtCore.Qt.AlignCenter) + main_layout.addWidget(content_frame) + return page + +# ------------------------------------------------------------------------------------------------------------- +# === Main Window Setup === +# ------------------------------------------------------------------------------------------------------------- def setup_main_window(main_window): """Set up the main window with a stacked widget containing home, admin, and employee pages.""" @@ -396,10 +542,10 @@ def setup_main_window(main_window): # Create pages def switch_to_admin(): - stacked_widget.setCurrentIndex(1) + stacked_widget.setCurrentIndex(ADMIN_PAGE) def switch_to_employee(): - stacked_widget.setCurrentIndex(2) + stacked_widget.setCurrentIndex(EMPLOYEE_PAGE) def exit_app(): QtWidgets.QApplication.quit() @@ -410,7 +556,7 @@ def admin_login_menu_page(name, password): success = backend.check_admin(name, password) if success: QtWidgets.QMessageBox.information(stacked_widget, "Login Successful", f"Welcome, {name}!") - stacked_widget.setCurrentIndex(3) + stacked_widget.setCurrentIndex(ADMIN_MENU_PAGE) else: QtWidgets.QMessageBox.warning(stacked_widget, "Login Failed", "Incorrect name or password.") except Exception as e: @@ -446,15 +592,6 @@ def update_employee_data(name, password, salary, position, name_to_update): except: show_popup_message(stacked_widget,"Please fill in all fields",3) - def fetch_employee_data(name): - try: - cur = backend.cur - cur.execute("SELECT * FROM staff WHERE name = ?", (name,)) - employee_data = cur.fetchone() - return employee_data - except: - print("Error fetching employee data") - return None # Create Home Page @@ -488,9 +625,11 @@ def fetch_employee_data(name): stacked_widget ) - add_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(4)) - update_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(5)) - + add_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(ADD_EMPLOYEE_PAGE)) + update_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(UPDATE_EMPLOYEE_PAGE1)) + list_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(EMPLOYEE_LIST_PAGE)) + back_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(HOME_PAGE)) + money_button.clicked.connect(lambda: stacked_widget.setCurrentIndex(ADMIN_TOTAL_MONEY)) # Create Add Employee Page add_employee_page, emp_name, emp_password, emp_salary, emp_position, emp_submit = create_add_employee_page( stacked_widget, @@ -498,25 +637,25 @@ def fetch_employee_data(name): ) # Update Employee Page - update_employee_page1 = get_employee_name(stacked_widget) + u_employee_page1 = get_employee_name(stacked_widget) # apply the update_employee_data function to the submit button - update_employee_page2 ,update_employee_name, update_employee_password, update_employee_salary, update_employee_position,update_employee_update = create_add_employee_page(stacked_widget,"Update Employee Details",update_btn=True) + u_employee_page2 ,u_employee_name, u_employee_password, u_employee_salary, u_employee_position,u_employee_update = create_add_employee_page(stacked_widget,"Update Employee Details",update_btn=True) def populate_employee_data(): global employee_data if employee_data: print("employee_data is not None") - update_employee_name.setText(str(employee_data[0])) # Name - update_employee_password.setText(str(employee_data[1])) # Password - update_employee_salary.setText(str(employee_data[2])) # Salary - update_employee_position.setText(str(employee_data[3])) # Position + u_employee_name.setText(str(employee_data[0])) # Name + u_employee_password.setText(str(employee_data[1])) # Password + u_employee_salary.setText(str(employee_data[2])) # Salary + u_employee_position.setText(str(employee_data[3])) # Position else: # Clear fields if no employee data is available print("employee_data is None") - update_employee_name.clear() - update_employee_password.clear() - update_employee_salary.clear() - update_employee_position.clear() + u_employee_name.clear() + u_employee_password.clear() + u_employee_salary.clear() + u_employee_position.clear() QtWidgets.QMessageBox.warning(stacked_widget, "No Data", "No employee data available to display.") def on_page_changed(index): if index == 6: # update_employee_page2 is at index 6 @@ -548,17 +687,16 @@ def update_employee_data(name, password, salary, position, name_to_update): show_popup_message(stacked_widget, "Employee updated successfully.", 3, False) except Exception as e: show_popup_message(stacked_widget, f"Error updating employee: {str(e)}", 5) - update_employee_update.clicked.connect( + u_employee_update.clicked.connect( lambda: update_employee_data( - update_employee_name.text().strip(), - update_employee_password.text().strip(), - update_employee_salary.text().strip(), - update_employee_position.text().strip(), + u_employee_name.text().strip(), + u_employee_password.text().strip(), + u_employee_salary.text().strip(), + u_employee_position.text().strip(), employee_data[0] if employee_data else "" ) ) - emp_submit.clicked.connect( lambda: add_employee_form_submit( @@ -568,13 +706,15 @@ def update_employee_data(name, password, salary, position, name_to_update): emp_position.text() ) ) - + # show employee list page + employee_list_page = show_employee_list_page(stacked_widget,"Employee List") + # Create Employee Login Page employee_page, employee_name, employee_password, employee_submit = create_login_page( stacked_widget, title="Employee Login" ) - + admin_total_money = show_total_money(stacked_widget,"Total Money") # Add pages to stacked widget stacked_widget.addWidget(home_page)#0 @@ -582,14 +722,18 @@ def update_employee_data(name, password, salary, position, name_to_update): stacked_widget.addWidget(employee_page)#2 stacked_widget.addWidget(admin_menu_page)#3 stacked_widget.addWidget(add_employee_page)#4 - stacked_widget.addWidget(update_employee_page1)#5 - stacked_widget.addWidget(update_employee_page2)#6 + stacked_widget.addWidget(u_employee_page1)#5 + stacked_widget.addWidget(u_employee_page2)#6 + stacked_widget.addWidget(employee_list_page)#7 + stacked_widget.addWidget(admin_total_money)#8 + + main_layout.addWidget(stacked_widget) main_window.setCentralWidget(central_widget) # Set initial page - stacked_widget.setCurrentIndex(5) + stacked_widget.setCurrentIndex(EMPLOYEE_PAGE) return stacked_widget, { "admin_name": admin_name, @@ -611,6 +755,7 @@ def main(): main_window.show() sys.exit(app.exec_()) +# ------------------------------------------------------------------------------------------------------------- if __name__ == "__main__": main()