@extends('layouts.app') @section('title', 'Mes Demandes') @section('content') @php $serviceCount = ($serviceBookings ?? collect())->count(); $equipmentCount = ($equipmentRentalRequests ?? collect())->count(); $urgentSaleCount = ($urgentSales ?? collect())->count(); $currentSort = request('sort', 'desc'); $queryWithoutPage = request()->except('page'); $selectedServiceForFilter = ($services ?? collect())->firstWhere('id', (int) request('service_id')); $resolveStorageUrl = function ($path) { if (!$path) { return null; } if (\Illuminate\Support\Str::startsWith($path, ['http://', 'https://'])) { return $path; } if (\Illuminate\Support\Str::startsWith($path, '/storage/')) { return asset(ltrim($path, '/')); } if (\Illuminate\Support\Str::startsWith($path, 'storage/')) { return asset($path); } return asset('storage/' . ltrim($path, '/')); }; $resolveClientAvatar = function ($type, $record, $clientUser = null) use ($resolveStorageUrl) { $user = $clientUser; if (!$user && in_array($type, ['service', 'equipment'], true)) { $user = $record->client->user ?? null; } if (!$user) { return null; } if (!empty($user->profile_photo_url)) { return $user->profile_photo_url; } if (!empty($user->client->photo)) { return $resolveStorageUrl($user->client->photo); } if (!empty($user->avatar)) { return $resolveStorageUrl($user->avatar); } return null; }; $formatDuration = function ($minutes) { if (!$minutes) { return null; } $hours = intdiv((int) $minutes, 60); $remainingMinutes = ((int) $minutes) % 60; if ($hours > 0 && $remainingMinutes > 0) { return $hours . 'h' . str_pad((string) $remainingMinutes, 2, '0', STR_PAD_LEFT); } if ($hours > 0) { return $hours . 'h'; } return $remainingMinutes . ' min'; }; $formatMoney = function ($amount, $decimals = 0) { if ($amount === null || $amount === '') { return null; } return number_format((float) $amount, $decimals, ',', ' ') . '€'; }; $normalizedRequests = collect(); foreach (($serviceBookings ?? collect()) as $booking) { $clientUser = ($booking->client && $booking->client->user) ? $booking->client->user : null; $isMultiSlot = (bool) ($booking->is_multi_slot ?? false); $normalizedRequests->push((object) [ 'id' => $booking->id ?? null, 'type' => 'service', 'title' => ($booking->service ? ($booking->service->title ?? $booking->service->name) : 'Service') ?? 'Service', 'client_name' => $clientUser->name ?? 'Client inconnu', 'client_avatar' => $resolveClientAvatar('service', $booking, $clientUser), 'client_rating' => $clientUser->client_rating ?? null, 'client_reviews_count' => $clientUser->client_reviews_count ?? 0, 'status' => $booking->status ?? 'unknown', 'created_at' => $booking->created_at ?? now(), 'image' => ($booking->service && $booking->service->images && $booking->service->images->count() > 0) ? $resolveStorageUrl($booking->service->images->first()->image_path) : null, 'category' => ($booking->service && $booking->service->category && $booking->service->category->first()) ? $booking->service->category->first()->name : null, 'price' => $isMultiSlot ? ($booking->total_session_price ?? 0) : ($booking->service->price ?? null), 'price_type' => $booking->service ? ($booking->service->price_type ?? null) : null, 'route_show' => $booking->id ? route('prestataire.bookings.show', $booking->id) : '#', 'is_multi_slot' => $isMultiSlot, 'total_slots' => $isMultiSlot ? ($booking->total_slots ?? 1) : 1, 'session_duration' => $isMultiSlot ? ($booking->session_duration ?? 0) : null, ]); } foreach (($equipmentRentalRequests ?? collect()) as $request) { $clientUser = ($request->client && $request->client->user) ? $request->client->user : null; $equipmentImage = null; if ($request->equipment && $request->equipment->main_photo) { $equipmentImage = $resolveStorageUrl($request->equipment->main_photo); } elseif ($request->equipment && $request->equipment->photos && count($request->equipment->photos) > 0) { $equipmentImage = $resolveStorageUrl($request->equipment->photos[0]); } $normalizedRequests->push((object) [ 'id' => $request->id ?? null, 'type' => 'equipment', 'title' => ($request->equipment ? ($request->equipment->name ?? 'Materiel') : 'Materiel') ?? 'Materiel', 'client_name' => $clientUser->name ?? 'Client inconnu', 'client_avatar' => $resolveClientAvatar('equipment', $request, $clientUser), 'client_rating' => $clientUser->client_rating ?? null, 'client_reviews_count' => $clientUser->client_reviews_count ?? 0, 'status' => $request->status ?? 'unknown', 'created_at' => $request->created_at ?? now(), 'image' => $equipmentImage, 'category' => ($request->equipment && $request->equipment->category) ? $request->equipment->category->name : (($request->equipment && $request->equipment->subcategory) ? $request->equipment->subcategory->name : null), 'start_date' => $request->start_date ?? null, 'end_date' => $request->end_date ?? null, 'route_show' => $request->id ? route('prestataire.equipment-rental-requests.show', $request->id) : '#', ]); } foreach (($urgentSales ?? collect()) as $sale) { $latestContact = $sale->contacts ? $sale->contacts->first() : null; $clientUser = ($latestContact && $latestContact->user) ? $latestContact->user : null; $saleImage = ($sale->photos && count($sale->photos) > 0) ? $resolveStorageUrl($sale->photos[0]) : null; $normalizedRequests->push((object) [ 'id' => $sale->id ?? null, 'type' => 'urgent_sale', 'title' => $sale->title ?? 'Annonce urgente', 'client_name' => $clientUser->name ?? 'Contact a confirmer', 'client_avatar' => $resolveClientAvatar('urgent_sale', $sale, $clientUser), 'client_rating' => $clientUser->client_rating ?? null, 'client_reviews_count' => $clientUser->client_reviews_count ?? 0, 'status' => $sale->status ?? 'unknown', 'created_at' => $sale->created_at ?? now(), 'image' => $saleImage, 'category' => $sale->category ? ($sale->category->name ?? null) : null, 'price' => $sale->price ?? null, 'price_min' => $sale->price_min ?? null, 'price_max' => $sale->price_max ?? null, 'route_show' => $sale->id ? route('prestataire.urgent-sales.contacts', $sale->id) : '#', ]); } $normalizedRequests = $currentSort === 'asc' ? $normalizedRequests->sortBy('created_at')->values() : $normalizedRequests->sortByDesc('created_at')->values(); $totalVisibleCount = $normalizedRequests->count(); $pendingVisibleCount = $normalizedRequests->where('status', 'pending')->count(); $typeMeta = [ 'service' => [ 'label' => 'Service', 'icon' => 'fa-concierge-bell', 'card' => 'border-blue-100 hover:border-blue-200 hover:bg-blue-50/40', 'surface' => 'bg-blue-50', 'surface_icon' => 'text-blue-600', 'badge' => 'bg-blue-100 text-blue-700', 'muted' => 'text-blue-700', 'button' => 'bg-blue-600 hover:bg-blue-700', ], 'equipment' => [ 'label' => 'Materiel', 'icon' => 'fa-tools', 'card' => 'border-emerald-100 hover:border-emerald-200 hover:bg-emerald-50/40', 'surface' => 'bg-emerald-50', 'surface_icon' => 'text-emerald-600', 'badge' => 'bg-emerald-100 text-emerald-700', 'muted' => 'text-emerald-700', 'button' => 'bg-emerald-600 hover:bg-emerald-700', ], 'urgent_sale' => [ 'label' => 'Annonce', 'icon' => 'fa-bolt', 'card' => 'border-orange-100 hover:border-orange-200 hover:bg-orange-50/40', 'surface' => 'bg-orange-50', 'surface_icon' => 'text-orange-600', 'badge' => 'bg-orange-100 text-orange-700', 'muted' => 'text-orange-700', 'button' => 'bg-orange-600 hover:bg-orange-700', ], ]; $statusMeta = [ 'pending' => ['label' => 'En attente', 'class' => 'bg-amber-100 text-amber-800'], 'accepted' => ['label' => 'Acceptee', 'class' => 'bg-emerald-100 text-emerald-800'], 'confirmed' => ['label' => 'Confirmee', 'class' => 'bg-emerald-100 text-emerald-800'], 'in_preparation' => ['label' => 'En preparation', 'class' => 'bg-sky-100 text-sky-800'], 'active' => ['label' => 'Active', 'class' => 'bg-sky-100 text-sky-800'], 'rejected' => ['label' => 'Refusee', 'class' => 'bg-red-100 text-red-800'], 'refused' => ['label' => 'Refusee', 'class' => 'bg-red-100 text-red-800'], 'cancelled' => ['label' => 'Annulee', 'class' => 'bg-slate-200 text-slate-700'], ]; $activeFilters = collect(); if (($type ?? 'all') !== 'all') { $activeFilters->push('Type: ' . match ($type) { 'service' => 'Services', 'equipment' => 'Materiel', 'urgent_sale' => 'Annonces', default => 'Tout', }); } if (request('status')) { $activeFilters->push('Statut: ' . ($statusMeta[request('status')]['label'] ?? ucfirst(str_replace('_', ' ', request('status'))))); } if (request('date_range')) { $activeFilters->push('Periode: ' . match (request('date_range')) { 'today' => 'Aujourd hui', 'week' => 'Cette semaine', 'month' => 'Ce mois', default => request('date_range'), }); } if ($selectedServiceForFilter) { $activeFilters->push('Service: ' . ($selectedServiceForFilter->title ?? $selectedServiceForFilter->name ?? 'Service')); } @endphp
Navigation rapide
Basculez entre les types et appliquez les filtres serveur pour garder une liste propre.
Reinitialiser
@if($activeFilters->isNotEmpty())
@foreach($activeFilters as $filterLabel) {{ $filterLabel }} @endforeach
@endif
@if($normalizedRequests->isNotEmpty())
Flux de demandes

Liste compacte et actionnable

{{ $totalVisibleCount }} resultat(s)
@foreach($normalizedRequests as $item) @php $meta = $typeMeta[$item->type] ?? $typeMeta['service']; $status = $statusMeta[$item->status] ?? [ 'label' => ucfirst(str_replace('_', ' ', $item->status ?? 'Inconnu')), 'class' => 'bg-slate-100 text-slate-700', ]; $clientInitial = \Illuminate\Support\Str::upper(\Illuminate\Support\Str::substr($item->client_name ?? '?', 0, 1)); $createdLabel = $item->created_at ? $item->created_at->format('d/m/Y \a H:i') : 'Date inconnue'; $createdRelative = $item->created_at ? $item->created_at->diffForHumans() : null; $summaryLabel = null; $detailPills = collect(); if ($item->category) { $detailPills->push([ 'icon' => 'fa-tag', 'label' => $item->category, ]); } if ($item->type === 'service') { if ($item->is_multi_slot) { $detailPills->push([ 'icon' => 'fa-calendar-alt', 'label' => $item->total_slots . ' creneau(x)', ]); } if ($item->session_duration) { $detailPills->push([ 'icon' => 'fa-hourglass-half', 'label' => $formatDuration($item->session_duration), ]); } if ($item->price !== null) { $priceSuffix = match ($item->price_type) { 'per_hour' => '/h', 'per_day' => '/jour', default => '', }; $summaryLabel = ($item->is_multi_slot ? 'Total ' : '') . $formatMoney($item->price, $item->is_multi_slot ? 2 : 0) . $priceSuffix; } } elseif ($item->type === 'equipment') { if ($item->start_date && $item->end_date) { $summaryLabel = \Carbon\Carbon::parse($item->start_date)->format('d/m') . ' -> ' . \Carbon\Carbon::parse($item->end_date)->format('d/m/Y'); $detailPills->push([ 'icon' => 'fa-calendar-alt', 'label' => \Carbon\Carbon::parse($item->start_date)->format('d/m/Y'), ]); $detailPills->push([ 'icon' => 'fa-flag-checkered', 'label' => \Carbon\Carbon::parse($item->end_date)->format('d/m/Y'), ]); } } elseif ($item->type === 'urgent_sale') { if ($item->price_min && $item->price_max) { $summaryLabel = $formatMoney($item->price_min) . ' - ' . $formatMoney($item->price_max); } elseif ($item->price) { $summaryLabel = $formatMoney($item->price); } } @endphp
@if($item->image) {{ $item->title }} @else
@endif
{{ $meta['label'] }}
{{ $status['label'] }} @if($createdRelative) {{ $createdRelative }} @endif

{{ $item->title }}

@if($item->client_avatar) {{ $item->client_name }} @else {{ $clientInitial }} @endif
{{ $item->client_name }}
@if($item->client_rating) {{ number_format($item->client_rating, 1) }}/5 ({{ $item->client_reviews_count ?? 0 }} avis) @elseif(($item->client_reviews_count ?? 0) === 0) Nouveau client @else Client @endif
Recue le {{ $createdLabel }}
Suivi en temps reel
@if($detailPills->isNotEmpty())
@foreach($detailPills as $pill) {{ $pill['label'] }} @endforeach
@endif
{{ $summaryLabel ?: 'Ouvrir la demande pour plus de details' }}
Voir
@endforeach
@else

Aucune demande a afficher

Votre tableau est vide pour les filtres actuels. Ajustez la periode, le statut ou vos services pour retrouver des demandes.

@endif
@endsection