Files
Verde-Web/app/Http/Controllers/Api/V1/Auth/SelfProfileController.php

121 lines
4.6 KiB
PHP

<?php
namespace App\Http\Controllers\Api\V1\Auth;
use App\Http\Controllers\Api\V1\ApiController;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
/**
* Self-service role-specific profile read/update.
*/
class SelfProfileController extends ApiController
{
public function show(Request $request): JsonResponse
{
$user = $request->user();
$relation = $user->profileRelation();
if (! $relation) {
return $this->fail('Admins have no role profile', null, 422);
}
$user->load($relation);
return $this->ok([
'role' => $user->role,
'profile' => $user->{$relation}?->toArray(),
]);
}
public function update(Request $request): JsonResponse
{
$user = $request->user();
$relation = $user->profileRelation();
if (! $relation) {
return $this->fail('Admins have no role profile to update', null, 422);
}
$rules = $this->rulesFor($user->role);
$validated = Validator::make($request->all(), $rules)->validate();
$profile = $user->{$relation};
if (! $profile) {
$profileClass = User::profileModelForRole($user->role);
$profile = $profileClass::create(array_merge(['user_id' => $user->id], $validated));
} else {
// Self-update should not allow changing verification fields.
unset(
$validated['verification_status'],
$validated['verified_at'],
$validated['verified_by_admin_id'],
$validated['rejection_reason'],
);
// Resubmitting a rejected profile resets it to pending.
if (
method_exists($profile, 'markVerified')
&& property_exists($profile, 'attributes')
&& ($profile->verification_status ?? null) === 'rejected'
) {
$validated['verification_status'] = 'pending';
$validated['rejection_reason'] = null;
}
$profile->update($validated);
}
return $this->ok([
'role' => $user->role,
'profile' => $profile->fresh()->toArray(),
], 'Profile updated');
}
private function rulesFor(string $role): array
{
return match ($role) {
User::ROLE_RESIDENT => [
'date_of_birth' => ['nullable', 'date', 'before:today'],
'gender' => ['nullable', 'in:male,female,other,prefer_not_to_say'],
'occupation' => ['nullable', 'string', 'max:100'],
'emergency_contact_name' => ['nullable', 'string', 'max:191'],
'emergency_contact_phone' => ['nullable', 'string', 'max:20'],
],
User::ROLE_DRIVER => [
'license_number' => ['nullable', 'string', 'max:32'],
'license_class' => ['nullable', 'string', 'max:16'],
'license_expires_at' => ['nullable', 'date'],
'license_photo_path' => ['nullable', 'string', 'max:255'],
'years_of_experience' => ['nullable', 'integer', 'min:0', 'max:80'],
'date_of_birth' => ['nullable', 'date', 'before:today'],
'gender' => ['nullable', 'in:male,female,other,prefer_not_to_say'],
'emergency_contact_name' => ['nullable', 'string', 'max:191'],
'emergency_contact_phone' => ['nullable', 'string', 'max:20'],
],
User::ROLE_HELPER => [
'date_of_birth' => ['nullable', 'date', 'before:today'],
'gender' => ['nullable', 'in:male,female,other,prefer_not_to_say'],
'emergency_contact_name' => ['nullable', 'string', 'max:191'],
'emergency_contact_phone' => ['nullable', 'string', 'max:20'],
],
User::ROLE_SCANNER => [
'shift_preference' => ['nullable', 'in:morning,afternoon,night,flexible'],
'date_of_birth' => ['nullable', 'date', 'before:today'],
'gender' => ['nullable', 'in:male,female,other,prefer_not_to_say'],
'emergency_contact_name' => ['nullable', 'string', 'max:191'],
'emergency_contact_phone' => ['nullable', 'string', 'max:20'],
],
User::ROLE_STORE_PARTNER => [
'business_name' => ['nullable', 'string', 'max:191'],
'business_permit_number' => ['nullable', 'string', 'max:64'],
'contact_phone' => ['nullable', 'string', 'max:20'],
],
default => [],
};
}
}