mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-22 21:51:11 -05:00
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:
62
resources/views/operators/create.blade.php
Normal file
62
resources/views/operators/create.blade.php
Normal file
@@ -0,0 +1,62 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">Create New Operator</h1>
|
||||
<a href="{{ route('operators.index') }}" class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg">
|
||||
Back to List
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
|
||||
<form action="{{ route('operators.store') }}" method="POST">
|
||||
@csrf
|
||||
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||
Name *
|
||||
</label>
|
||||
<input type="text" id="name" name="name" value="{{ old('name') }}" required
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
|
||||
@error('name')
|
||||
<p class="text-red-600 text-sm mt-1">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||
Description
|
||||
</label>
|
||||
<textarea id="description" name="description" rows="4"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">{{ old('description') }}</textarea>
|
||||
@error('description')
|
||||
<p class="text-red-600 text-sm mt-1">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="flex items-center">
|
||||
<input type="checkbox" name="is_active" value="1" {{ old('is_active', true) ? 'checked' : '' }}
|
||||
class="rounded border-gray-300 text-blue-600 shadow-sm focus:ring-blue-500">
|
||||
<span class="ml-2 text-sm text-gray-700 dark:text-gray-300">Active</span>
|
||||
</label>
|
||||
@error('is_active')
|
||||
<p class="text-red-600 text-sm mt-1">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end space-x-2 mt-6 pt-6 border-t border-gray-200 dark:border-gray-700">
|
||||
<a href="{{ route('operators.index') }}" class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg">
|
||||
Cancel
|
||||
</a>
|
||||
<button type="submit" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg">
|
||||
Create Operator
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
68
resources/views/operators/edit.blade.php
Normal file
68
resources/views/operators/edit.blade.php
Normal file
@@ -0,0 +1,68 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">Edit Operator</h1>
|
||||
<div class="flex space-x-2">
|
||||
<a href="{{ route('operators.show', $operator) }}" class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg">
|
||||
View
|
||||
</a>
|
||||
<a href="{{ route('operators.index') }}" class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg">
|
||||
Back to List
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
|
||||
<form action="{{ route('operators.update', $operator) }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||
Name *
|
||||
</label>
|
||||
<input type="text" id="name" name="name" value="{{ old('name', $operator->name) }}" required
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
|
||||
@error('name')
|
||||
<p class="text-red-600 text-sm mt-1">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="description" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||
Description
|
||||
</label>
|
||||
<textarea id="description" name="description" rows="4"
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white">{{ old('description', $operator->description) }}</textarea>
|
||||
@error('description')
|
||||
<p class="text-red-600 text-sm mt-1">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="flex items-center">
|
||||
<input type="checkbox" name="is_active" value="1" {{ old('is_active', $operator->is_active) ? 'checked' : '' }}
|
||||
class="rounded border-gray-300 text-blue-600 shadow-sm focus:ring-blue-500">
|
||||
<span class="ml-2 text-sm text-gray-700 dark:text-gray-300">Active</span>
|
||||
</label>
|
||||
@error('is_active')
|
||||
<p class="text-red-600 text-sm mt-1">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end space-x-2 mt-6 pt-6 border-t border-gray-200 dark:border-gray-700">
|
||||
<a href="{{ route('operators.show', $operator) }}" class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg">
|
||||
Cancel
|
||||
</a>
|
||||
<button type="submit" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg">
|
||||
Update Operator
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
77
resources/views/operators/index.blade.php
Normal file
77
resources/views/operators/index.blade.php
Normal file
@@ -0,0 +1,77 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">Operators</h1>
|
||||
<a href="{{ route('operators.create') }}" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg">
|
||||
Add New Operator
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Search and Filters -->
|
||||
<form method="GET" class="mb-6">
|
||||
<div class="flex gap-4">
|
||||
<input type="text" name="search" value="{{ request('search') }}"
|
||||
placeholder="Search operators..."
|
||||
class="flex-1 px-4 py-2 border border-gray-300 rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white">
|
||||
<select name="status" class="px-4 py-2 border border-gray-300 rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white">
|
||||
<option value="">All Status</option>
|
||||
<option value="active" {{ request('status') === 'active' ? 'selected' : '' }}>Active</option>
|
||||
<option value="inactive" {{ request('status') === 'inactive' ? 'selected' : '' }}>Inactive</option>
|
||||
</select>
|
||||
<button type="submit" class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Results -->
|
||||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow overflow-hidden">
|
||||
@forelse($operators as $operator)
|
||||
<div class="p-6 border-b border-gray-200 dark:border-gray-700">
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
|
||||
<a href="{{ route('operators.show', $operator) }}" class="hover:text-blue-600">
|
||||
{{ $operator->name }}
|
||||
</a>
|
||||
</h3>
|
||||
@if($operator->description)
|
||||
<p class="text-gray-600 dark:text-gray-400 mt-2">{{ $operator->description }}</p>
|
||||
@endif
|
||||
<div class="flex items-center mt-2 space-x-4">
|
||||
<span class="text-sm text-gray-500">
|
||||
{{ $operator->created_at->format('M j, Y') }}
|
||||
</span>
|
||||
<span class="px-2 py-1 text-xs rounded-full {{ $operator->is_active ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800' }}">
|
||||
{{ $operator->is_active ? 'Active' : 'Inactive' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex space-x-2">
|
||||
<a href="{{ route('operators.edit', $operator) }}" class="text-blue-600 hover:text-blue-800">Edit</a>
|
||||
<form action="{{ route('operators.destroy', $operator) }}" method="POST" class="inline">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="text-red-600 hover:text-red-800"
|
||||
onclick="return confirm('Are you sure?')">Delete</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="p-6 text-center text-gray-500 dark:text-gray-400">
|
||||
No operators found.
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
@if($operators->hasPages())
|
||||
<div class="mt-6">
|
||||
{{ $operators->links() }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endsection
|
||||
73
resources/views/operators/show.blade.php
Normal file
73
resources/views/operators/show.blade.php
Normal file
@@ -0,0 +1,73 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">{{ $operator->name }}</h1>
|
||||
<div class="flex space-x-2">
|
||||
<a href="{{ route('operators.edit', $operator) }}" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg">
|
||||
Edit
|
||||
</a>
|
||||
<a href="{{ route('operators.index') }}" class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg">
|
||||
Back to List
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">Details</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Name</label>
|
||||
<p class="text-gray-900 dark:text-white">{{ $operator->name }}</p>
|
||||
</div>
|
||||
|
||||
@if($operator->description)
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Description</label>
|
||||
<p class="text-gray-900 dark:text-white">{{ $operator->description }}</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Status</label>
|
||||
<span class="px-2 py-1 text-xs rounded-full {{ $operator->is_active ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800' }}">
|
||||
{{ $operator->is_active ? 'Active' : 'Inactive' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">Metadata</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Created</label>
|
||||
<p class="text-gray-900 dark:text-white">{{ $operator->created_at->format('F j, Y \at g:i A') }}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Last Updated</label>
|
||||
<p class="text-gray-900 dark:text-white">{{ $operator->updated_at->format('F j, Y \at g:i A') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end space-x-2 mt-6 pt-6 border-t border-gray-200 dark:border-gray-700">
|
||||
<form action="{{ route('operators.destroy', $operator) }}" method="POST" class="inline">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg"
|
||||
onclick="return confirm('Are you sure you want to delete this operator?')">
|
||||
Delete Operator
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user