Просмотр исходного кода

feat: :sparkles: feat (maps e dashboard incompletes) implementado sistema de mapas e dashboard incompleta

foi implementado todo o sistema de mapas do google mapas com preenchimento de endereco, e foi criado 2 blcoos na dashboard para o cliente completar o perfil

fase:dev | origin:escopo
Gustavo Zanatta 1 месяц назад
Родитель
Сommit
57b64ec3aa

+ 10 - 0
app/Http/Controllers/UserController.php

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
 use App\Http\Resources\UserTypeResource;
 use App\Services\UserService;
 use App\Http\Requests\UserRequest;
+use App\Http\Requests\UpdateMeRequest;
 use App\Http\Resources\UserResource;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Support\Facades\Log;
@@ -61,6 +62,15 @@ class UserController extends Controller
     );
   }
 
+  public function updateMe(UpdateMeRequest $request): JsonResponse
+  {
+    $user = $this->service->updateMe($request->validated());
+    return $this->successResponse(
+      payload: new UserResource($user),
+      message: __("messages.updated"),
+    );
+  }
+
   public function getUserTypes(): JsonResponse
   {
     $user_types = $this->service->getUserTypes();

+ 26 - 0
app/Http/Requests/UpdateMeRequest.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace App\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Validation\Rule;
+
+class UpdateMeRequest extends FormRequest
+{
+  public function authorize(): bool
+  {
+    return true;
+  }
+
+  public function rules(): array
+  {
+    return [
+      'name'     => 'sometimes|string|nullable|max:255',
+      'email'    => ['sometimes', 'email', 'nullable', Rule::unique('users', 'email')->ignore(Auth::id())],
+      'phone'    => 'sometimes|string|nullable',
+      'language' => 'sometimes|string|nullable',
+      'document' => 'sometimes|string|nullable',
+    ];
+  }
+}

+ 3 - 2
app/Http/Resources/DashboardClienteResource.php

@@ -22,8 +22,9 @@ class DashboardClienteResource extends JsonResource
       'lastDoneSchedules' => $this['lastDoneSchedules'],
       'favoriteProviders' => $this['favoriteProviders'],
       'providersClose' => $this['providersClose'],
-      'schedulesProposals' => $this['schedulesProposals'],
-      'todaySchedules' => $this['todaySchedules'],
+      'schedulesProposals'  => $this['schedulesProposals'],
+      'todaySchedules'      => $this['todaySchedules'],
+      'has_payment_methods' => $this['has_payment_methods'],
     ];
   }
 }

+ 2 - 0
app/Http/Resources/UserResource.php

@@ -29,6 +29,8 @@ class UserResource extends JsonResource
       'provider_daily_price_4h' => $this->provider?->daily_price_4h,
       'provider_daily_price_2h' => $this->provider?->daily_price_2h,
       'client_id' => $this->client?->id,
+      'client_document' => $this->client?->document,
+      'registration_complete' => $this->registration_complete,
       'provider' => $this->whenLoaded('provider'),
       'client' => $this->whenLoaded('client'),
       'created_at' => Carbon::parse($this->created_at)->format('Y-m-d H:i'),

+ 1 - 0
app/Models/User.php

@@ -67,6 +67,7 @@ class User extends Authenticatable
             "password" => "hashed",
             "type" => UserTypeEnum::class,
             "language" => LanguageEnum::class,
+            "registration_complete" => "boolean",
         ];
     }
 

+ 10 - 1
app/Services/AuthService.php

@@ -2,6 +2,8 @@
 
 namespace App\Services;
 
+use App\Models\Address;
+use App\Models\Client;
 use App\Models\User;
 use App\Models\PersonalAccessToken;
 use App\Enums\UserTypeEnum;
@@ -142,7 +144,12 @@ class AuthService
         $user->code = $code;
         $user->validated_code = false;
         $user->save();
