From 045272df70d0f0253befb1da5bc4cb57a7aad0b5 Mon Sep 17 00:00:00 2001 From: NguyenND Date: Wed, 31 Dec 2025 15:38:50 -0500 Subject: [PATCH] Update attendance report page, filter employee by ID or Name --- app.py | 67 +++++++++------ static/css/attendance.css | 85 +++++++++++++++++++ templates/attendance_report.html | 137 +++++++++++++++++++++++++++++-- 3 files changed, 255 insertions(+), 34 deletions(-) diff --git a/app.py b/app.py index a8c35c1..3e136f2 100644 --- a/app.py +++ b/app.py @@ -4706,6 +4706,18 @@ def attendance_report(): employee_filter = request.args.get('employee', '') project_filter = request.args.get('project', '') + # Get employee display name for filter if employee ID is provided + employee_display_name = '' + if employee_filter: + try: + employee = Employee.query.filter_by(id=int(employee_filter)).first() + if employee: + employee_display_name = f"{employee.lastName}, {employee.firstName}" + else: + employee_display_name = f"ID: {employee_filter}" + except (ValueError, TypeError): + employee_display_name = employee_filter + # ============================================================ # PROJECT MANAGER ACCESS CONTROL # ============================================================ @@ -4757,19 +4769,21 @@ def attendance_report(): # Return empty template return render_template('attendance_report.html', - attendance_records=[], - locations=[], - projects=[], - stats=empty_stats, - date_from=date_from, - date_to=date_to, - location_filter=location_filter, - employee_filter=employee_filter, - project_filter=project_filter, - today_date=datetime.now().strftime('%Y-%m-%d'), - current_date_formatted=datetime.now().strftime('%B %d'), - has_location_accuracy_feature=has_location_accuracy, - user_role=user_role) + attendance_records=[], + locations=[], + projects=[], + stats=empty_stats, + date_from=date_from, + date_to=date_to, + location_filter=location_filter, + employee_filter=employee_filter, + employee_display_name=employee_display_name, + project_filter=project_filter, + today_date=datetime.now().strftime('%Y-%m-%d'), + current_date_formatted=datetime.now().strftime('%B %d'), + has_location_accuracy_feature=has_location_accuracy, + user_role=user_role) + # ============================================================ # END: PROJECT MANAGER ACCESS CONTROL # ============================================================ @@ -5115,19 +5129,20 @@ def attendance_report(): print(f"✅ Stats object: {stats}") return render_template('attendance_report.html', - attendance_records=processed_records, - locations=locations, - projects=projects, - stats=stats, - date_from=date_from, - date_to=date_to, - location_filter=location_filter, - employee_filter=employee_filter, - project_filter=project_filter, - today_date=today_date, - current_date_formatted=current_date_formatted, - has_location_accuracy_feature=has_location_accuracy, - user_role=user_role) + attendance_records=processed_records, + locations=locations, + projects=projects, + stats=stats, + date_from=date_from, + date_to=date_to, + location_filter=location_filter, + employee_filter=employee_filter, + employee_display_name=employee_display_name, + project_filter=project_filter, + today_date=datetime.now().strftime('%Y-%m-%d'), + current_date_formatted=datetime.now().strftime('%B %d'), + has_location_accuracy_feature=has_location_accuracy, + user_role=user_role) except Exception as e: print(f"❌ Error loading attendance report: {e}") diff --git a/static/css/attendance.css b/static/css/attendance.css index c7bbb2f..9fe7bd8 100644 --- a/static/css/attendance.css +++ b/static/css/attendance.css @@ -1562,4 +1562,89 @@ tr.modified-record { width: 100%; justify-content: center; } +} + +/* Employee Filter Autocomplete Styles */ +.autocomplete-container-filter { + position: relative; +} + +.autocomplete-results-filter { + position: fixed; /* CHANGED from absolute to fixed */ + background: white; + border: 1px solid #ddd; + border-top: none; + border-radius: 0 0 4px 4px; + max-height: 250px; + overflow-y: auto; + z-index: 9999; /* INCREASED z-index */ + display: none; + box-shadow: 0 4px 8px rgba(0,0,0,0.15); + margin-top: 0; +} + +.autocomplete-results-filter.show { + display: block; +} + +.autocomplete-item-filter { + padding: 0.75rem; + cursor: pointer; + border-bottom: 1px solid #f0f0f0; + transition: background-color 0.2s; +} + +.autocomplete-item-filter:hover { + background-color: #f8f9fa; +} + +.autocomplete-item-filter:last-child { + border-bottom: none; +} + +.employee-info-filter { + display: flex; + justify-content: space-between; + align-items: center; +} + +.employee-name-filter { + font-weight: 600; + color: #333; +} + +.employee-id-filter { + color: #666; + font-size: 0.9rem; +} + +.clear-employee-filter { + position: absolute; + right: 8px; + top: 50%; + transform: translateY(-50%); + background: #dc3545; + color: white; + border: none; + border-radius: 50%; + width: 24px; + height: 24px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: background-color 0.2s; + padding: 0; +} + +.clear-employee-filter:hover { + background: #c82333; +} + +.clear-employee-filter i { + font-size: 0.75rem; +} + +.filter-input { + padding-right: 35px !important; } \ No newline at end of file diff --git a/templates/attendance_report.html b/templates/attendance_report.html index 3f10b91..21aa457 100644 --- a/templates/attendance_report.html +++ b/templates/attendance_report.html @@ -127,15 +127,31 @@
-
@@ -737,4 +753,109 @@ document.addEventListener('DOMContentLoaded', function() { } }); + + {% endblock %} \ No newline at end of file