Kaynağa Gözat

feat: :sparkles: feat (agendamentos-adm) criada pagina de agendamentos

foi criada a pagina de agendamentos no layout adm, contendo as abas de criar agendamento, exibir agendamentos, e aba de agendamentos aprovados automaticamente

fase:dev | origin:escopo
Gustavo Zanatta 3 hafta önce
ebeveyn
işleme
ee158ddc86

+ 1 - 0
app/Enums/AppointmentStatusEnum.php

@@ -10,6 +10,7 @@ enum AppointmentStatusEnum: string
 
     case PENDENTE = 'pendente';
     case CONFIRMADO = 'confirmado';
+    case RECUSADO = 'recusado';
     case CANCELADO = 'cancelado';
     case CONCLUIDO = 'concluido';
 }

+ 45 - 0
app/Http/Controllers/AppointmentController.php

@@ -6,6 +6,7 @@ use App\Http\Requests\AppointmentRequest;
 use App\Http\Resources\AppointmentResource;
 use App\Services\AppointmentService;
 use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 
 class AppointmentController extends Controller
@@ -54,4 +55,48 @@ class AppointmentController extends Controller
         $this->service->delete($id);
         return $this->successResponse(message: __('messages.deleted'), code: 204);
     }
+
+    public function getAdminCounters(): JsonResponse
+    {
+        return $this->successResponse(payload: $this->service->getAdminCounters());
+    }
+
+    public function getAdminAppointmentsPaginated(Request $request): JsonResponse
+    {
+        $filters = $request->only(['status', 'search']);
+        $perPage = (int) $request->input('per_page', 10);
+        $paginator = $this->service->getAllPaginated($filters, $perPage);
+
+        $items = collect($paginator->items())->map(fn($a) => [
+            'id'                      => $a->id,
+            'order_number'            => $a->order_number,
+            'registration'            => $a->user?->registration,  
+            'user_name'               => $a->user?->name,
+            'partner_name'            => $a->partnerAgreement?->trade_name ?? $a->partnerAgreement?->company_name,
+            'service_name'            => $a->partnerAgreementService?->name,
+            'requested_at'            => $a->requested_at?->format('d/m/Y'),
+            'status'                  => $a->status?->value,
+        ]);
+
+        return $this->successResponse(payload: [
+            'data'         => $items,
+            'total'        => $paginator->total(),
+            'per_page'     => $paginator->perPage(),
+            'current_page' => $paginator->currentPage(),
+            'from'         => $paginator->firstItem(),
+            'to'           => $paginator->lastItem(),
+        ]);
+    }
+
+    public function approve(int $id): JsonResponse
+    {
+        $item = $this->service->approve($id);
+        return $this->successResponse(payload: new AppointmentResource($item), message: __('messages.updated'));
+    }
+
+    public function reject(int $id): JsonResponse
+    {
+        $item = $this->service->reject($id);
+        return $this->successResponse(payload: new AppointmentResource($item), message: __('messages.updated'));
+    }
 }

+ 52 - 0
app/Services/AppointmentService.php

@@ -2,8 +2,10 @@
 
 namespace App\Services;
 
+use App\Enums\AppointmentStatusEnum;
 use App\Models\Appointment;
 use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Pagination\LengthAwarePaginator;
 use Illuminate\Support\Str;
 
 class AppointmentService
@@ -59,6 +61,56 @@ class AppointmentService
         return $model->delete();
     }
 
+    public function getAdminCounters(): array
+    {
+        return [
+            'pendentes'  => Appointment::where('status', AppointmentStatusEnum::PENDENTE)->count(),
+            'aprovados'  => Appointment::where('status', AppointmentStatusEnum::CONFIRMADO)->count(),
+            'recusados'  => Appointment::where('status', AppointmentStatusEnum::RECUSADO)->count(),
+        ];
+    }
+
+    public function getAllPaginated(array $filters = [], int $perPage = 10): LengthAwarePaginator
+    {
+        $query = Appointment::with(['user', 'partnerAgreement', 'partnerAgreementService'])
+            ->orderBy('requested_at', 'desc');
+
+        if (!empty($filters['status'])) {
+            $query->where('status', $filters['status']);
+        }
+
+        if (!empty($filters['search'])) {
+            $term = '%' . mb_strtolower($filters['search']) . '%';
+            $query->where(function ($q) use ($term) {
+                $q->whereHas('user', function ($uq) use ($term) {
+                    $uq->whereRaw('UNACCENT(LOWER(name)) LIKE UNACCENT(?)', [$term]);
+                })->orWhereHas('partnerAgreement', function ($pq) use ($term) {
+                    $pq->whereRaw('UNACCENT(LOWER(COALESCE(trade_name, company_name))) LIKE UNACCENT(?)', [$term]);
+                })->orWhereHas('partnerAgreementService', function ($sq) use ($term) {
+                    $sq->whereRaw('UNACCENT(LOWER(name)) LIKE UNACCENT(?)', [$term]);
+                })->orWhereRaw('UNACCENT(LOWER(order_number)) LIKE UNACCENT(?)', [$term]);
+            });
+        }
+
+        return $query->paginate($perPage);
+    }
+
+    public function approve(int $id): ?Appointment
+    {
+        $model = Appointment::find($id);
+        if (!$model) return null;
+        $model->update(['status' => AppointmentStatusEnum::CONFIRMADO]);
+        return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
+    }
+
+    public function reject(int $id): ?Appointment
+    {
+        $model = Appointment::find($id);
+        if (!$model) return null;
+        $model->update(['status' => AppointmentStatusEnum::RECUSADO]);
+        return $model->fresh(['user', 'partnerAgreement', 'partnerAgreementService']);
+    }
+
     private function generateOrderNumber(): string
     {
         do {

+ 5 - 0
routes/authRoutes/appointment.php

@@ -10,6 +10,11 @@ Route::controller(AppointmentController::class)->prefix('appointment')->group(fu
 
     Route::post('/', 'store')->middleware('permission:agendamento,add');
 
+    Route::get('/admin/counters', 'getAdminCounters')->middleware('permission:agendamento,view');
+    Route::get('/admin/list', 'getAdminAppointmentsPaginated')->middleware('permission:agendamento,view');
+    Route::put('/{id}/approve', 'approve')->middleware('permission:agendamento,edit');
+    Route::put('/{id}/reject', 'reject')->middleware('permission:agendamento,edit');
+
     Route::get('/{id}', 'show')->middleware('permission:agendamento,view');
 
     Route::put('/{id}', 'update')->middleware('permission:agendamento,edit');