# Employee Portal — Business Flows

## What the Portal Is

The Employee Portal is a self-service web interface where company employees can view their own HR and payroll data, submit workplace requests, track tasks assigned to them, and receive HR notifications. It is completely separate from the admin back-office dashboard. Employees cannot see any other employee's data and have no access to administrative or financial management functions.

The portal lives at `/portal/` and is distinct in every technical sense from the admin area: different login page, different session, different permissions model.

---

## Who Uses It

- **Employees** — hourly, salaried, or contracted staff whose records exist in the HR module and whose `Employee` account has been activated by an HR admin. An employee logs in with their own credentials and sees only their own data.
- **HR Administrators** — they do not log in to the portal; they manage employees from the admin back-office. The data employees see in the portal is created and maintained by HR admins.

---

## Authentication

### How Employees Log In

1. The employee navigates to `/portal/login`.
2. They enter their registered email address and password.
3. The system validates credentials against the `employees` auth guard (backed by the `Employee` model). This guard is completely separate from the admin guard; an admin account cannot be used to log in to the portal.
4. On success the session is regenerated to prevent session fixation, and the employee is redirected to the portal dashboard (or to their originally intended page if they were redirected from there).
5. If already logged in when hitting `/portal/login`, the employee is redirected straight to the dashboard without being shown the login form.

### What Blocks Portal Access

Two layers of middleware protect every portal page beyond login and logout:

- **`auth:employee`** — standard Laravel authentication check against the `employee` guard. Any unauthenticated request is redirected to the portal login page.
- **`employee.active` (`EnsureEmployeeActive` middleware)** — even after a valid login, if the employee's `is_active` flag has been set to `false` by an admin (for example, upon suspension or termination), the middleware immediately logs the employee out, invalidates the session, regenerates the CSRF token, and redirects to the login page with an "account inactive" error message. This ensures that deactivating an employee in the admin panel takes effect on any live portal session without waiting for a natural session expiry.

### Logging Out

The employee clicks a logout button which submits a POST request to `/portal/logout`. The session is fully invalidated and the employee is redirected to the login page.

---

## Dashboard

When an employee first logs in they land on the portal dashboard. The dashboard is a summary view showing:

- A greeting personalised to the logged-in employee.
- The count of unread notifications waiting for them.
- A list of their five most recent notifications so they can see what has happened without navigating away.
- A list of their pending HR requests — requests that have been submitted but have not yet been fully approved or rejected. This gives a quick at-a-glance status of outstanding items.

The dashboard is designed to be a starting point, not a deep data view. Each item is a link into the relevant full section.

---

## Profile

The profile page displays a comprehensive view of the logged-in employee's current record. The information is read-only from the employee's perspective; they cannot edit it directly (they must submit a Data Change Request if something needs updating).

The profile shows:

- **Personal information** — name, branch, department, designation, grade, direct manager.
- **Current contract** — the most recent contract record, loaded with its contract type. If the employee has multiple contracts, only the current one is shown.
- **Current salary profile** — the most recent active salary profile, including the linked cost centre.
- **Primary bank account** — the bank account marked as primary and active, for salary payment reference.
- **Documents** — up to five of the employee's most recently expiring active documents (passport, national ID, driving licence, etc.).

---

## Attendance

The attendance section lets an employee review their own attendance records for any given month.

The employee selects a year and month using filters on the page. The system then shows:

- Summary statistics for that month — for example, the count of present days, late arrivals, absences, and overtime hours. The exact metrics are calculated by the `AttendancePortalService`.
- A paginated list of individual attendance records for the selected period — each record shows the date, check-in time, check-out time, and any computed duration or status.
- A set of month options for the filter to allow easy navigation between periods.

Employees can only see their own attendance; the data is always scoped to the authenticated employee's ID.

---

## Payroll and Payslips

The payroll section gives an employee visibility into their payroll history.

### Payroll List

The main payroll page shows:

- The latest payroll line (the most recent pay period for which the employee has been paid), displayed prominently at the top.
- A paginated history of all past payroll lines.
- A summary of the employee's leave usage, giving context about deductions or adjustments related to leave taken.

### Payslip Detail

Clicking any payroll line takes the employee to a detailed payslip view for that period. The detail page shows a full breakdown of earnings, deductions, and the net amount for that pay run.

If an employee tries to access a payslip line that does not belong to them or does not exist, the system returns a 404 page.

---

## Request Submission

Employees can submit several types of HR requests directly from the portal. Each submission enters the HR request workflow where it is reviewed and approved (or rejected) by appropriate HR staff via the admin panel.

### Supported Request Types

| Type | What it does |
|------|-------------|
| Leave | Request time off (annual, sick, unpaid, etc.) |
| Permission | Request a short authorised absence during the working day |
| Loan | Request a salary advance or employee loan |
| Data Change | Ask HR to update personal or employment data on the employee's behalf |
| Complaint | File a formal workplace complaint |
| Resignation | Submit formal notice of intent to resign |

### How a Submission Works

1. The employee navigates to `Submit` and selects the request type, or they click a dedicated submission link for a specific type.
2. The portal loads the appropriate form for that type. The form may include contextual data pre-loaded by the service — for example, available leave types or current balance.
3. The employee fills in the form and submits it.
4. The system validates the submission using a type-specific form request class (for example, `SubmitLeaveRequest` for leave, `SubmitComplaintRequest` for complaints). Each form request has its own rules.
5. The validated data is passed to `SubmissionService::submit()`, which creates the appropriate HR request record in the database and routes it into the approval workflow.
6. Any file attachments uploaded with the form are also processed by the service.
7. On success, the employee is redirected to their request list with a success message.
8. If an unknown request type is provided in the URL, the system returns a 404 error.

### Viewing Past Requests

The Request List page shows all of the employee's past and current submissions across all request types. The employee can filter by:

- Request type (leave, permission, loan, etc.)
- Status (pending, approved, rejected, etc.)

Summary statistics at the top show counts per status. The list is paginated.

Clicking a request opens a detail view showing the full request information and its current approval status.

---

## Tasks

Employees may be assigned tasks by HR administrators or managers. The Tasks section lets an employee manage and track work assigned to them.

### Task List

The task list shows all tasks assigned to the employee. An optional status filter allows the employee to narrow the list to tasks in a specific state (for example, "in progress" or "completed"). Statistics at the top summarise the employee's tasks by status.

### Task Detail

Clicking a task opens the detail view for that task. This shows the task description, due date, assigned status, and any comments or activity associated with the task. The service layer (`TaskPortalService`) handles scoping so the employee can only see tasks assigned to them.

If an employee tries to access a task that does not belong to them or does not exist, the system returns a 404 page.

---

## Documents

The Documents section shows the employee's official HR documents — items like employment letters, contract copies, or certificates that HR has uploaded against their record.

The employee can filter documents by type. The list is paginated. Each document entry shows the document name, type, and any relevant date. The data is scoped strictly to the logged-in employee.

---

## Notifications

The portal has a full notification centre. Notifications are created by the admin system when significant events occur — for example, when an HR request is approved or rejected, or when a task is assigned.

### Notification List

The notifications page shows a paginated list of all notifications for the employee. It also shows pending requests count for context.

### Marking as Read

- The employee can mark an individual notification as read by clicking it or using the "mark read" action. This submits a POST to `/portal/notifications/{id}/read`.
- A "Mark all as read" button submits a POST to `/portal/notifications/read-all` and marks every unread notification for the employee as read at once.

The dashboard always shows the current unread count so the employee knows at a glance whether they have new notifications.

---

## Static Informational Pages

Two informational placeholder pages are accessible:

- `/portal/complaints` — provides context about the complaints process (static content, no data).
- `/portal/resignation` — provides context about the resignation process (static content, no data).

These pages use a shared placeholder template and are distinct from the actual submission forms (which are accessed through `/portal/submit/complaint` and `/portal/submit/resignation`).
