Add employee presence with kiosk sign-in, QR badges, and mobile step-out.
Deploy Ladill Frontdesk / deploy (push) Failing after 26s
Deploy Ladill Frontdesk / deploy (push) Failing after 26s
Enables staff roster, PIN/code kiosk flow, attendance reports, evacuation staff roll call, webhooks, branch mismatch warnings, and a linked-user My presence portal. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Frontdesk;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Frontdesk\Concerns\ScopesToAccount;
|
||||
use App\Models\Employee;
|
||||
use App\Services\Frontdesk\EmployeePresenceService;
|
||||
use App\Services\Frontdesk\OrganizationResolver;
|
||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class EmployeePortalController extends Controller
|
||||
{
|
||||
use ScopesToAccount;
|
||||
|
||||
public function index(Request $request, EmployeePresenceService $presence): View
|
||||
{
|
||||
$employee = $this->resolveLinkedEmployee($request);
|
||||
$organization = $this->organization($request);
|
||||
$presence->presenceFor($employee);
|
||||
$employee->load(['presence', 'branch']);
|
||||
|
||||
return view('frontdesk.employee-portal.index', [
|
||||
'employee' => $employee,
|
||||
'organization' => $organization,
|
||||
'stepOutReasons' => config('frontdesk.employee_step_out_reasons'),
|
||||
'statusLabel' => config('frontdesk.employee_presence_statuses.'.$employee->presence->status, $employee->presence->status),
|
||||
]);
|
||||
}
|
||||
|
||||
public function action(Request $request, EmployeePresenceService $presence): RedirectResponse
|
||||
{
|
||||
$employee = $this->resolveLinkedEmployee($request);
|
||||
|
||||
$validated = $request->validate([
|
||||
'action' => ['required', 'string', 'in:step_out,step_in,sign_out'],
|
||||
'step_out_reason' => ['nullable', 'string', 'in:'.implode(',', array_keys(config('frontdesk.employee_step_out_reasons')))],
|
||||
'destination' => ['nullable', 'string', 'max:255'],
|
||||
'notes' => ['nullable', 'string', 'max:500'],
|
||||
'expected_return_at' => ['nullable', 'date'],
|
||||
]);
|
||||
|
||||
match ($validated['action']) {
|
||||
'step_out' => $presence->stepOut($employee, [
|
||||
'step_out_reason' => $validated['step_out_reason'] ?? 'other',
|
||||
'destination' => $validated['destination'] ?? null,
|
||||
'notes' => $validated['notes'] ?? null,
|
||||
'expected_return_at' => $validated['expected_return_at'] ?? null,
|
||||
]),
|
||||
'step_in' => $presence->stepIn($employee),
|
||||
'sign_out' => $presence->signOut($employee),
|
||||
default => null,
|
||||
};
|
||||
|
||||
$message = match ($validated['action']) {
|
||||
'step_out' => 'Stepped out recorded.',
|
||||
'step_in' => 'Welcome back!',
|
||||
'sign_out' => 'Signed out for the day.',
|
||||
default => 'Done.',
|
||||
};
|
||||
|
||||
return redirect()->route('frontdesk.employee.portal')->with('success', $message);
|
||||
}
|
||||
|
||||
protected function resolveLinkedEmployee(Request $request): Employee
|
||||
{
|
||||
$employee = app(OrganizationResolver::class)->employeeFor($request->user());
|
||||
|
||||
if (! $employee) {
|
||||
throw new HttpResponseException(
|
||||
redirect()
|
||||
->route('frontdesk.dashboard')
|
||||
->with('error', 'No employee profile is linked to your account. Ask an administrator to link your Ladill user on the Employees screen.'),
|
||||
);
|
||||
}
|
||||
|
||||
$this->authorizeOwner($request, $employee);
|
||||
|
||||
return $employee;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user