-        $isLogin = true;
+
+        $client = Client::where('user_id', $user->id)->first();
+        $hasAddress = $client && Address::where('source', 'client')
+          ->where('source_id', $client->id)
+          ->exists();
+        $isLogin = $client && $hasAddress;
       } else {
         $user = new User();
         $user->fill($data);
@@ -150,6 +157,8 @@ class AuthService
         $user->name = $data['name'] ?? 'Usuário';
         $user->type = $data['type'] ?? UserTypeEnum::CLIENT->value;
         $user->save();
+
+        Client::create(['user_id' => $user->id]);
       }
 
       if (!empty($data['email'])) {

+ 36 - 21
app/Services/ClientService.php

@@ -69,37 +69,52 @@ class ClientService
         $user->save();
       }
 
-      $client = new Client();
-      $client->user_id = $user->id;
-      $client->document = $data['document'] ?? null;
-      $client->save();
+      $client = Client::firstOrCreate(
+        ['user_id' => $user->id],
+        ['document' => $data['document'] ?? null]
+      );
+      if (!empty($data['document'])) {
+        $client->document = $data['document'];
+        $client->save();
+      }
       $client->refresh();
 
-      $address = new Address();
-      $address->source = 'client';
-      $address->source_id = $client->id;
-      $address->zip_code = $data['zip_code'] ?? null;
-      $address->address = $data['address'] ?? null;
-      $address->number = $data['number'] ?? null;
-      $address->district = $data['district'] ?? null;
-      $address->has_complement = $data['has_complement'] ?? false;
-      $address->complement = $data['complement'] ?? null;
-      $address->nickname = $data['nickname'] ?? null;
-      $address->instructions = $data['instructions'] ?? null;
-      $address->address_type = $data['address_type'] ?? 'home';
-      $address->latitude = $data['latitude'] ?? null;
-      $address->longitude = $data['longitude'] ?? null;
+      $addressData = [
+        'zip_code'       => $data['zip_code'] ?? null,
+        'address'        => $data['address'] ?? null,
+        'number'         => $data['number'] ?? null,
+        'district'       => $data['district'] ?? null,
+        'has_complement' => $data['has_complement'] ?? false,
+        'complement'     => $data['complement'] ?? null,
+        'nickname'       => $data['nickname'] ?? null,
+        'instructions'   => $data['instructions'] ?? null,
+        'address_type'   => $data['address_type'] ?? 'home',
+        'latitude'       => $data['latitude'] ?? null,
+        'longitude'      => $data['longitude'] ?? null,
+      ];
 
       if (!empty($data['state']) && !empty($data['city'])) {
         $state = State::where('code', $data['state'])->first();
         if ($state) {
           $city = City::where('name', $data['city'])->where('state_id', $state->id)->first();
-          $address->state_id = $state->id;
-          $address->city_id = $city?->id;
+          $addressData['state_id'] = $state->id;
+          $addressData['city_id']  = $city?->id;
         }
       }
 
