device($request); $organization = Organization::findOrFail($device->organization_id); $settings = $organization->settings ?? []; $hosts = Host::owned($device->owner_ref) ->where('organization_id', $organization->id) ->where('is_available', true); if ($device->branch_id) { $hosts->where(function ($q) use ($device) { $q->whereNull('branch_id')->orWhere('branch_id', $device->branch_id); }); } $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, 'checkInUrl' => route('frontdesk.kiosk.device.check-in', $device->device_token), ]); } public function checkIn(Request $request, VisitCheckInService $checkIn, VisitorTypeService $visitorTypes): JsonResponse { $device = $this->device($request); $organization = Organization::findOrFail($device->organization_id); $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'], 'vehicle_info' => ['nullable', 'array'], 'signature_path' => ['nullable', 'string'], ], $visitorTypes->validationRules($visitorType))); $payload = $visitorTypes->enrichCheckInData($visitorType, $validated, $organization); if (! empty($validated['photo_data'])) { $payload['photo_data'] = $validated['photo_data']; } $payload['branch_id'] = $device->branch_id; $payload['reception_desk_id'] = $device->reception_desk_id; $visit = $checkIn->checkIn($device->owner_ref, $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, ], ]); } protected function device(Request $request): Device { return $request->attributes->get('frontdesk.device') ?? abort(404); } }