Files
thrillwiki_laravel/app/Livewire/RideFormComponent.php

140 lines
4.2 KiB
PHP

<?php
namespace App\Livewire;
use App\Models\Ride;
use App\Models\Park;
use App\Models\ParkArea;
use App\Models\RideModel;
use App\Models\Designer;
use App\Models\Manufacturer;
use App\Enums\RideCategory;
use App\Enums\RideStatus;
use Livewire\Component;
use Illuminate\Validation\Rules\Enum;
class RideFormComponent extends Component
{
public ?Ride $ride = null;
/** @var array<string, mixed> */
public array $state = [];
/** @var array<string, mixed>|null */
public ?array $coasterStats = null;
/** @var int|null */
public ?int $parkId = null;
protected function rules(): array
{
return [
'state.name' => ['required', 'string', 'max:255'],
'state.park_id' => ['required', 'exists:parks,id'],
'state.park_area_id' => ['nullable', 'exists:park_areas,id'],
'state.manufacturer_id' => ['nullable', 'exists:manufacturers,id'],
'state.designer_id' => ['nullable', 'exists:designers,id'],
'state.ride_model_id' => ['nullable', 'exists:ride_models,id'],
'state.category' => ['required', new Enum(RideCategory::class)],
'state.status' => ['required', new Enum(RideStatus::class)],
'state.post_closing_status' => ['nullable', new Enum(RideStatus::class)],
'state.description' => ['nullable', 'string'],
'state.opening_date' => ['nullable', 'date'],
'state.closing_date' => ['nullable', 'date'],
'state.status_since' => ['nullable', 'date'],
'state.min_height_in' => ['nullable', 'integer', 'min:0'],
'state.max_height_in' => ['nullable', 'integer', 'min:0'],
'state.capacity_per_hour' => ['nullable', 'integer', 'min:0'],
'state.ride_duration_seconds' => ['nullable', 'integer', 'min:0'],
];
}
public function mount(?Ride $ride = null): void
{
$this->ride = $ride;
if ($ride) {
$this->state = $ride->only([
'name', 'park_id', 'park_area_id', 'manufacturer_id',
'designer_id', 'ride_model_id', 'category', 'status',
'post_closing_status', 'description', 'opening_date',
'closing_date', 'status_since', 'min_height_in',
'max_height_in', 'capacity_per_hour', 'ride_duration_seconds',
]);
$this->parkId = $ride->park_id;
if ($ride->coasterStats) {
$this->coasterStats = $ride->coasterStats->toArray();
}
}
}
public function updated(string $field): void
{
$this->validateOnly($field);
if ($field === 'state.category') {
$this->coasterStats = $this->state['category'] === RideCategory::ROLLER_COASTER->value
? ($this->coasterStats ?? [])
: null;
}
}
public function save(): void
{
$this->validate();
if (!$this->ride) {
$this->ride = new Ride();
}
$this->ride->fill($this->state)->save();
// Handle coaster stats if applicable
if ($this->state['category'] === RideCategory::ROLLER_COASTER->value && $this->coasterStats) {
$this->ride->coasterStats()->updateOrCreate(
['ride_id' => $this->ride->id],
$this->coasterStats
);
} elseif ($this->ride->coasterStats) {
$this->ride->coasterStats->delete();
}
session()->flash('message', 'Ride saved successfully.');
$this->redirect(route('rides.show', $this->ride));
}
public function getParksProperty()
{
return Park::orderBy('name')->get();
}
public function getParkAreasProperty()
{
return $this->parkId
? ParkArea::where('park_id', $this->parkId)->orderBy('name')->get()
: collect();
}
public function getManufacturersProperty()
{
return Manufacturer::orderBy('name')->get();
}
public function getDesignersProperty()
{
return Designer::orderBy('name')->get();
}
public function getRideModelsProperty()
{
return RideModel::orderBy('name')->get();
}
public function render()
{
return view('livewire.ride-form');
}
}