44import backend
55backend .connect_database ()
66employee_data = None
7+ # Page Constants (for reference)
8+ HOME_PAGE = 0
9+ ADMIN_PAGE = 1
10+ EMPLOYEE_PAGE = 2
11+ ADMIN_MENU_PAGE = 3
12+ ADD_EMPLOYEE_PAGE = 4
13+ UPDATE_EMPLOYEE_PAGE1 = 5
14+ UPDATE_EMPLOYEE_PAGE2 = 6
15+ EMPLOYEE_LIST_PAGE = 7
16+ ADMIN_TOTAL_MONEY = 8
17+ # -------------------------------------------------------------------------------------------------------------
18+ # === Reusable UI Component Functions ===
19+ # -------------------------------------------------------------------------------------------------------------
20+
721def create_styled_frame (parent , min_size = None , style = "" ):
822 """Create a styled QFrame with optional minimum size and custom style."""
923 frame = QtWidgets .QFrame (parent )
@@ -133,7 +147,23 @@ def on_reject():
133147 button_box .rejected .connect (on_reject )
134148
135149 dialog .exec_ ()
150+ # -------------------------------------------------------------------------------------------------------------
151+ # === Page Creation Functions ==
152+ # -------------------------------------------------------------------------------------------------------------
153+ def create_page_with_header (parent , title_text ):
154+ """Create a page with a styled header and return the page + main layout."""
155+ page = QtWidgets .QWidget (parent )
156+ main_layout = QtWidgets .QVBoxLayout (page )
157+ main_layout .setContentsMargins (20 , 20 , 20 , 20 )
158+ main_layout .setSpacing (20 )
136159
160+ header_frame = create_styled_frame (page , style = "background-color: #ffffff; border-radius: 10px; padding: 10px;" )
161+ header_layout = QtWidgets .QVBoxLayout (header_frame )
162+ title_label = create_styled_label (header_frame , title_text , font_size = 30 )
163+ header_layout .addWidget (title_label , 0 , QtCore .Qt .AlignHCenter | QtCore .Qt .AlignTop )
164+
165+ main_layout .addWidget (header_frame , 0 , QtCore .Qt .AlignTop )
166+ return page , main_layout
137167def get_employee_name (parent , name_field_text = "Enter Employee Name" ):
138168 page , main_layout = create_page_with_header (parent , "Employee Data Update" )
139169
@@ -170,7 +200,7 @@ def on_search_button_clicked():
170200 cur .execute ("SELECT * FROM staff WHERE name = ?" , (entered_name ,))
171201 employee_data = cur .fetchone ()
172202 print (f"Employee Data: { employee_data } " )
173- parent .setCurrentIndex (6 )
203+ parent .setCurrentIndex (UPDATE_EMPLOYEE_PAGE2 )
174204
175205 # if employee_data:
176206 # QtWidgets.QMessageBox.information(parent, "Employee Found",
@@ -191,7 +221,7 @@ def on_search_button_clicked():
191221
192222def create_login_page (parent ,title , name_field_text = "Name :" , password_field_text = "Password :" , submit_text = "Submit" ,):
193223 """Create a login page with a title, name and password fields, and a submit button."""
194- page , main_layout = create_page_with_header (parent , "Admin Menu" )
224+ page , main_layout = create_page_with_header (parent , title )
195225
196226 # Content frame
197227 content_frame = create_styled_frame (page )
@@ -293,21 +323,6 @@ def create_home_page(parent, on_admin_clicked, on_employee_clicked, on_exit_clic
293323
294324 return page
295325
296- def create_page_with_header (parent , title_text ):
297- """Create a page with a styled header and return the page + main layout."""
298- page = QtWidgets .QWidget (parent )
299- main_layout = QtWidgets .QVBoxLayout (page )
300- main_layout .setContentsMargins (20 , 20 , 20 , 20 )
301- main_layout .setSpacing (20 )
302-
303- header_frame = create_styled_frame (page , style = "background-color: #ffffff; border-radius: 10px; padding: 10px;" )
304- header_layout = QtWidgets .QVBoxLayout (header_frame )
305- title_label = create_styled_label (header_frame , title_text , font_size = 30 )
306- header_layout .addWidget (title_label , 0 , QtCore .Qt .AlignHCenter | QtCore .Qt .AlignTop )
307-
308- main_layout .addWidget (header_frame , 0 , QtCore .Qt .AlignTop )
309- return page , main_layout
310-
311326def create_admin_menu_page (parent ):
312327 page , main_layout = create_page_with_header (parent , "Admin Menu" )
313328
@@ -342,7 +357,7 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool
342357
343358 form_frame = create_styled_frame (content_frame , min_size = (340 , 200 ), style = "background-color: #ffffff; border-radius: 15px; padding: 10px;" )
344359 form_layout = QtWidgets .QVBoxLayout (form_frame )
345- form_layout .setSpacing (20 )
360+ form_layout .setSpacing (10 )
346361
347362 # Define input fields
348363 fields = ["Name :" , "Password :" , "Salary :" , "Position :" ]
@@ -378,10 +393,141 @@ def create_add_employee_page(parent, title, submit_text="Submit",update_btn:bool
378393 form_layout .addWidget (button_frame )
379394 content_layout .addWidget (form_frame , 0 , QtCore .Qt .AlignHCenter | QtCore .Qt .AlignVCenter )
380395 main_layout .addWidget (content_frame )
396+ back_btn = QtWidgets .QPushButton ("Back" , content_frame )
397+ back_btn .setStyleSheet ("""
398+ QPushButton {
399+ background-color: #6c757d;
400+ color: white;
401+ border: none;
402+ border-radius: 4px;
403+ padding: 8px 16px;
404+ font-size: 14px;
405+ }
406+ QPushButton:hover {
407+ background-color: #5a6268;
408+ }
409+ """ )
410+ back_btn .clicked .connect (lambda : parent .setCurrentIndex (ADMIN_MENU_PAGE ))
411+ main_layout .addWidget (back_btn , 0 ,alignment = QtCore .Qt .AlignLeft )
381412 if update_btn :
382413 return page , name_edit , password_edit , salary_edit , position_edit , update_button
383414 else :
384415 return page , name_edit , password_edit , salary_edit , position_edit , submit_button # Unpack as name_edit, password_edit, etc.
416+
417+ def show_employee_list_page (parent , title ):
418+ page , main_layout = create_page_with_header (parent , title )
419+
420+ content_frame = create_styled_frame (page , style = "background-color: #f9f9f9; border-radius: 10px; padding: 15px;" )
421+ content_frame .setSizePolicy (QtWidgets .QSizePolicy .Preferred , QtWidgets .QSizePolicy .Expanding )
422+ content_layout = QtWidgets .QVBoxLayout (content_frame )
423+
424+ # Table frame
425+ table_frame = create_styled_frame (content_frame , style = "background-color: #ffffff; border-radius: 8px; padding: 10px;" )
426+ table_layout = QtWidgets .QVBoxLayout (table_frame )
427+ table_layout .setSpacing (0 )
428+
429+ # Header row
430+ header_frame = create_styled_frame (table_frame , style = "background-color: #f5f5f5; ; border-radius: 8px 8px 0 0; padding: 10px;" )
431+ header_layout = QtWidgets .QHBoxLayout (header_frame )
432+ header_layout .setContentsMargins (10 , 5 , 10 , 5 )
433+ headers = ["Name" , "Position" , "Salary" ]
434+ for i , header in enumerate (headers ):
435+ header_label = QtWidgets .QLabel (header , header_frame )
436+ header_label .setStyleSheet ("font-weight: bold; font-size: 14px; color: #333333; padding: 0px; margin: 0px;" )
437+ if i == 2 : # Right-align salary header
438+ header_label .setAlignment (QtCore .Qt .AlignRight | QtCore .Qt .AlignVCenter )
439+ else :
440+ header_label .setAlignment (QtCore .Qt .AlignLeft | QtCore .Qt .AlignVCenter )
441+ header_layout .addWidget (header_label , 1 if i < 2 else 0 ) # Stretch name and position, not salary
442+ table_layout .addWidget (header_frame )
443+
444+ # Employee rows
445+ employees = backend .show_employees_for_update ()
446+ for row , employee in enumerate (employees ):
447+ row_frame = create_styled_frame (table_frame , style = f"background-color: { '#fafafa' if row % 2 else '#ffffff' } ; padding: 8px;" )
448+ row_layout = QtWidgets .QHBoxLayout (row_frame )
449+ row_layout .setContentsMargins (10 , 5 , 10 , 5 )
450+
451+ # Name
452+ name_label = QtWidgets .QLabel (employee [0 ], row_frame )
453+ name_label .setStyleSheet ("font-size: 14px; color: #333333; padding: 0px; margin: 0px;" )
454+ name_label .setAlignment (QtCore .Qt .AlignLeft | QtCore .Qt .AlignVCenter )
455+ row_layout .addWidget (name_label , 1 )
456+
457+ # Position
458+ position_label = QtWidgets .QLabel (employee [3 ], row_frame )
459+ position_label .setStyleSheet ("font-size: 14px; color: #333333; padding: 0px; margin: 0px;" )
460+ position_label .setAlignment (QtCore .Qt .AlignLeft | QtCore .Qt .AlignVCenter )
461+ row_layout .addWidget (position_label , 1 )
462+
463+ # Salary (formatted as currency)
464+ salary_label = QtWidgets .QLabel (f"${ float (employee [2 ]):,.2f} " , row_frame )
465+ salary_label .setStyleSheet ("font-size: 14px; color: #333333; padding: 0px; margin: 0px;" )
466+ salary_label .setAlignment (QtCore .Qt .AlignRight | QtCore .Qt .AlignVCenter )
467+ row_layout .addWidget (salary_label , 0 )
468+
469+ table_layout .addWidget (row_frame )
470+
471+ # Add stretch to prevent rows from expanding vertically
472+ table_layout .addStretch ()
473+
474+ # Back button
475+ back_button = QtWidgets .QPushButton ("Back" , content_frame )
476+ back_button .setStyleSheet ("""
477+ QPushButton {
478+ background-color: #6c757d;
479+ color: white;
480+ border: none;
481+ border-radius: 4px;
482+ padding: 8px 16px;
483+ font-size: 14px;
484+ }
485+ QPushButton:hover {
486+ background-color: #5a6268;
487+ }
488+ """ )
489+ back_button .clicked .connect (lambda : parent .setCurrentIndex (ADMIN_MENU_PAGE ))
490+
491+ content_layout .addWidget (table_frame )
492+ main_layout .addWidget (back_button , alignment = QtCore .Qt .AlignLeft )
493+ main_layout .addWidget (content_frame )
494+
495+ return page
496+ def show_total_money (parent , title ):
497+ page , main_layout = create_page_with_header (parent , title )
498+
499+ content_frame = create_styled_frame (page , style = "background-color: #f9f9f9; border-radius: 10px; padding: 15px;" )
500+ content_layout = QtWidgets .QVBoxLayout (content_frame )
501+ content_layout .setProperty ("spacing" , 10 )
502+ all = backend .all_money ()
503+
504+ # Total money label
505+ total_money_label = QtWidgets .QLabel (f"Total Money: ${ all } " , content_frame )
506+ total_money_label .setStyleSheet ("font-size: 24px; font-weight: bold; color: #333333;" )
507+ content_layout .addWidget (total_money_label , alignment = QtCore .Qt .AlignCenter )
508+ # Back button
509+ back_button = QtWidgets .QPushButton ("Back" , content_frame )
510+ back_button .setStyleSheet ("""
511+ QPushButton {
512+ background-color: #6c757d;
513+ color: white;
514+ border: none;
515+ border-radius: 4px;
516+ padding: 8px 16px;
517+ font-size: 14px;
518+ }
519+ QPushButton:hover {
520+ background-color: #5a6268;
521+ }
522+ """ )
523+ back_button .clicked .connect (lambda : parent .setCurrentIndex (ADMIN_MENU_PAGE ))
524+ content_layout .addWidget (back_button , alignment = QtCore .Qt .AlignCenter )
525+ main_layout .addWidget (content_frame )
526+ return page
527+
528+ # -------------------------------------------------------------------------------------------------------------
529+ # === Main Window Setup ===
530+ # -------------------------------------------------------------------------------------------------------------
385531
386532def setup_main_window (main_window ):
387533 """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):
396542
397543 # Create pages
398544 def switch_to_admin ():
399- stacked_widget .setCurrentIndex (1 )
545+ stacked_widget .setCurrentIndex (ADMIN_PAGE )
400546
401547 def switch_to_employee ():
402- stacked_widget .setCurrentIndex (2 )
548+ stacked_widget .setCurrentIndex (EMPLOYEE_PAGE )
403549
404550 def exit_app ():
405551 QtWidgets .QApplication .quit ()
@@ -410,7 +556,7 @@ def admin_login_menu_page(name, password):
410556 success = backend .check_admin (name , password )
411557 if success :
412558 QtWidgets .QMessageBox .information (stacked_widget , "Login Successful" , f"Welcome, { name } !" )
413- stacked_widget .setCurrentIndex (3 )
559+ stacked_widget .setCurrentIndex (ADMIN_MENU_PAGE )
414560 else :
415561 QtWidgets .QMessageBox .warning (stacked_widget , "Login Failed" , "Incorrect name or password." )
416562 except Exception as e :
@@ -446,15 +592,6 @@ def update_employee_data(name, password, salary, position, name_to_update):
446592 except :
447593 show_popup_message (stacked_widget ,"Please fill in all fields" ,3 )
448594
449- def fetch_employee_data (name ):
450- try :
451- cur = backend .cur
452- cur .execute ("SELECT * FROM staff WHERE name = ?" , (name ,))
453- employee_data = cur .fetchone ()
454- return employee_data
455- except :
456- print ("Error fetching employee data" )
457- return None
458595
459596
460597 # Create Home Page
@@ -488,35 +625,37 @@ def fetch_employee_data(name):
488625 stacked_widget
489626 )
490627
491- add_button .clicked .connect (lambda : stacked_widget .setCurrentIndex (4 ))
492- update_button .clicked .connect (lambda : stacked_widget .setCurrentIndex (5 ))
493-
628+ add_button .clicked .connect (lambda : stacked_widget .setCurrentIndex (ADD_EMPLOYEE_PAGE ))
629+ update_button .clicked .connect (lambda : stacked_widget .setCurrentIndex (UPDATE_EMPLOYEE_PAGE1 ))
630+ list_button .clicked .connect (lambda : stacked_widget .setCurrentIndex (EMPLOYEE_LIST_PAGE ))
631+ back_button .clicked .connect (lambda : stacked_widget .setCurrentIndex (HOME_PAGE ))
632+ money_button .clicked .connect (lambda : stacked_widget .setCurrentIndex (ADMIN_TOTAL_MONEY ))
494633 # Create Add Employee Page
495634 add_employee_page , emp_name , emp_password , emp_salary , emp_position , emp_submit = create_add_employee_page (
496635 stacked_widget ,
497636 title = "Add Employee"
498637 )
499638
500639 # Update Employee Page
501- update_employee_page1 = get_employee_name (stacked_widget )
640+ u_employee_page1 = get_employee_name (stacked_widget )
502641 # apply the update_employee_data function to the submit button
503642
504- 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 )
643+ 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 )
505644 def populate_employee_data ():
506645 global employee_data
507646 if employee_data :
508647 print ("employee_data is not None" )
509- update_employee_name .setText (str (employee_data [0 ])) # Name
510- update_employee_password .setText (str (employee_data [1 ])) # Password
511- update_employee_salary .setText (str (employee_data [2 ])) # Salary
512- update_employee_position .setText (str (employee_data [3 ])) # Position
648+ u_employee_name .setText (str (employee_data [0 ])) # Name
649+ u_employee_password .setText (str (employee_data [1 ])) # Password
650+ u_employee_salary .setText (str (employee_data [2 ])) # Salary
651+ u_employee_position .setText (str (employee_data [3 ])) # Position
513652 else :
514653 # Clear fields if no employee data is available
515654 print ("employee_data is None" )
516- update_employee_name .clear ()
517- update_employee_password .clear ()
518- update_employee_salary .clear ()
519- update_employee_position .clear ()
655+ u_employee_name .clear ()
656+ u_employee_password .clear ()
657+ u_employee_salary .clear ()
658+ u_employee_position .clear ()
520659 QtWidgets .QMessageBox .warning (stacked_widget , "No Data" , "No employee data available to display." )
521660 def on_page_changed (index ):
522661 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):
548687 show_popup_message (stacked_widget , "Employee updated successfully." , 3 , False )
549688 except Exception as e :
550689 show_popup_message (stacked_widget , f"Error updating employee: { str (e )} " , 5 )
551- update_employee_update .clicked .connect (
690+ u_employee_update .clicked .connect (
552691 lambda : update_employee_data (
553- update_employee_name .text ().strip (),
554- update_employee_password .text ().strip (),
555- update_employee_salary .text ().strip (),
556- update_employee_position .text ().strip (),
692+ u_employee_name .text ().strip (),
693+ u_employee_password .text ().strip (),
694+ u_employee_salary .text ().strip (),
695+ u_employee_position .text ().strip (),
557696 employee_data [0 ] if employee_data else ""
558697 )
559698 )
560699
561-
562700
563701 emp_submit .clicked .connect (
564702 lambda : add_employee_form_submit (
@@ -568,28 +706,34 @@ def update_employee_data(name, password, salary, position, name_to_update):
568706 emp_position .text ()
569707 )
570708 )
571-
709+ # show employee list page
710+ employee_list_page = show_employee_list_page (stacked_widget ,"Employee List" )
711+
572712 # Create Employee Login Page
573713 employee_page , employee_name , employee_password , employee_submit = create_login_page (
574714 stacked_widget ,
575715 title = "Employee Login"
576716 )
577-
717+ admin_total_money = show_total_money ( stacked_widget , "Total Money" )
578718
579719 # Add pages to stacked widget
580720 stacked_widget .addWidget (home_page )#0
581721 stacked_widget .addWidget (admin_page )#1
582722 stacked_widget .addWidget (employee_page )#2
583723 stacked_widget .addWidget (admin_menu_page )#3
584724 stacked_widget .addWidget (add_employee_page )#4
585- stacked_widget .addWidget (update_employee_page1 )#5
586- stacked_widget .addWidget (update_employee_page2 )#6
725+ stacked_widget .addWidget (u_employee_page1 )#5
726+ stacked_widget .addWidget (u_employee_page2 )#6
727+ stacked_widget .addWidget (employee_list_page )#7
728+ stacked_widget .addWidget (admin_total_money )#8
729+
730+
587731
588732 main_layout .addWidget (stacked_widget )
589733 main_window .setCentralWidget (central_widget )
590734
591735 # Set initial page
592- stacked_widget .setCurrentIndex (5 )
736+ stacked_widget .setCurrentIndex (EMPLOYEE_PAGE )
593737
594738 return stacked_widget , {
595739 "admin_name" : admin_name ,
@@ -611,6 +755,7 @@ def main():
611755
612756 main_window .show ()
613757 sys .exit (app .exec_ ())
758+ # -------------------------------------------------------------------------------------------------------------
614759
615760if __name__ == "__main__" :
616761 main ()
0 commit comments