feat: Implement rides management with CRUD functionality

- Added rides index view with search and filter options.
- Created rides show view to display ride details.
- Implemented API routes for rides.
- Developed authentication routes for user registration, login, and email verification.
- Created tests for authentication, email verification, password reset, and user profile management.
- Added feature tests for rides and operators, including creation, updating, deletion, and searching.
- Implemented soft deletes and caching for rides and operators.
- Enhanced manufacturer and operator model tests for various functionalities.
This commit is contained in:
pacnpal
2025-06-19 22:34:10 -04:00
parent 86263db9d9
commit cc33781245
148 changed files with 14026 additions and 2482 deletions

View File

@@ -3,22 +3,22 @@
@if ($message)
<div @class([
'p-4 mb-4 rounded-lg',
'bg-green-100 dark:bg-green-800 text-green-700 dark:text-green-200' => !str_contains($message, 'error') && !str_contains($message, 'cannot'),
'bg-red-100 dark:bg-red-800 text-red-700 dark:text-red-200' => str_contains($message, 'error') || str_contains($message, 'cannot'),
'bg-green-100 text-green-700' => !str_contains($message, 'error') && !str_contains($message, 'cannot'),
'bg-red-100 text-red-700' => str_contains($message, 'error') || str_contains($message, 'cannot'),
])>
{{ $message }}
</div>
@endif
{{-- Statistics Panel --}}
<div x-data="{ open: @entangle('showStats') }" class="bg-white dark:bg-gray-800 rounded-lg shadow">
<div class="p-4 border-b border-gray-200 dark:border-gray-700">
<div x-data="{ open: @entangle('showStats') }" class="bg-white rounded-lg shadow">
<div class="p-4 border-b border-gray-200">
<button
type="button"
@click="open = !open"
class="flex justify-between items-center w-full"
>
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">
<h3 class="text-lg font-medium text-gray-900">
Review Statistics
</h3>
<span class="transform" :class="{ 'rotate-180': open }">
@@ -29,7 +29,7 @@
<div x-show="open" class="p-4">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="text-center">
<div class="text-3xl font-bold text-gray-900 dark:text-gray-100">
<div class="text-3xl font-bold text-gray-900">
{{ $statistics['average'] }}
</div>
<div class="text-sm text-gray-500">
@@ -37,7 +37,7 @@
</div>
</div>
<div class="text-center">
<div class="text-3xl font-bold text-gray-900 dark:text-gray-100">
<div class="text-3xl font-bold text-gray-900">
{{ $statistics['total'] }}
</div>
<div class="text-sm text-gray-500">
@@ -47,12 +47,12 @@
<div class="col-span-1 md:col-span-1">
@foreach (range(5, 1) as $rating)
<div class="flex items-center">
<span class="w-8 text-sm text-gray-600 dark:text-gray-400">
<span class="w-8 text-sm text-gray-600">
{{ $rating }}
</span>
<div
x-data="{ width: '{{ $statistics['total'] > 0 ? number_format(($statistics['distribution'][$rating] / $statistics['total']) * 100, 1) : 0 }}%' }"
class="flex-1 h-4 mx-2 bg-gray-200 dark:bg-gray-700 rounded relative overflow-hidden"
class="flex-1 h-4 mx-2 bg-gray-200 rounded relative overflow-hidden"
>
@if ($statistics['total'] > 0)
<div
@@ -61,7 +61,7 @@
></div>
@endif
</div>
<span class="w-8 text-sm text-gray-600 dark:text-gray-400">
<span class="w-8 text-sm text-gray-600">
{{ $statistics['distribution'][$rating] }}
</span>
</div>
@@ -79,8 +79,8 @@
wire:click="sortBy('created_at')"
@class([
'px-3 py-2 text-sm font-medium rounded-md',
'bg-primary-100 text-primary-700 dark:bg-primary-800 dark:text-primary-200' => $sortField === 'created_at',
'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700' => $sortField !== 'created_at',
'bg-primary-100 text-primary-700' => $sortField === 'created_at',
'text-gray-700 hover:bg-gray-100' => $sortField !== 'created_at',
])
>
Date
@@ -92,8 +92,8 @@
wire:click="sortBy('rating')"
@class([
'px-3 py-2 text-sm font-medium rounded-md',
'bg-primary-100 text-primary-700 dark:bg-primary-800 dark:text-primary-200' => $sortField === 'rating',
'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700' => $sortField !== 'rating',
'bg-primary-100 text-primary-700' => $sortField === 'rating',
'text-gray-700 hover:bg-gray-100' => $sortField !== 'rating',
])
>
Rating
@@ -110,8 +110,8 @@
wire:click="filterByRating({{ $rating }})"
@class([
'px-3 py-2 text-sm font-medium rounded-md',
'bg-yellow-100 text-yellow-700 dark:bg-yellow-800 dark:text-yellow-200' => $ratingFilter === $rating,
'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700' => $ratingFilter !== $rating,
'bg-yellow-100 text-yellow-700' => $ratingFilter === $rating,
'text-gray-700 hover:bg-gray-100' => $ratingFilter !== $rating,
])
>
{{ $rating }}
@@ -120,7 +120,7 @@
@if ($ratingFilter)
<button
wire:click="filterByRating(null)"
class="px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700 rounded-md"
class="px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 rounded-md"
>
Clear
</button>
@@ -131,7 +131,7 @@
{{-- Reviews List --}}
<div class="space-y-4">
@forelse ($reviews as $review)
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
<div class="bg-white rounded-lg shadow p-6">
<div class="flex justify-between items-start">
<div>
<div class="flex items-center gap-2">
@@ -141,12 +141,12 @@
@endfor
</div>
@if ($review->title)
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">
<h3 class="text-lg font-medium text-gray-900">
{{ $review->title }}
</h3>
@endif
</div>
<p class="mt-2 text-gray-600 dark:text-gray-400">
<p class="mt-2 text-gray-600">
{{ $review->content }}
</p>
</div>
@@ -162,8 +162,8 @@
wire:click="toggleHelpfulVote({{ $review->id }})"
@class([
'flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md',
'bg-green-100 text-green-700 dark:bg-green-800 dark:text-green-200' => $review->helpfulVotes->contains('user_id', Auth::id()),
'text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700' => !$review->helpfulVotes->contains('user_id', Auth::id()),
'bg-green-100 text-green-700' => $review->helpfulVotes->contains('user_id', Auth::id()),
'text-gray-700 hover:bg-gray-100' => !$review->helpfulVotes->contains('user_id', Auth::id()),
])
>
<span>Helpful</span>
@@ -172,7 +172,7 @@
</div>
</div>
@empty
<div class="text-center py-12 text-gray-500 dark:text-gray-400">
<div class="text-center py-12 text-gray-500">
@if ($ratingFilter)
No {{ $ratingFilter }}-star reviews yet.
@else