Initial Ladill Frontdesk release with deploy pipeline.
Visitor management app with SSO, kiosk, badges, reports, and Gitea CI deploy to frontdesk.ladill.com. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Frontdesk;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Frontdesk\Concerns\ScopesToAccount;
|
||||
use App\Models\Host;
|
||||
use App\Models\Visit;
|
||||
use App\Services\Frontdesk\VisitCheckInService;
|
||||
use App\Services\Frontdesk\VisitCheckOutService;
|
||||
use App\Services\Frontdesk\VisitorTypeService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class KioskController extends Controller
|
||||
{
|
||||
use ScopesToAccount;
|
||||
|
||||
public function show(Request $request, VisitorTypeService $visitorTypes): View
|
||||
{
|
||||
$this->authorizeAbility($request, 'kiosk.use');
|
||||
$organization = $this->organization($request);
|
||||
$settings = $organization->settings ?? [];
|
||||
|
||||
$hosts = Host::owned($this->ownerRef($request))
|
||||
->where('organization_id', $organization->id)
|
||||
->where('is_available', true);
|
||||
$this->scopeToBranch($request, $hosts);
|
||||
$hosts = $hosts->orderBy('name')->get();
|
||||
|
||||
return view('frontdesk.kiosk.index', [
|
||||
'organization' => $organization,
|
||||
'hosts' => $hosts,
|
||||
'visitorTypes' => config('frontdesk.visitor_types'),
|
||||
'typeConfigs' => $visitorTypes->configsForFrontend(),
|
||||
'resetSeconds' => (int) ($settings['kiosk_reset_seconds'] ?? config('frontdesk.kiosk.inactivity_reset_seconds', 120)),
|
||||
'visitorPolicy' => $settings['visitor_policy'] ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function checkIn(Request $request, VisitCheckInService $checkIn, VisitorTypeService $visitorTypes): JsonResponse
|
||||
{
|
||||
$this->authorizeAbility($request, 'kiosk.use');
|
||||
$organization = $this->organization($request);
|
||||
$visitorType = $request->input('visitor_type', 'visitor');
|
||||
|
||||
$validated = $request->validate(array_merge([
|
||||
'full_name' => ['required', 'string', 'max:255'],
|
||||
'company' => ['nullable', 'string', 'max:255'],
|
||||
'phone' => ['nullable', 'string', 'max:50'],
|
||||
'email' => ['nullable', 'email', 'max:255'],
|
||||
'host_id' => ['nullable', 'integer'],
|
||||
'visitor_type' => ['required', 'string', 'in:'.implode(',', array_keys(config('frontdesk.visitor_types')))],
|
||||
'purpose' => ['nullable', 'string', 'max:500'],
|
||||
'expected_duration_minutes' => ['nullable', 'integer'],
|
||||
'policies_accepted' => ['accepted'],
|
||||
'photo_data' => ['nullable', 'string'],
|
||||
'signature_path' => ['nullable', 'string'],
|
||||
], $visitorTypes->validationRules($visitorType)));
|
||||
|
||||
$payload = $visitorTypes->enrichCheckInData($visitorType, $validated, $organization);
|
||||
if (! empty($validated['photo_data'])) {
|
||||
$payload['photo_data'] = $validated['photo_data'];
|
||||
}
|
||||
|
||||
$visit = $checkIn->checkIn($this->ownerRef($request), $organization, $payload);
|
||||
|
||||
return response()->json([
|
||||
'visit' => [
|
||||
'id' => $visit->id,
|
||||
'public_id' => $visit->public_id,
|
||||
'badge_code' => $visit->badge_code,
|
||||
'visitor_name' => $visit->visitor->full_name,
|
||||
'host_name' => $visit->host?->name,
|
||||
'status' => $visit->status,
|
||||
'awaiting_approval' => $visit->awaitingApproval(),
|
||||
'checked_in_at' => $visit->checked_in_at?->toIso8601String(),
|
||||
'badge_url' => $visit->isInside() ? route('frontdesk.visits.badge', $visit) : null,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user