-      $address->save();
+      Address::updateOrCreate(
+        ['source' => 'client', 'source_id' => $client->id],
+        $addressData
+      );
+
+      $registrationComplete = !empty($user->name)
+        && !empty($client->document)
+        && Address::where('source', 'client')->where('source_id', $client->id)->exists();
+
+      if ($registrationComplete !== $user->registration_complete) {
+        $user->registration_complete = $registrationComplete;
+        $user->save();
+      }
 
       $result = $this->authService->loginWithEmail(
         email: $user->email,

+ 12 - 8
app/Services/DashboardService.php

@@ -5,6 +5,7 @@ namespace App\Services;
 use App\Models\Address;
 use App\Models\Client;
 use App\Models\ClientFavoriteProvider;
+use App\Models\ClientPaymentMethod;
 use App\Models\Provider;
 use App\Models\ProviderSpeciality;
 use App\Models\Review;
@@ -255,16 +256,19 @@ class DashboardService
       ->orderBy('schedules.start_time', 'asc')
       ->get();
 
+    $hasPaymentMethods = ClientPaymentMethod::where('client_id', $cliente->id)->exists();
+
     return [
-      'headerBar'        => $headerBar,
-      'summaryInfos'     => $summaryInfos,
-      'pendingSchedules' => $pendingSchedules,
-      'nextSchedules'    => $nextSchedules,
-      'lastDoneSchedules' => $lastDoneSchedules,
-      'favoriteProviders' => $favoriteProviders,
-      'providersClose'   => $providersClose,
-      'todaySchedules'   => $todaySchedules,
+      'headerBar'          => $headerBar,
+      'summaryInfos'       => $summaryInfos,
+      'pendingSchedules'   => $pendingSchedules,
+      'nextSchedules'      => $nextSchedules,
+      'lastDoneSchedules'  => $lastDoneSchedules,
+      'favoriteProviders'  => $favoriteProviders,
+      'providersClose'     => $providersClose,
+      'todaySchedules'     => $todaySchedules,
       'schedulesProposals' => $schedulesProposals,
+      'has_payment_methods' => $hasPaymentMethods,
     ];
   }
 

+ 46 - 0
app/Services/UserService.php

@@ -3,9 +3,13 @@
 namespace App\Services;
 
 use App\Enums\UserTypeEnum;
+use App\Models\Address;
+use App\Models\Client;
 use App\Models\User;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
 
 class UserService
 {
@@ -52,6 +56,48 @@ class UserService
     return $model->delete();
   }
 
+  public function updateMe(array $data): User
+  {
+    try {
+      DB::beginTransaction();
+
+      $user = User::with(['client'])->findOrFail(Auth::id());
+
+      $userFields = array_filter(
+        array_intersect_key($data, array_flip(['name', 'email', 'phone', 'language'])),
+        fn($v) => $v !== null,
+      );
+
+      if (!empty($userFields)) {
+        $user->update($userFields);
+      }
+
+      if (array_key_exists('document', $data)) {
+        $client = $user->client ?? Client::create(['user_id' => $user->id]);
+        $client->document = $data['document'];
+        $client->save();
+      }
+
+      $user->load('client');
+
+      $registrationComplete = !empty($user->name)
+        && !empty($user->client?->document)
+        && Address::where('source', 'client')->where('source_id', $user->client->id)->exists();
+
+      if ($user->registration_complete !== $registrationComplete) {
+        $user->registration_complete = $registrationComplete;
+        $user->save();
+      }
+
+      DB::commit();
+      return $user->fresh(['client']);
+    } catch (\Exception $e) {
+      DB::rollBack();
+      Log::error('Erro ao atualizar perfil.', ['error' => $e->getMessage()]);
+      throw $e;
+    }
+  }
+
   public function getUserTypes(): array
   {
     return UserTypeEnum::toArray();

+ 22 - 0
database/migrations/2026_05_12_000001_alter_clients_document_nullable.php

@@ -0,0 +1,22 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::table('clients', function (Blueprint $table) {
+            $table->string('document')->nullable()->change();
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('clients', function (Blueprint $table) {
+            $table->string('document')->nullable(false)->change();
+        });
+    }
+};

+ 22 - 0
database/migrations/2026_05_12_000002_add_registration_complete_to_users_table.php

@@ -0,0 +1,22 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->boolean('registration_complete')->default(false)->after('validated_code');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->dropColumn('registration_complete');
+        });
+    }
+};

+ 1 - 0
routes/authRoutes/user.php

@@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Route;
 use App\Http\Controllers\UserController;
 
 Route::get('/user/me', [UserController::class, 'me']);
+Route::put('/me', [UserController::class, 'updateMe'])->middleware('permission:config.user,edit');
 Route::get('/user', [UserController::class, 'index'])->middleware('permission:config.user,view');
 Route::post('/user', [UserController::class, 'store'])->middleware('permission:config.user,add');
 Route::get('/user/{id}', [UserController::class, 'show'])->middleware('permission:config.user,view');