Spaces:
Running
Running
1.1 Purpose This System Design Document (SDD) provides a technical blueprint for the Civil Service Management System (CSMS) phase 1, detailing its architecture, components, data models, interfaces, and deployment strategies. It guides developers, testers, and stakeholders to ensure consistent implementation, aligning with the Software Requirements Specification (SRS) and Inception Report provided. 1.2 Scope The CSMS phase 1 automates HR operations for the CSC, covering the following modules: • Employee Confirmation • Leave Without Pay (LWOP) • Promotion • Complaints • Change of Cadre • Retirement • Resignation (Employee) • Service Extension • Termination • Dismissal • Authentication & Authorization • Dashboard • Employee Profile Management • Reports & Analytics • Audit Trail Out-of-Scope: • Payroll and pension system integration. • Recruitment modules. • Mobile app development (planned for phase 2). The system integrates solely with HRIMS to fetch employee data, with no connections to payroll or pension systems. 1.3 Timeline The project spans from May 20, 2025, to December 9, 2025, with milestones for requirements gathering, design, development, testing, and deployment. 2. System Overview 2.1 System Description The CSMS is a web-based platform to manage the civil servant lifecycle, from confirmation to retirement or dismissal. It supports user roles (HR Officer (HRO), HR Management Officer (HRMO), Head of HR Management (HHRMD), Disciplinary Officer (DO), Employees) with role-based access control (RBAC). The system automates HR processes, provides real-time dashboards and reports, and ensures compliance through immutable audit trails. 2.2 Key Objectives • Automate HR processes (e.g., confirmations, promotions, complaints). • Provide real-time insights for decision-making. • Ensure data security, auditability, and compliance with CSC business plan. • Support scalability for 50,000+ employee records. 2.3 Key Features • Secure authentication with RBAC and multi-factor authentication (MFA). • CRUD operations for employee profiles with document uploads (PDF, ≤2MB). • Automated HR processes with approval/rejection by HHRMD/HRMO or HHRMD/DO, notifying HRO. • Real-time dashboards with role-based widgets and alerts. • Customizable reports in PDF/Excel formats with date-based filtering. • Integration with HRIMS for data fetching. • Immutable audit trails for all actions. 3. System Architecture 3.1 Architectural Style The CSMS adopts a microservices-based architecture for scalability, modularity, and maintainability, using a layered approach: • Presentation Layer: Angular 15+ frontend, WCAG 2.1 AA-compliant. • Application Layer: Spring Boot 3 (Java 17) for business logic and REST APIs. • Data Layer: PostgreSQL 14 with read replicas for high availability. • Integration Layer: Apache Camel for HRIMS integration (SOAP/REST). • Security Layer: Keycloak for OAuth 2.0/OIDC authentication and RBAC. 3.2 System Components The system is structured into layers: • Frontend: Angular 15+ with TypeScript, HTML5, CSS3, and Tailwind CSS. • Backend Services: o Authentication Service (Keycloak integration). o Employee Profile Service (CRUD operations for admin only). o Workflow Services (Confirmation, LWOP, Promotion, etc.). o Reporting Service (PDF/Excel generation). o Audit Trail Service (logging user actions). • Database: PostgreSQL 14 in a clustered configuration with read replicas. • Integration: Apache Camel for HRIMS data fetching. • Notifications: Email (SMTP) and in-system alerts for status updates and SLA breaches. Architecture Diagram PlantUML Code for Architecture Diagram @startuml skinparam titleFontSize 20 skinparam titleFontColor #00008B skinparam titleFontName Arial title System Architecture package "Presentation Layer" { [Angular 15+ Frontend] } package "Application Layer" { [Spring Boot 3 Microservices] } package "Data Layer" { [PostgreSQL 14 Database] } package "Integration Layer" { [Apache Camel] } package "Security Layer" { [Keycloak] } [Angular 15+ Frontend] -> [Spring Boot 3 Microservices] [Spring Boot 3 Microservices] -> [PostgreSQL 14 Database] [Spring Boot 3 Microservices] -> [Apache Camel] [Spring Boot 3 Microservices] -> [Keycloak] @enduml 4. Module Design Each module is a microservice with its own API endpoints, business logic, and database interactions. Below are the designs, with workflows detailed in Appendix D. 4.1 Authentication & Authorization • Purpose: Secure user access with RBAC. • Components: o Keycloak for authentication (OAuth 2.0/OIDC). o Custom RBAC for roles (HRO, HRMO, HHRMD, DO, Employee,… etc). o Password recovery via OTP (60-minute expiry). • APIs: o POST /auth/login: Authenticate user. o POST /auth/otp: Generate OTP for recovery. o GET /auth/roles: Fetch user roles and permissions. • Non-Functional: o 99.9% availability. o Login response time <1.5 seconds for 95% of users. o Audit logging of authentication attempts. 4.2 Dashboard • Purpose: Provide role-based, real-time insights and module access. • Components: o Angular components for widgets (charts, tables, alerts). o REST API for real-time data (e.g., pending requests). • APIs: o GET /dashboard/summary: Fetch pending request counts. o GET /dashboard/alerts: Fetch SLA deadline alerts. • Non-Functional: o Load time <5 seconds. o Responsive on desktop and tablet (WCAG 2.1 AA). o Data restricted by RBAC. 4.3 Employee Profile Management • Purpose: Manage employee records with CRUD operations. • Components: o Angular forms for profile creation/editing. o Spring Boot service for CRUD operations. o PostgreSQL tables for employee data and documents. • APIs: o POST /employees: Create profile. o GET /employees/{id}: Retrieve details. o PUT /employees/{id}: Update profile. o DELETE /employees/{id}: Deactivate profile. o POST /employees/search: Search by name, zan_id, or department. • Non-Functional: o Search response time <1 second for 10,000 records. o Document encryption with AES-256. 4.4 HR Workflow Modules • Modules: Confirmation, LWOP, Promotion, Change of Cadre, Retirement, Resignation, Service Extension, Termination, Dismissal. • Purpose: Automate HR processes with forms and approval mechanisms. • Components: o Angular forms for request submission with document uploads (PDF, ≤2MB). o Spring Boot service for request processing and status updates. o PostgreSQL tables for requests and documents. • APIs: o POST /{module}: Submit request (e.g., /confirmation, /termination). o GET /{module}/{id}: View request status. o PUT /{module}/{id}/approve: Approve request (HHRMD/HRMO or HHRMD/DO). o PUT /{module}/{id}/reject: Reject request with reason (HHRMD/HRMO or HHRMD/DO). • Details: See Appendix D for workflows. • Non-Functional: o Form load time <3 seconds. o Audit logging of all actions. 4.5 Complaints Module • Purpose: Allow employees to submit and track complaints which will be resolved by HHRMD or DO. • Components: o Angular form for complaint submission with category selection and evidence upload. o Spring Boot service for complaint management. o PostgreSQL tables for complaints and documents. • APIs: o POST /complaints: Submit complaint (Employee). o GET /complaints/{id}: View complaint status. o PUT /complaints/{id}/approve: Resolve complaint (HHRMD/DO). o PUT /complaints/{id}/reject: Reject complaint with reason (HHRMD/DO). • Details: See Appendix D for workflow. • Non-Functional: o Form load time <3 seconds. o Audit logging of all actions. 4.6 Reports & Analytics • Purpose: Generate customizable reports in PDF/Excel formats for HR processes, with date or date interval selection. • Components: o Frontend: Angular interface with drag-and-drop report builder, date pickers, and filters (e.g., ministry, gender). o Backend: Spring Boot service using JasperReports for PDF/Excel generation, querying PostgreSQL. o Database: PostgreSQL tables (Employee, Request, Complaint) with indexed fields. • Report Types (see Appendix F for formats): 1. Service Extension: Lists employees with extended service periods. 2. Retirement (Compulsory): Lists employees retiring at mandatory age. 3. Retirement (Voluntary): Lists employees retiring early. 4. Retirement (Illness): Lists employees retiring due to illness. 5. Leave Without Pay (LWOP): Lists employees on leave without pay. 6. Promotion in Position/Rank: Summarizes promotions by Institution. 7. Termination and Dismissal: Lists termination/dismissal cases. 8. Complaints: Lists employee complaints and resolutions. 9. Change of Cadre: Lists employees with cadre changes. 10. Employee Resignation: Lists approved resignations. 11. Confirmation of Employment: Lists confirmed employees. • APIs: o POST /reports/generate: Generate report (parameters: report_type, date_from, date_to, ministry, gender, etc.). o GET /reports/templates: List report types and fields. o GET /reports/{id}: Retrieve generated report (PDF/Excel). • Non-Functional: o Report generation time <30 seconds for 10,000 records. o Supports 100 concurrent users. o PDF/Excel files <10MB, optimized for printing. o Audit logging of report generation. 4.7 Audit Trail • Purpose: Display immutable audit logs for compliance. • Components: o Angular table for viewing logs with filters (date range, user, action). o Spring Boot service for log retrieval. • APIs: o GET /audit-logs: Retrieve logs with pagination and filtering. • Non-Functional: o Log retrieval time <5 seconds for 1-year range. 5. Data Model 5.1 Key Entities Entity Key Fields Constraints Employee employee_id (PK), full_name, zan_id, payroll_number, zssf_number, cadre, date_of_appointment, status (Confirmed/Not Confirmed), department, date_of_birth, gender, phone_number Unique zan_id, payroll_number, zssf_number User user_id (PK), username, email, role_id (FK), status (Active/Inactive) Unique username, email Role role_id (PK), role_name (e.g., HRO, HRMO, HHRMD, DO), permissions (JSONB) Unique role_name Document document_id (PK), employee_id (FK), request_id (FK), file_name, file_type (PDF), file_size (≤2MB), encrypted_content (BYTEA) File size ≤2MB Request request_id (PK), employee_id (FK), request_type (ENUM: Confirmation, LWOP, Promotion, Cadre Change, Retirement, Resignation, Service Extension, Termination, Dismissal), status (Pending, Approved, Rejected), created_by (FK), approver_id (FK), details (JSONB, e.g., start_date, reason), submission_date, decision_date Foreign keys for integrity Complaint complaint_id (PK), employee_id (FK), category (ENUM: Unconfirmed Employees, Job-Related, Other), status (Pending, Resolved, Rejected), details (JSONB), submission_date Foreign key for employee_id Audit_Log log_id (PK), user_id (FK), request_id (FK), action, timestamp, before_value (JSONB), after_value (JSONB) Immutable logs with SHA-256 signing 5.2 Entity Relationship Diagram (ERD) [Employee] --1:N--> [Document] [Employee] --1:N--> [Request] [Employee] --1:N--> [Complaint] [User] --N:1--> [Role] [User] --1:N--> [Audit_Log] [Request] --1:N--> [Audit_Log] [Complaint] --1:N--> [Audit_Log] [Request] --1:N--> [Document] PlantUML Code for ERD @startuml entity Employee { * employee_id : VARCHAR(50) <<PK>> -- full_name : VARCHAR(100) <<Not Null>> zan_id : VARCHAR(20) <<Unique, Not Null>> payroll_number : VARCHAR(20) <<Unique, Not Null>> zssf_number : VARCHAR(20) <<Unique, Not Null>> cadre : VARCHAR(50) <<Not Null>> date_of_appointment : DATE <<Not Null>> status : ENUM('Confirmed', 'Not Confirmed') <<Not Null>> department : VARCHAR(100) date_of_birth : DATE gender : ENUM('Male', 'Female') phone_number : VARCHAR(15) } entity User { * user_id : VARCHAR(50) <<PK>> -- username : VARCHAR(50) <<Unique, Not Null>> email : VARCHAR(100) <<Unique, Not Null>> password_hash : VARCHAR(256) <<Not Null>> role_id : VARCHAR(50) <<FK, Not Null>> status : ENUM('Active', 'Inactive') <<Not Null>> } entity Role { * role_id : VARCHAR(50) <<PK>> -- role_name : VARCHAR(50) <<Not Null>> permissions : JSONB <<Not Null>> } entity Document { * document_id : VARCHAR(50) <<PK>> -- employee_id : VARCHAR(50) <<FK, Not Null>> request_id : VARCHAR(50) <<FK, Nullable>> file_name : VARCHAR(100) <<Not Null>> file_type : ENUM('PDF') <<Not Null>> file_size : INTEGER <<Not Null, <=2MB>> encrypted_content : BYTEA <<Not Null>> } entity Request { * request_id : VARCHAR(50) <<PK>> -- employee_id : VARCHAR(50) <<FK, Not Null>> request_type : ENUM('Confirmation', 'LWOP', 'Promotion', 'Cadre Change', 'Retirement', 'Resignation', 'Service Extension', 'Termination', 'Dismissal') <<Not Null>> status : ENUM('Pending', 'Approved', 'Rejected') <<Not Null>> created_by : VARCHAR(50) <<FK, Not Null>> approver_id : VARCHAR(50) <<FK, Nullable>> details : JSONB submission_date : DATE <<Not Null>> decision_date : DATE } entity Complaint { * complaint_id : VARCHAR(50) <<PK>> -- employee_id : VARCHAR(50) <<FK, Not Null>> category : ENUM('Unconfirmed Employees', 'Job-Related', 'Other') <<Not Null>> status : ENUM('Pending', 'Resolved', 'Rejected') <<Not Null>> details : JSONB submission_date : DATE <<Not Null>> } entity Audit_Log { * log_id : VARCHAR(50) <<PK>> -- user_id : VARCHAR(50) <<FK, Not Null>> request_id : VARCHAR(50) <<FK, Nullable>> action : VARCHAR(100) <<Not Null>> timestamp : TIMESTAMP <<Not Null>> before_value : JSONB after_value : JSONB } Employee ||--o{ Document Employee ||--o{ Request Employee ||--o{ Complaint User }o--|| Role User ||--o{ Audit_Log Request ||--o{ Audit_Log Complaint ||--o{ Audit_Log Request ||--o{ Document @enduml 6. Interface Design 6.1 User Interface (UI) • Framework: Angular 15+ with Tailwind CSS for responsive design. • Key Screens: o Login Screen: Username/password input, OTP recovery. o Dashboard: Role-based widgets (pending requests, alerts, quick links). o Employee Profile: CRUD forms with search/filter functionality. o HR Workflow Forms: Standardized forms for each module with document upload. o Complaints: Form for submitting complaints with category selection. o Reports: Drag-and-drop interface with date pickers, ministry/gender filters, and export options (PDF/Excel). o Audit Trail: Table view of logs with filtering. • Accessibility: WCAG 2.1 AA-compliant (keyboard navigation, screen reader support). 6.2 API Design • Base URL: /api/v1 • Endpoints (examples): o GET /employees/{id}: Retrieve employee profile. o POST /confirmation: Submit confirmation request. o PUT /complaints/{id}/approve: Resolve complaint. o POST /reports/generate: Generate report. • Response Format: JSON with { "status": "success", "data": {...}, "message": "Operation completed" }. • Error Handling: HTTP status codes (400, 401, 403, 500) with descriptive messages. 7. Integration Design 7.1 HRIMS Integration • Purpose: Fetch employee data from HRIMS for synchronization. • Technology: Apache Camel for SOAP/REST connectors. • APIs: o GET /hrims/employees: Fetch employee records. • Error Handling: Fallback to CSV import/export for API failures. • Note: No integration with payroll or pension systems. 7.2 Notification System • Email: SMTP server for approvals, rejections, and SLA breaches. • In-System Alerts: Stored in PostgreSQL, displayed on Dashboard. • Triggers: o Request status changes (Approved/Rejected). o SLA breaches. 8. Security Design • Authentication: Keycloak with OAuth 2.0/OIDC, supporting username/password and MFA. • Authorization: RBAC with roles (HRO, HRMO, HHRMD, DO, Employee). • Data Protection: o AES-256 encryption for documents and sensitive fields at rest. o TLS 1.3 for data in transit. • Audit Trail: Immutable logs with SHA-256 signing. • Security Measures: o Account lockout after 5 failed login attempts (15-minute lock). o OTP for password recovery (60-minute expiry). o Regular security audits and penetration testing. 9. Non-Functional Requirements Implementation • Performance: o Database query optimization with indexing and Redis caching. o Response time <2 seconds for 95% of transactions under 1,000 concurrent users. • Availability: o 99.9% uptime with clustered PostgreSQL and failover. o Scheduled maintenance communicated in advance. • Scalability: o Supports 50,000+ employee records with read replicas. • Compliance: o Audit logs retained in WORM format for 10 years. o Adheres to CSC regulations and data privacy laws. • Usability: o Intuitive UI requiring ≤1 hour training. o Responsive design for desktop and tablet. 10. Deployment Strategy • Environment: o Development: Local /online servers for coding and testing. o Staging: Virtual machine (VM) on government’s data center server, mirroring production. o Production: Single physical server with virtualization. • Virtualization Platform: VMware ESXi or Proxmox for isolated VMs: o Frontend VM: Angular 15+, 4 vCPUs, 8GB RAM, 50GB storage. o Backend VM: Spring Boot 3, 8 vCPUs, 16GB RAM, 100GB storage. o Database VM: PostgreSQL 14, 8 vCPUs, 32GB RAM, 500GB SSD. o Security VM: Keycloak, 4 vCPUs, 8GB RAM, 50GB storage. • Deployment Process: o Rolling updates for microservices to minimize downtime. o Blue-green deployment for major releases using VM snapshots. • Backup and Recovery: o Daily backups to a separate partition, retained for 30 days. o Offsite archival for 10-year compliance. • Monitoring: o Prometheus and Grafana for system health and performance. o Alerts for CPU, memory, disk usage, and suspicious activities. • Infrastructure: o Server: ≥32 cores, ≥128GB RAM, ≥1TB SSD, redundant power supplies. o Network: Dedicated VLAN with firewall rules. 11. Testing Strategy • Unit Testing: JUnit for Spring Boot, Jest for Angular. • Integration Testing: Test API endpoints and HRIMS integration. • Performance Testing: Load test for 1,000 concurrent users. • Security Testing: Penetration testing and vulnerability scans. • User Acceptance Testing (UAT): o Conducted with CSC stakeholders (HRO, HRMO, HHRMD, DO, Employees and other external users). o Validates modules, UI, and reports. o Scheduled for November 4, 2025. 12. Maintenance and Support • Maintenance: o Regular updates for Angular, Spring Boot, and PostgreSQL. o Bug fixes and performance optimizations during sprints. • Support: o Helpdesk managed by CSC ICT Support Staff. o User manuals and training materials provided. • Monitoring: o Real-time monitoring via Prometheus/Grafana. o Alerts for system health and security issues. 13. Assumptions and Constraints 13.1 Assumptions • Reliable internet connectivity (≥5Mbps) at Government offices. • Users complete 8-hour mandatory training. • Stable HRIMS APIs with consistent data formats. • Primary use during working hours (Monday–Friday, 8:00 AM–5:00 PM EAT). • Government data center provides stable power, cooling, and network infrastructure. • Users have access to modern browsers (Chrome, Firefox, Edge) on desktops or tablets. 13.2 Constraints • Integration limited to HRIMS; no payroll or pension system integration. • 12-month parallel run with HRIMS for data synchronization. • Web-based platform only (no mobile app in phase 1). • Deployment on a single physical server with virtualization. • Project completion within budget and timeline (May 20, 2025–December 9, 2025). 14. Risk Mitigation Strategies Risk Description Mitigation Strategy Inaccurate HRIMS Data Inconsistent employee data from HRIMS. Validation checks; admin CRUD permissions; audit logs. HRIMS Integration Failures Unstable APIs or connectivity issues. Apache Camel with retries; CSV fallback; error logging. Security Breaches Unauthorized access or data leaks. AES-256 encryption, RBAC, MFA, TLS 1.3; audits; lockout after 5 failed attempts. Performance Issues High concurrency or large datasets. Query optimization; Redis caching; sufficient VM resources. Server Failure Hardware failure causing downtime. Daily VM snapshots; backups; offsite archival; redundant power. User Resistance Resistance to system adoption. Training; UAT involvement; manuals and helpdesk. Scope Creep Additional feature requests. Adhere to SRS; defer any feature requests to phase 2; stakeholder communication. 15. Appendices 15.1 Appendix A: Entity Relationship Diagram (ERD) Provided in Section 5.2 with PlantUML representation. 15.2 Appendix B: UI Prototypes UI mockups in Figma, covering: • Login Screen • Dashboard (role-based widgets) • Employee Profile (CRUD forms) • HR Workflow Forms (Confirmation, LWOP, etc.) • Complaints (category selection, evidence upload) • Reports (drag-and-drop interface) • Audit Trail (log table with filters) Link: Figma Prototypes (placeholder; actual link to be provided at later stage). 15.3 Appendix C: API Specification OpenAPI 3.0 specification for endpoints (e.g., /employees, /confirmation). Key details: • JSON responses with standardized format. • JWT-based authentication via Keycloak. • Error codes: 400, 401, 403, 500. Link: OpenAPI Specification (placeholder; actual link to be provided). 15.4 Appendix D: Sample Workflows Detailed workflows for all phase 1 HR modules, including actors, text-based flows, and PlantUML diagrams. Workflow 1: Employee Confirmation Purpose: Automate confirmation after a 12-month probation period. Actors: HRO (user3, ajuma), HHRMD/HRMO (user2, msmith), Employee (emp1, Ali Juma Ali, zan_id: 221458232). Text-Based Flow: [Start] → [HRO Login] → [Navigate to Confirmation] → [Submit Request with Employee Details and Documents] → [HHRMD/HRMO Login] → [Review Request and Documents] → [Approve or Reject with Reason] → [Update Employee Status] → [Notify HRO via Email/In-System Alert] → [End] PlantUML Code: @startuml start :HRO Login; :Navigate to Confirmation; :Submit Request with Employee Details and Documents; :HHRMD/HRMO Login; :Review Request and Documents; if (Decision?) then (Approve) :Approve Request; :Update Employee Status to Confirmed; else (Reject) :Reject Request with Reason; :Update Request Status; endif :Notify HRO via Email/In-System Alert; stop @enduml Workflow 2: Leave Without Pay (LWOP) Purpose: Automate LWOP requests for specified durations. Actors: HRO (user3, ajuma), HHRMD/HRMO (user2, msmith), Employee (emp3, Fatma Said Omar, zan_id: 334589123). Text-Based Flow: [Start] → [HRO Login] → [Navigate to LWOP] → [Submit Request with Duration and Documents] → [HHRMD/HRMO Login] → [Review Request and Documents] → [Approve or Reject with Reason] → [Update Request Status] → [Notify HRO via Email/In-System Alert] → [End] PlantUML Code: @startuml start :HRO Login; :Navigate to LWOP; :Submit Request with Duration and Documents; :HHRMD/HRMO Login; :Review Request and Documents; if (Decision?) then (Approve) :Approve Request; :Update Request Status; else (Reject) :Reject Request with Reason; :Update Request Status; endif :Notify HRO via Email/In-System Alert; stop @enduml Workflow 3: Promotion Purpose: Automate promotion based on qualifications/performance. Actors: HRO (user3, ajuma), HHRMD/HRMO (user2, msmith), Employee (emp2, Safia Juma Ali, zan_id: 125468957). Text-Based Flow: [Start] → [HRO Login] → [Navigate to Promotion] → [Submit Request with Performance Records and Documents] → [HHRMD/HRMO Login] → [Review Request and Documents] → [Approve or Reject with Reason] → [Update Employee Cadre/Status] → [Notify HRO via Email/In-System Alert] → [End] PlantUML Code: @startuml start :HRO Login; :Navigate to Promotion; :Submit Request with Performance Records and Documents; :HHRMD/HRMO Login; :Review Request and Documents; if (Decision?) then (Approve) :Approve Request; :Update Employee Cadre/Status; else (Reject) :Reject Request with Reason; :Update Request Status; endif :Notify HRO via Email/In-System Alert; stop @enduml Workflow 4: Complaints Purpose: Manage employee complaints with resolution. Actors: Employee (emp3, user7, hmohamed), HHRMD/DO (user5, kabdul). Text-Based Flow: [Start] → [Employee Login] → [Navigate to Complaints] → [Submit Complaint with Category and Evidence] → [HHRMD/DO Login] → [Review Complaint and Evidence] → [Resolve or Reject with Reason] → [Update Complaint Status] → [Notify HRO and Employee via Email/In-System Alert] → [End] PlantUML Code: @startuml start :Employee Login; :Navigate to Complaints; :Submit Complaint with Category and Evidence; :HHRMD/DO Login; :Review Complaint and Evidence; if (Decision?) then (Resolve) :Resolve Complaint; else (Reject) :Reject Complaint with Reason; endif :Update Complaint Status; :Notify HRO and Employee via Email/In-System Alert; stop @enduml Workflow 5: Change of Cadre Purpose: Update employee cadre based on qualifications. Actors: HRO (user3, ajuma), HHRMD/HRMO (user2, msmith), Employee (emp4, Hassan Mzee Juma, zan_id: 445678912). Text-Based Flow: [Start] → [HRO Login] → [Navigate to Cadre Change] → [Submit Request with New Cadre Details and Documents] → [HHRMD/HRMO Login] → [Review Request and Documents] → [Approve or Reject with Reason] → [Update Employee Cadre] → [Notify HRO via Email/In-System Alert] → [End] PlantUML Code: @startuml start :HRO Login; :Navigate to Cadre Change; :Submit Request with New Cadre Details and Documents; :HHRMD/HRMO Login; :Review Request and Documents; if (Decision?) then (Approve) :Approve Request; :Update Employee Cadre; else (Reject) :Reject Request with Reason; :Update Request Status; endif :Notify HRO via Email/In-System Alert; stop @enduml Workflow 6: Retirement Purpose: Automate retirement processing (compulsory, voluntary, illness). Actors: HRO (user3, ajuma), HHRMD/HRMO (user2, msmith), Employee (emp5, Zainab Ali Khamis, zan_id: 556789345). Text-Based Flow: [Start] → [HRO Login] → [Navigate to Retirement] → [Submit Request with Retirement Type and Documents] → [HHRMD/HRMO Login] → [Review Request and Documents] → [Approve or Reject with Reason] → [Update Employee Status] → [Notify HRO via Email/In-System Alert] → [End] PlantUML Code: @startuml start :HRO Login; :Navigate to Retirement; :Submit Request with Retirement Type and Documents; :HHRMD/HRMO Login; :Review Request and Documents; if (Decision?) then (Approve) :Approve Request; :Update Employee Status; else (Reject) :Reject Request with Reason; :Update Request Status; endif :Notify HRO via Email/In-System Alert; stop @enduml Workflow 7: Resignation Purpose: Process employee resignations. Actors: HRO (user3, ajuma), HHRMD/HRMO (user2, msmith), Employee (emp3, Fatma Said Omar, zan_id: 334589123). Text-Based Flow: [Start] → [HRO Login] → [Navigate to Resignation] → [Submit Request with Documents] → [HHRMD/HRMO Login] → [Review Request and Documents] → [Approve or Reject with Reason] → [Update Employee Status] → [Notify HRO via Email/In-System Alert] → [End] PlantUML Code: @startuml start :HRO Login; :Navigate to Resignation; :Submit Request with Documents; :HHRMD/HRMO Login; :Review Request and Documents; if (Decision?) then (Approve) :Approve Request; :Update Employee Status; else (Reject) :Reject Request with Reason; :Update Request Status; endif :Notify HRO via Email/In-System Alert; stop @enduml Workflow 8: Service Extension Purpose: Extend employee service beyond retirement age. Actors: HRO (user3, ajuma), HHRMD/HRMO (user2, msmith), Employee (emp5, Zainab Ali Khamis, zan_id: 556789345). Text-Based Flow: [Start] → [HRO Login] → [Navigate to Service Extension] → [Submit Request with Extension Details and Documents] → [HHRMD/HRMO Login] → [Review Request and Documents] → [Approve or Reject with Reason] → [Update Retirement Date/Status] → [Notify HRO via Email/In-System Alert] → [End] PlantUML Code: @startuml start :HRO Login; :Navigate to Service Extension; :Submit Request with Extension Details and Documents; :HHRMD/HRMO Login; :Review Request and Documents; if (Decision?) then (Approve) :Approve Request; :Update Retirement Date/Status; else (Reject) :Reject Request with Reason; :Update Request Status; endif :Notify HRO via Email/In-System Alert; stop @enduml Workflow 9: Termination Purpose: Process employee termination due to misconduct. Actors: HRO (user3, ajuma), HHRMD/DO (user2, msmith), Employee (emp4, Hassan Mzee Juma, zan_id: 445678912). Text-Based Flow: [Start] → [HRO Login] → [Navigate to Termination] → [Submit Request with Misconduct Evidence] → [HHRMD/DO Login] → [Review Request and Evidence] → [Approve or Reject with Reason] → [Update Employee Status] → [Notify HRO via Email/In-System Alert] → [End] PlantUML Code: @startuml start :HRO Login; :Navigate to Termination; :Submit Request with Misconduct Evidence; :HHRMD/DO Login; :Review Request and Evidence; if (Decision?) then (Approve) :Approve Request; :Update Employee Status; else (Reject) :Reject Request with Reason; :Update Request Status; endif :Notify HRO via Email/In-System Alert; stop @enduml Workflow 10: Dismissal Purpose: Process employee dismissal due to severe misconduct. Actors: HRO (user3, ajuma), HHRMD/DO (user2, msmith), Employee (emp6, Juma Omar Ali, zan_id: 667890456). Text-Based Flow: [Start] → [HRO Login] → [Navigate to Dismissal] → [Submit Request with Misconduct Evidence] → [HHRMD/DO Login] → [Review Request and Evidence] → [Approve or Reject with Reason] → [Update Employee Status] → [Notify HRO via Email/In-System Alert] → [End] PlantUML Code: @startuml start :HRO Login; :Navigate to Dismissal; :Submit Request with Misconduct Evidence; :HHRMD/DO Login; :Review Request and Evidence; if (Decision?) then (Approve) :Approve Request; :Update Employee Status; else (Reject) :Reject Request with Reason; :Update Request Status; endif :Notify HRO via Email/In-System Alert; stop @enduml 15.5 Appendix E: Sample Data Table Entity ID Employee ID Description Employee emp1_id emp1 Ali Juma Ali, zan_id: 221458232, Confirmation Employee emp2_id emp2 Safia Juma Ali, zan_id: 125468957, Promotion Employee emp3_id emp3 Fatma Said Omar, zan_id: 334589123, LWOP, Resignation, Complaints Employee emp4_id emp4 Hassan Mzee Juma, zan_id: 445678912, Cadre Change, Termination Employee emp5_id emp5 Zainab Ali Khamis, zan_id: 556789345, Retirement, Service Extension Employee emp6_id emp6 Juma Omar Ali, zan_id: 667890456, Dismissal Employee emp7_id emp7 Hamid Khalfan Abdalla, zan_id: 778901234, Service Extension Employee emp8_id emp8 Khamis Mcha Machano, zan_id: 889012345, Compulsory Retirement Employee emp9_id emp9 Zahran Ali Hamad, zan_id: 990123456, Voluntary Retirement Employee emp10_id emp10 Khamis Omar Moh’d, zan_id: 101234567, Illness Retirement Employee emp11_id emp11 Mgeni Mussa Haji, zan_id: 112345678, LWOP Employee emp12_id emp12 Salum Omar Haji, zan_id: 123456789, Dismissal Employee emp13_id emp13 Shehe Omar Yussuf, zan_id: 134567890, Cadre Change Employee emp14_id emp14 Feisal Ali Salum, zan_id: 145678901, Resignation User user3_id user3 HRO, username: ajuma, submits requests (all except Complaints) User user2_id user2 HHRMD/HRMO, username: msmith, approves/rejects Confirmation, LWOP, Promotion, Cadre Change, Retirement, Resignation, Service Extension User user5_id user5 DO, username: kabdul, approves/rejects Complaints, Termination, Dismissal User user7_id user7 Employee, username: hmohamed, submits Complaints Request req1_id–req10_id req1–req10 Requests for Confirmation, LWOP, Promotion, Cadre Change, Retirement, Resignation, Service Extension, Termination, Dismissal Complaint comp3_id comp3 Complaint by emp3, category: Unconfirmed Employees Audit_Log log8_id–log37_id log8–log37 Logs for login, request creation, approval/rejection, report generation 15.6 Appendix F: Sample Report Formats Structured formats for all phase 1 report types, based on provided sample data. Report 1: Service Extension S/N Name Ministry/Institution Position Gender (M/F) Total Start Date End Date 1 Hamid Khalfan Abdalla Afisi ya Rais Fedha na Mipango Dereva M:1, F:0 1 01/07/2025 30/06/2026 2 Subira Juma Abdalla BLM Katibu Mahasusi M:0, F:1 1 14/12/2024 13/12/2026 3 Somoe Said Mussa Wizara ya Elimu na Mafunzo ya Amali Afisa Elimu M:0, F:1 1 01/02/2025 31/01/2027 Total M:1, F:2 3 Report 2: Retirement (Compulsory) S/N Name Ministry/Institution Gender (M/F) Total Position Date of Birth Retirement Date 1 Khamis Mcha Machano Wizara ya Elimu na Mafunzo ya Amali M:1, F:0 1 Mwalimu 1965 30/06/2025 2 Biubwa Said Seif Wizara ya Elimu na Mafunzo ya Amali M:0, F:1 1 Mwalimu 1965 30/06/2025 3 Khamis Ali Makame Baraza la Mji Mkoani M:1, F:0 1 Tarishi 15/06/1965 14/06/2025 Total M:2, F:1 3 Report 3: Retirement (Voluntary) S/N Name Ministry/Institution Position Gender (M/F) Total Date of Birth Age 1 Zahran Ali Hamad Wizara ya Afya Mfamasia M:1, F:0 1 09/02/1970 55 2 Omar Said Omar WEMA Mwalimu M:1, F:0 1 26/06/1966 58 3 Asha Khamis Mwinshehe Wizara ya Biashara na Viwanda Afisa Viwanda M:0, F:1 1 30/05/1966 57 Total M:2, F:1 3 - Initial Deployment
272646f verified | <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>CSMS - Civil Service Management System</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet"> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script> | |
| <style> | |
| body { | |
| font-family: 'Roboto', sans-serif; | |
| background-color: #f8fafc; | |
| } | |
| .sidebar { | |
| transition: all 0.3s ease; | |
| } | |
| @media (max-width: 768px) { | |
| .sidebar { | |
| transform: translateX(-100%); | |
| } | |
| .sidebar.open { | |
| transform: translateX(0); | |
| } | |
| } | |
| .notification-badge { | |
| top: -0.5rem; | |
| right: -0.5rem; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50"> | |
| <!-- Header --> | |
| <header class="bg-white shadow-sm"> | |
| <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex justify-between items-center"> | |
| <div class="flex items-center"> | |
| <button id="sidebarToggle" class="md:hidden mr-4 text-gray-500 hover:text-gray-700"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> | |
| </svg> | |
| </button> | |
| <h1 class="text-xl font-semibold text-gray-800"> | |
| <span class="text-blue-600">CSMS</span> - Civil Service Management System | |
| </h1> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <div class="relative"> | |
| <button class="p-1 text-gray-500 hover:text-gray-700 relative"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" /> | |
| </svg> | |
| <span class="absolute top-0 right-0 h-4 w-4 bg-red-500 text-white text-xs rounded-full flex items-center justify-center notification-badge">3</span> | |
| </button> | |
| </div> | |
| <div class="relative group"> | |
| <button class="flex items-center space-x-2 focus:outline-none"> | |
| <div class="h-8 w-8 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 font-semibold">HJ</div> | |
| <span class="hidden md:block text-sm font-medium text-gray-700">H.R.Juma</span> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> | |
| </svg> | |
| </button> | |
| <div class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-10 hidden group-focus:block"> | |
| <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Profile</a> | |
| <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Settings</a> | |
| <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Log out</a> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </header> | |
| <div class="flex"> | |
| <!-- Sidebar --> | |
| <aside class="sidebar bg-white w-64 min-h-screen fixed shadow-md z-10"> | |
| <div class="p-4 border-b border-gray-200"> | |
| <div class="flex items-center space-x-3"> | |
| <div class="h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 font-semibold">HJ</div> | |
| <div> | |
| <p class="font-medium text-gray-800">H.R.Juma</p> | |
| <p class="text-xs text-gray-500">HR Officer (HRO)</p> | |
| </div> | |
| </div> | |
| </div> | |
| <nav class="p-4"> | |
| <ul class="space-y-2"> | |
| <li> | |
| <a href="#" class="flex items-center px-4 py-2 text-gray-700 rounded-md bg-blue-50 text-blue-600"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" /> | |
| </svg> | |
| Dashboard | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#" class="flex items-center px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-md"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /> | |
| </svg> | |
| Employee Profiles | |
| </a> | |
| </li> | |
| <li> | |
| <div class="flex items-center justify-between px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-md cursor-pointer" onclick="toggleSubmenu('hrMenu')"> | |
| <div class="flex items-center"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" /> | |
| </svg> | |
| HR Operations | |
| </div> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /> | |
| </svg> | |
| </div> | |
| <ul id="hrMenu" class="ml-8 mt-1 space-y-1 hidden"> | |
| <li><a href="#" class="flex items-center px-4 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-md">Confirmation</a></li> | |
| <li><a href="#" class="flex items-center px-4 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-md">Leave Without Pay</a></li> | |
| <li><a href="#" class="flex items-center px-4 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-md">Promotion</a></li> | |
| <li><a href="#" class="flex items-center px-4 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-md">Complaints</a></li> | |
| <li><a href="#" class="flex items-center px-4 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-md">Change of Cadre</a></li> | |
| <li><a href="#" class="flex items-center px-4 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-md">Retirement</a></li> | |
| <li><a href="#" class="flex items-center px-4 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-md">Resignation</a></li> | |
| <li><a href="#" class="flex items-center px-4 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-md">Service Extension</a></li> | |
| <li><a href="#" class="flex items-center px-4 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-md">Termination</a></li> | |
| <li><a href="#" class="flex items-center px-4 py-2 text-sm text-gray-500 hover:bg-gray-100 rounded-md">Dismissal</a></li> | |
| </ul> | |
| </li> | |
| <li> | |
| <a href="#" class="flex items-center px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-md"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /> | |
| </svg> | |
| Reports & Analytics | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#" class="flex items-center px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-md"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /> | |
| </svg> | |
| Audit Trail | |
| </a> | |
| </li> | |
| <li> | |
| <a href="#" class="flex items-center px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-md"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" /> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /> | |
| </svg> | |
| Settings | |
| </a> | |
| </li> | |
| </ul> | |
| </nav> | |
| </aside> | |
| <!-- Main Content --> | |
| <main class="flex-1 ml-0 md:ml-64 p-4"> | |
| <div class="max-w-7xl mx-auto"> | |
| <!-- Page Title --> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h2 class="text-2xl font-bold text-gray-800">Dashboard</h2> | |
| <div class="flex items-center space-x-2"> | |
| <span class="text-sm text-gray-500">Last updated: Today, 10:45 AM</span> | |
| <button class="text-gray-500 hover:text-gray-700"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" /> | |
| </svg> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Stats Cards --> | |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6"> | |
| <div class="bg-white rounded-lg shadow p-6"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <p class="text-sm font-medium text-gray-500">Pending Requests</p> | |
| <h3 class="text-2xl font-bold text-gray-800 mt-1">24</h3> | |
| </div> | |
| <div class="p-3 rounded-full bg-red-50 text-red-600"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /> | |
| </svg> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <span class="text-sm text-gray-500">3 nearing deadline</span> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-lg shadow p-6"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <p class="text-sm font-medium text-gray-500">Employees</p> | |
| <h3 class="text-2xl font-bold text-gray-800 mt-1">48,526</h3> | |
| </div> | |
| <div class="p-3 rounded-full bg-blue-50 text-blue-600"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" /> | |
| </svg> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <span class="text-sm text-gray-500">1,234 new this year</span> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-lg shadow p-6"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <p class="text-sm font-medium text-gray-500">Active Cases</p> | |
| <h3 class="text-2xl font-bold text-gray-800 mt-1">87</h3> | |
| </div> | |
| <div class="p-3 rounded-full bg-yellow-50 text-yellow-600"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" /> | |
| </svg> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <span class="text-sm text-gray-500">32 awaiting approval</span> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-lg shadow p-6"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <p class="text-sm font-medium text-gray-500">Retirements</p> | |
| <h3 class="text-2xl font-bold text-gray-800 mt-1">1,089</h3> | |
| </div> | |
| <div class="p-3 rounded-full bg-green-50 text-green-600"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /> | |
| </svg> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <span class="text-sm text-gray-500">67 upcoming this month</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Charts and Recent Activity --> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6"> | |
| <!-- Requests Chart --> | |
| <div class="lg:col-span-2 bg-white rounded-lg shadow p-6"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-lg font-semibold text-gray-800">HR Requests Overview</h3> | |
| <select class="border-gray-300 rounded-md text-sm focus:border-blue-500 focus:ring-blue-500"> | |
| <option>Last 7 days</option> | |
| <option selected>Last 30 days</option> | |
| <option>Last 90 days</option> | |
| <option>Year to date</option> | |
| </select> | |
| </div> | |
| <div class="h-64"> | |
| <canvas id="requestsChart"></canvas> | |
| </div> | |
| </div> | |
| <!-- Recent Activity --> | |
| <div class="bg-white rounded-lg shadow p-6"> | |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">Recent Activity</h3> | |
| <div class="space-y-4"> | |
| <div class="flex items-start"> | |
| <div class="flex-shrink-0 mr-3"> | |
| <div class="h-8 w-8 rounded-full bg-blue-100 flex items-center justify-center text-blue-600 font-semibold">SM</div> | |
| </div> | |
| <div class="flex-1 min-w-0"> | |
| <p class="text-sm font-medium text-gray-900">Safia Mohamed</p> | |
| <p class="text-sm text-gray-500">Approved promotion request for Ali Juma</p> | |
| <p class="text-xs text-gray-400 mt-1">2 hours ago</p> | |
| </div> | |
| </div> | |
| <div class="flex items-start"> | |
| <div class="flex-shrink-0 mr-3"> | |
| <div class="h-8 w-8 rounded-full bg-green-100 flex items-center justify-center text-green-600 font-semibold">KA</div> | |
| </div> | |
| <div class="flex-1 min-w-0"> | |
| <p class="text-sm font-medium text-gray-900">Khamis Abdalla</p> | |
| <p class="text-sm text-gray-500">Rejected complaint #CR-2025-0456</p> | |
| <p class="text-xs text-gray-400 mt-1">5 hours ago</p> | |
| </div> | |
| </div> | |
| <div class="flex items-start"> | |
| <div class="flex-shrink-0 mr-3"> | |
| <div class="h-8 w-8 rounded-full bg-purple-100 flex items-center justify-center text-purple-600 font-semibold">ZM</div> | |
| </div> | |
| <div class="flex-1 min-w-0"> | |
| <p class="text-sm font-medium text-gray-900">Zainab Mohamed</p> | |
| <p class="text-sm text-gray-500">Submitted confirmation documents</p> | |
| <p class="text-xs text-gray-400 mt-1">Yesterday</p> | |
| </div> | |
| </div> | |
| <div class="flex items-start"> | |
| <div class="flex-shrink-0 mr-3"> | |
| <div class="h-8 w-8 rounded-full bg-yellow-100 flex items-center justify-center text-yellow-600 font-semibold">AJ</div> | |
| </div> | |
| <div class="flex-1 min-w-0"> | |
| <p class="text-sm font-medium text-gray-900">Ali Juma</p> | |
| <p class="text-sm text-gray-500">Requested change of cadre to Accounts</p> | |
| <p class="text-xs text-gray-400 mt-1">2 days ago</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-4 text-center"> | |
| <a href="#" class="text-sm font-medium text-blue-600 hover:text-blue-800">View all activity</a> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Pending Requests and Quick Actions --> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> | |
| <!-- Pending Requests --> | |
| <div class="lg:col-span-2 bg-white rounded-lg shadow"> | |
| <div class="p-6"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-lg font-semibold text-gray-800">Pending Requests</h3> | |
| <a href="#" class="text-sm font-medium text-blue-600 hover:text-blue-800">View all</a> | |
| </div> | |
| <div class="overflow-x-auto"> | |
| <table class="min-w-full divide-y divide-gray-200"> | |
| <thead class="bg-gray-50"> | |
| <tr> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Employee</th> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th> | |
| <th scope="col" class="relative px-6 py-3"><span class="sr-only">Action</span></th> | |
| </tr> | |
| </thead> | |
| <tbody class="bg-white divide-y divide-gray-200"> | |
| <tr> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /> | |
| </svg> | |
| </div> | |
| <div class="ml-4"> | |
| <div class="text-sm font-medium text-gray-900">Confirmation</div> | |
| </div> | |
| </div> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <div class="text-sm text-gray-900">Ali Juma Ali</div> | |
| <div class="text-sm text-gray-500">ZAN ID: 221458232</div> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800">Pending Review</span> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">20/05/2025</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> | |
| <a href="#" class="text-blue-600 hover:text-blue-900">View</a> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 h-10 w-10 rounded-full bg-red-100 flex items-center justify-center text-red-600"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" /> | |
| </svg> | |
| </div> | |
| <div class="ml-4"> | |
| <div class="text-sm font-medium text-gray-900">Complaint</div> | |
| <div class="text-sm text-gray-500">Unconfirmed</div> | |
| </div> | |
| </div> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <div class="text-sm text-gray-900">Hamid Khalfan</div> | |
| <div class="text-sm text-gray-500">ZAN ID: 445678912</div> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Urgent</span> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">18/05/2025</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> | |
| <a href="#" class="text-blue-600 hover:text-blue-900">View</a> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 h-10 w-10 rounded-full bg-green-100 flex items-center justify-center text-green-600"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 11l3-3m0 0l3 3m-3-3v8m0-13a9 9 0 110 18 9 9 0 010-18z" /> | |
| </svg> | |
| </div> | |
| <div class="ml-4"> | |
| <div class="text-sm font-medium text-gray-900">Promotion</div> | |
| <div class="text-sm text-gray-500">Finance Dept.</div> | |
| </div> | |
| </div> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <div class="text-sm text-gray-900">Safia Juma Ali</div> | |
| <div class="text-sm text-gray-500">ZAN ID: 125468957</div> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800">Pending DO</span> | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">15/05/2025</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> | |
| <a href="#" class="text-blue-600 hover:text-blue-900">View</a> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Quick Actions --> | |
| <div class="bg-white rounded-lg shadow p-6"> | |
| <h3 class="text-lg font-semibold text-gray-800 mb-4">Quick Actions</h3> | |
| <div class="space-y-4"> | |
| <a href="#" class="group flex items-center space-x-3 p-3 rounded-md border border-gray-200 hover:border-blue-500 hover:bg-blue-50 transition-colors duration-150"> | |
| <div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center group-hover:bg-blue-600 group-hover:text-white"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" /> | |
| </svg> | |
| </div> | |
| <div> | |
| <h4 class="text-sm font-medium text-gray-900 group-hover:text-blue-700">Create New Employee Profile</h4> | |
| <p class="text-xs text-gray-500 group-hover:text-blue-600">Register a new civil servant</p> | |
| </div> | |
| </a> | |
| <a href="#" class="group flex items-center space-x-3 p-3 rounded-md border border-gray-200 hover:border-green-500 hover:bg-green-50 transition-colors duration-150"> | |
| <div class="flex-shrink-0 h-10 w-10 rounded-full bg-green-100 text-green-600 flex items-center justify-center group-hover:bg-green-600 group-hover:text-white"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /> | |
| </svg> | |
| </div> | |
| <div> | |
| <h4 class="text-sm font-medium text-gray-900 group-hover:text-green-700">Submit Confirmation</h4> | |
| <p class="text-xs text-gray-500 group-hover:text-green-600">Request employee confirmation</p> | |
| </div> | |
| </a> | |
| <a href="#" class="group flex items-center space-x-3 p-3 rounded-md border border-gray-200 hover:border-purple-500 hover:bg-purple-50 transition-colors duration-150"> | |
| <div class="flex-shrink-0 h-10 w-10 rounded-full bg-purple-100 text-purple-600 flex items-center justify-center group-hover:bg-purple-600 group-hover:text-white"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> | |
| </svg> | |
| </div> | |
| <div> | |
| <h4 class="text-sm font-medium text-gray-900 group-hover:text-purple-700">Process Leave Without Pay</h4> | |
| <p class="text-xs text-gray-500 group-hover:text-purple-600">Request or approve LWOP</p> | |
| </div> | |
| </a> | |
| <a href="#" class="group flex items-center space-x-3 p-3 rounded-md border border-gray-200 hover:border-red-500 hover:bg-red-50 transition-colors duration-150"> | |
| <div class="flex-shrink-0 h-10 w-10 rounded-full bg-red-100 text-red-600 flex items-center justify-center group-hover:bg-red-600 group-hover:text-white"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> | |
| </svg> | |
| </div> | |
| <div> | |
| <h4 class="text-sm font-medium text-gray-900 group-hover:text-red-700">Submit Complaint</h4> | |
| <p class="text-xs text-gray-500 group-hover:text-red-600">Report HR-related issues</p> | |
| </div> | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| </div> | |
| <!-- Employee Confirmation Modal --> | |
| <div id="confirmationModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 hidden z-20"> | |
| <div class="bg-white rounded-lg shadow-xl max-w-2xl w-full max-h-screen overflow-y-auto"> | |
| <div class="p-6"> | |
| <div class="flex justify-between items-start mb-4"> | |
| <h3 class="text-xl font-semibold text-gray-900">Employee Confirmation Request</h3> | |
| <button onclick="closeModal('confirmationModal')" class="text-gray-400 hover:text-gray-500"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> | |
| </svg> | |
| </button> | |
| </div> | |
| <div class="space-y-4"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Employee Name</label> | |
| <input type="text" value="Ali Juma Ali" disabled class="w-full bg-gray-100 border border-gray-300 rounded-md px-3 py-2 text-sm"> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">ZAN ID</label> | |
| <input type="text" value="221458232" disabled class="w-full bg-gray-100 border border-gray-300 rounded-md px-3 py-2 text-sm"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Department</label> | |
| <input type="text" value="Finance" disabled class="w-full bg-gray-100 border border-gray-300 rounded-md px-3 py-2 text-sm"> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Confirmation Documents</label> | |
| <div class="border border-dashed border-gray-300 rounded-md p-4 text-center"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" /> | |
| </svg> | |
| <div class="mt-1 text-sm text-gray-600"> | |
| <p>Download performance_review.pdf (1.4MB)</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Comments</label> | |
| <textarea rows="3" class="w-full border border-gray-300 rounded-md px-3 py-2 text-sm focus:ring-blue-500 focus:border-blue-500" placeholder="Add any notes for the reviewer..."></textarea> | |
| </div> | |
| <div class="flex justify-end space-x-3 pt-4"> | |
| <button onclick="closeModal('confirmationModal')" class="px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> | |
| Cancel | |
| </button> | |
| <button class="px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> | |
| Submit for Review | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Toggle sidebar on mobile | |
| const sidebarToggle = document.getElementById('sidebarToggle'); | |
| const sidebar = document.querySelector('.sidebar'); | |
| sidebarToggle.addEventListener('click', () => { | |
| sidebar.classList.toggle('open'); | |
| }); | |
| // Toggle submenus | |
| function toggleSubmenu(id) { | |
| const element = document.getElementById(id); | |
| element.classList.toggle('hidden'); | |
| } | |
| // Close modal | |
| function closeModal(id) { | |
| document.getElementById(id).classList.add('hidden'); | |
| } | |
| // Open modal - example function | |
| function openConfirmationModal() { | |
| document.getElementById('confirmationModal').classList.remove('hidden'); | |
| } | |
| // Chart initialization | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const ctx = document.getElementById('requestsChart').getContext('2d'); | |
| const requestsChart = new Chart(ctx, { | |
| type: 'bar', | |
| data: { | |
| labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], | |
| datasets: [ | |
| { | |
| label: 'Confirmations', | |
| data: [12, 19, 8, 15, 18, 7, 11, 13, 9, 14, 6, 10], | |
| backgroundColor: '#3B82F6', | |
| }, | |
| { | |
| label: 'Promotions', | |
| data: [5, 8, 4, 6, 9, 3, 7, 5, 4, 6, 2, 5], | |
| backgroundColor: '#10B981', | |
| }, | |
| { | |
| label: 'Retirements', | |
| data: [3, 7, 2, 5, 8, 4, 6, 5, 3, 7, 4, 9], | |
| backgroundColor: '#F59E0B', | |
| }, | |
| { | |
| label: 'Complaints', | |
| data: [2, 4, 3, 6, 5, 7, 4, 3, 5, 2, 6, 8], | |
| backgroundColor: '#EF4444', | |
| } | |
| ] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| scales: { | |
| y: { | |
| beginAtZero: true, | |
| grid: { | |
| drawBorder: false, | |
| } | |
| }, | |
| x: { | |
| grid: { | |
| display: false, | |
| } | |
| } | |
| }, | |
| plugins: { | |
| legend: { | |
| position: 'bottom', | |
| labels: { | |
| boxWidth: 12, | |
| padding: 20 | |
| } | |
| } | |
| } | |
| } | |
| }); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=hakiba67/csms-space" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |