diff --git a/app/Filament/Widgets/FunnelStageChart.php b/app/Filament/Widgets/FunnelStageChart.php index 595fcfe..d1f4754 100644 --- a/app/Filament/Widgets/FunnelStageChart.php +++ b/app/Filament/Widgets/FunnelStageChart.php @@ -9,7 +9,7 @@ use Filament\Widgets\ChartWidget; class FunnelStageChart extends ChartWidget { - protected static ?string $heading = 'Funnel ejecutivo'; + protected static ?string $heading = 'Funnel'; protected int | string | array $columnSpan = 'full'; @@ -32,7 +32,7 @@ class FunnelStageChart extends ChartWidget 'borderRadius' => 12, 'borderSkipped' => false, ]], - 'labels' => ['Taxi', 'Views', 'Clicks', 'Bookings'], + 'labels' => ['Taxi', 'Espera útil', 'Detalle', 'Reserva'], ]; } diff --git a/app/Filament/Widgets/JourneyStoryboard.php b/app/Filament/Widgets/JourneyStoryboard.php index 33e5f62..0a50e97 100644 --- a/app/Filament/Widgets/JourneyStoryboard.php +++ b/app/Filament/Widgets/JourneyStoryboard.php @@ -21,28 +21,20 @@ class JourneyStoryboard extends Widget $views = Event::where('event_type', 'recommendation_viewed')->count(); $clicks = Event::where('event_type', 'recommendation_clicked')->count(); $bookingsCount = Booking::count(); - $latestBooking = Booking::with(['offer', 'ride', 'recommendation'])->latest()->first(); $commission = (float) Booking::sum('commission_amount'); $gmv = (float) Booking::sum('amount'); $rideToBooking = $rides > 0 ? round(($bookingsCount / $rides) * 100, 1) : 0; $clickThrough = $views > 0 ? round(($clicks / $views) * 100, 1) : 0; - $topZone = Ride::query() - ->selectRaw("COALESCE(context_zone, 'General') as zone, COUNT(*) as aggregate") - ->groupBy('zone') - ->orderByDesc('aggregate') - ->value('zone') ?: 'General'; return [ 'rides' => $rides, 'views' => $views, 'clicks' => $clicks, 'bookingsCount' => $bookingsCount, - 'latestBooking' => $latestBooking, 'commission' => $commission, 'gmv' => $gmv, 'rideToBooking' => $rideToBooking, 'clickThrough' => $clickThrough, - 'topZone' => $topZone, ]; } } diff --git a/app/Filament/Widgets/LatestBookingsTable.php b/app/Filament/Widgets/LatestBookingsTable.php new file mode 100644 index 0000000..3ad3a21 --- /dev/null +++ b/app/Filament/Widgets/LatestBookingsTable.php @@ -0,0 +1,45 @@ +query(Booking::query()->with(['offer', 'ride'])->latest()->limit(5)) + ->paginated(false) + ->columns([ + Tables\Columns\TextColumn::make('offer.title') + ->label('Oferta') + ->description(fn (Booking $record): string => $record->customer_name ?: ($record->ride?->pickup_label ?: 'Reserva directa')) + ->weight('semibold'), + Tables\Columns\TextColumn::make('amount') + ->label('Importe') + ->money('EUR'), + Tables\Columns\TextColumn::make('status') + ->label('Estado') + ->badge() + ->color(fn (?string $state): string => match ($state) { + 'confirmed', 'completed' => 'success', + 'pending' => 'warning', + 'cancelled' => 'danger', + default => 'gray', + }), + Tables\Columns\TextColumn::make('created_at') + ->label('Creada') + ->since(), + ]); + } +} diff --git a/app/Filament/Widgets/LatestRidesTable.php b/app/Filament/Widgets/LatestRidesTable.php new file mode 100644 index 0000000..67caa15 --- /dev/null +++ b/app/Filament/Widgets/LatestRidesTable.php @@ -0,0 +1,46 @@ +query(Ride::query()->latest()->limit(5)) + ->paginated(false) + ->columns([ + Tables\Columns\TextColumn::make('pickup_label') + ->label('Trayecto') + ->description(fn (Ride $record): string => '→ '.$record->destination_label) + ->weight('semibold'), + Tables\Columns\TextColumn::make('status') + ->label('Estado') + ->badge() + ->formatStateUsing(fn (?string $state): string => ucfirst($state ?: 'pendiente')) + ->color(fn (?string $state): string => match ($state) { + 'confirmed', 'completed' => 'success', + 'pending' => 'warning', + 'cancelled' => 'danger', + default => 'gray', + }), + Tables\Columns\TextColumn::make('eta_minutes') + ->label('ETA') + ->formatStateUsing(fn ($state): string => $state ? $state.' min' : '—'), + Tables\Columns\TextColumn::make('created_at') + ->label('Creado') + ->since(), + ]); + } +} diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 9b88523..412799b 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -4,6 +4,8 @@ namespace App\Providers\Filament; use App\Filament\Widgets\FunnelStageChart; use App\Filament\Widgets\JourneyStoryboard; +use App\Filament\Widgets\LatestBookingsTable; +use App\Filament\Widgets\LatestRidesTable; use Filament\Http\Middleware\Authenticate; use Filament\Http\Middleware\AuthenticateSession; use Filament\Http\Middleware\DisableBladeIconComponents; @@ -41,6 +43,8 @@ class AdminPanelProvider extends PanelProvider ->widgets([ JourneyStoryboard::class, FunnelStageChart::class, + LatestRidesTable::class, + LatestBookingsTable::class, ]) ->middleware([ EncryptCookies::class, diff --git a/resources/views/bookings/success.blade.php b/resources/views/bookings/success.blade.php index 15834bb..b896d35 100644 --- a/resources/views/bookings/success.blade.php +++ b/resources/views/bookings/success.blade.php @@ -8,33 +8,29 @@
Reserva confirmada

Reserva cerrada.

-

{{ $booking->customer_name }} ya tiene {{ $booking->offer->title }}.

+

{{ $booking->offer->title }} ya está en marcha.

1 · Taxi - 2 · Contexto + 2 · Confirmado 3 · Oferta 4 · Reserva
- Resultado + Estado actual {{ $booking->offer->title }} - {{ $booking->amount ? '€'.number_format((float) $booking->amount, 2) : 'Importe pendiente' }} · {{ ucfirst($booking->status) }} · {{ $booking->ride?->context_zone ?: ($booking->offer->location_label ?: 'General') }} + {{ $booking->amount ? '€'.number_format((float) $booking->amount, 2) : 'Importe pendiente' }} · {{ ucfirst($booking->status) }}
-
+
{{ $booking->amount ? '€'.number_format((float) $booking->amount, 0) : '—' }} importe
- {{ $booking->commission_amount ? '€'.number_format((float) $booking->commission_amount, 0) : '—' }} - comisión -
-
- {{ $booking->recommendation?->position ? 'Top '.$booking->recommendation->position : 'Directa' }} - atribución + {{ ucfirst($booking->status) }} + estado
@@ -43,37 +39,36 @@ @if($booking->ride) Volver al taxi confirmado @endif - +
- ℹ️ Ver detalle de atribución + ℹ️ Más info Abrir
  • Booking UUID: {{ $booking->uuid }}.
  • Estado: {{ ucfirst($booking->status) }}.
  • -
  • Ride vinculado: {{ $booking->ride?->uuid ?? 'Reserva directa' }}.
  • -
  • Origen: {{ $booking->ride?->source_channel ? ucfirst($booking->ride->source_channel) : 'Directo' }}.
  • +
  • Zona: {{ $booking->ride?->context_zone ?: ($booking->offer->location_label ?: 'General') }}.