Crud of books
books/index.php
<!-- resources/views/books/index.blade.php -->
<x-app-layout>
<div class="container mx-auto p-4">
<div class="flex justify-between items-center mb-4">
<h1 class="text-2xl font-bold">Books</h1>
<!-- Search Form -->
<form method="GET" action="{{ route('books.index') }}" class="flex items-center space-x-2">
<input type="text" name="search" value="{{ request('search') }}" placeholder="Search by title or author" class="px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
<button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded">Search</button>
@if(request('search'))
<a href="{{ route('books.index') }}" class="bg-gray-500 text-white px-4 py-2 rounded">Clear Search</a>
@endif
</form>
<a href="{{ route('books.create') }}" class="bg-blue-500 text-white px-4 py-2 rounded">Add New Book</a>
</div>
<table class="min-w-full bg-white border border-gray-200 rounded-lg">
<thead>
<tr class="w-full bg-gray-100 border-b border-gray-200">
<th class="py-2 px-4 text-left">ID</th>
<th class="py-2 px-4 text-left">Title</th>
<th class="py-2 px-4 text-left">Author</th>
<!-- th class="py-2 px-4 text-left">ISBN</>
<th class="py-2 px-4 text-left">Published Date</th -->
<th class="py-2 px-4 text-left">Status</th>
<th class="py-2 px-4 text-left">Actions</th>
</tr>
</thead>
<tbody>
@forelse ($books as $book)
<tr>
<td class="py-2 px-4 border-b">{{ $book->id }}</td>
<td class="py-2 px-4 border-b">{{ $book->title }}</td>
<td class="py-2 px-4 border-b">{{ $book->author }}</td>
<!-- td class="py-2 px-4 border-b">{{ $book->isbn }}</>
<td class="py-2 px-4 border-b">{{ \Carbon\Carbon::parse($book->published_date)->format('Y-m-d') }}</td -->
<td class="py-2 px-4 border-b">{{ ucfirst($book->status) }}</td>
<td class="py-2 px-4 border-b flex space-x-2">
<a href="{{ route('books.show', $book) }}" class="text-blue-500">View</a>
<a href="{{ route('books.edit', $book) }}" class="text-green-500">Edit</a>
<!-- Check Out / Return Buttons -->
@if ($book->status == 'available')
<form action="{{ route('books.checkout', $book->id) }}" method="POST">
@csrf
<button type="submit" class="text-yellow-500">Check Out</button>
</form>
@else
<form action="{{ route('books.return', $book->id) }}" method="POST">
@csrf
<button type="submit" class="text-green-500">Return</button>
</form>
@endif
<!-- Delete Form -->
<form action="{{ route('books.destroy', $book) }}" method="POST" class="inline">
@csrf
@method('DELETE')
<button type="submit" class="text-red-500">Delete</button>
</form>
</td>
</tr>
@empty
<tr>
<td colspan="7" class="py-2 px-4 text-center">No books found</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</x-app-layout>
books/show.blade.php
<!-- resources/views/books/show.blade.php -->
<x-app-layout>
<div class="container mx-auto p-4">
<h1 class="text-2xl font-bold mb-4">Book Details</h1>
<div class="bg-white p-6 border border-gray-200 rounded-lg">
<p><strong>ID:</strong> {{ $book->id }}</p>
<p><strong>Title:</strong> {{ $book->title }}</p>
<p><strong>Author:</strong> {{ $book->author }}</p>
<p><strong>ISBN:</strong> {{ $book->isbn }}</p>
<p><strong>Published Date:</strong> {{ \Carbon\Carbon::parse($book->published_date)->format('Y-m-d') }}</p>
<p><strong>Status:</strong> {{ ucfirst($book->status) }}</p>
<div class="mt-4">
<a href="{{ route('books.edit', $book) }}" class="bg-green-500 text-white px-4 py-2 rounded">Edit</a>
<a href="{{ route('books.index') }}" class="bg-gray-500 text-white px-4 py-2 rounded ml-4">Back to list</a>
<!-- Check Out / Return Buttons -->
@if ($book->status == 'available')
<form action="{{ route('books.checkout', $book) }}" method="POST" class="inline">
@csrf
<button type="submit" class="bg-yellow-500 text-white px-4 py-2 rounded ml-4">Check Out</button>
</form>
@else
<form action="{{ route('books.return', $book) }}" method="POST" class="inline">
@csrf
<button type="submit" class="bg-green-500 text-white px-4 py-2 rounded ml-4">Return</button>
</form>
@endif
</div>
</div>
</div>
</x-app-layout>
books/edit.blade.php
<!-- resources/views/books/edit.blade.php -->
<x-app-layout>
<div class="container mx-auto p-4">
<h1 class="text-2xl font-bold mb-4">Edit Book</h1>
<form action="{{ route('books.update', $book) }}" method="POST" class="bg-white p-6 border border-gray-200 rounded-lg">
@csrf
@method('PUT')
<div class="mb-4">
<label for="title" class="block text-sm font-medium text-gray-700">Title</label>
<input type="text" id="title" name="title" value="{{ old('title', $book->title) }}" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
@error('title')
<p class="text-red-500 text-sm">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<label for="author" class="block text-sm font-medium text-gray-700">Author</label>
<input type="text" id="author" name="author" value="{{ old('author', $book->author) }}" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
@error('author')
<p class="text-red-500 text-sm">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<label for="isbn" class="block text-sm font-medium text-gray-700">ISBN</label>
<input type="text" id="isbn" name="isbn" value="{{ old('isbn', $book->isbn) }}" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
@error('isbn')
<p class="text-red-500 text-sm">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<label for="published_date" class="block text-sm font-medium text-gray-700">Published Date</label>
<input type="date" id="published_date" name="published_date" value="{{ old('published_date', \Carbon\Carbon::parse($book->published_date)->format('Y-m-d')) }}" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
@error('published_date')
<p class="text-red-500 text-sm">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<label for="status" class="block text-sm font-medium text-gray-700">Status</label>
<select id="status" name="status" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
<option value="available" {{ old('status', $book->status) == 'available' ? 'selected' : '' }}>Available</option>
<option value="checked_out" {{ old('status', $book->status) == 'checked_out' ? 'selected' : '' }}>Checked Out</option>
</select>
@error('status')
<p class="text-red-500 text-sm">{{ $message }}</p>
@enderror
</div>
<button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded">Update Book</button>
<a href="{{ route('books.index') }}" class="ml-4 text-gray-600">Back to list</a>
</form>
</div>
</x-app-layout>
books/create.blade.php
<!-- resources/views/books/create.blade.php -->
<x-app-layout>
<div class="container mx-auto p-4">
<h1 class="text-2xl font-bold mb-4">Add New Book</h1>
<form action="{{ route('books.store') }}" method="POST" class="bg-white p-6 border border-gray-200 rounded-lg">
@csrf
<div class="mb-4">
<label for="title" class="block text-sm font-medium text-gray-700">Title</label>
<input type="text" id="title" name="title" value="{{ old('title') }}" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
@error('title')
<p class="text-red-500 text-sm">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<label for="author" class="block text-sm font-medium text-gray-700">Author</label>
<input type="text" id="author" name="author" value="{{ old('author') }}" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
@error('author')
<p class="text-red-500 text-sm">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<label for="isbn" class="block text-sm font-medium text-gray-700">ISBN</label>
<input type="text" id="isbn" name="isbn" value="{{ old('isbn') }}" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
@error('isbn')
<p class="text-red-500 text-sm">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<label for="published_date" class="block text-sm font-medium text-gray-700">Published Date</label>
<input type="date" id="published_date" name="published_date" value="{{ old('published_date') }}" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
@error('published_date')
<p class="text-red-500 text-sm">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<label for="status" class="block text-sm font-medium text-gray-700">Status</label>
<select id="status" name="status" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
<option value="available" {{ old('status') == 'available' ? 'selected' : '' }}>Available</option>
<option value="checked_out" {{ old('status') == 'checked_out' ? 'selected' : '' }}>Checked Out</option>
</select>
@error('status')
<p class="text-red-500 text-sm">{{ $message }}</p>
@enderror
</div>
<button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded">Add Book</button>
<a href="{{ route('books.index') }}" class="ml-4 text-gray-600">Back to list</a>
</form>
</div>
</x-app-layout>
Web.php
<?php
use App\Http\Controllers\ProfileController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BookController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::middleware(['auth' , 'verified'])->group(function () {
Route::get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
// Book management routes
Route::resource('books', BookController::class);
// Additional routes that require authentication
// For example, checking out and returning books
Route::post('books/{id}/checkout', [BookController::class, 'checkout'])->name('books.checkout');
Route::post('books/{id}/return', [BookController::class, 'return'])->name('books.return');
});
// Route::get('/dashboard', function () {
// return view('dashboard');
// })->middleware(['auth', 'verified'])->name('dashboard');
Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
});
require __DIR__.'/auth.php';
BookController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Book;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class BookController extends Controller
{
// GET /books
public function index(Request $request)
{
$query = $request->input('search');
// Filter books by title or author if search query is present
$books = Book::when($query, function($queryBuilder) use ($query) {
return $queryBuilder->where('title', 'like', "%{$query}%")
->orWhere('author', 'like', "%{$query}%");
})->get();
return view('books.index', compact('books'));
}
// GET /books/create
public function create()
{
return view('books.create');
}
// POST /books
public function store(Request $request)
{
$validatedData = $request->validate([
'title' => 'required|string|max:255',
'author' => 'required|string|max:255',
'isbn' => 'required|string|unique:books,isbn|max:13',
'published_date' => 'nullable|date',
'status' => 'required|in:available,checked_out',
]);
Book::create($validatedData);
return redirect()->route('books.index')->with('success', 'Book added successfully.');
}
// GET /books/{id}
public function show(Book $book)
{
return view('books.show', compact('book'));
}
// GET /books/{id}/edit
public function edit(Book $book)
{
return view('books.edit', compact('book'));
}
// PUT/PATCH /books/{id}
public function update(Request $request, Book $book)
{
$validatedData = $request->validate([
'title' => 'required|string|max:255',
'author' => 'required|string|max:255',
'isbn' => 'required|string|unique:books,isbn,' . $book->id . '|max:13',
'published_date' => 'nullable|date',
'status' => 'required|in:available,checked_out',
]);
$book->update($validatedData);
return redirect()->route('books.index')->with('success', 'Book updated successfully.');
}
// DELETE /books/{id}
public function destroy(Book $book)
{
$book->delete();
return redirect()->route('books.index')->with('success', 'Book deleted successfully.');
}
// POST /books/{id}/checkout
public function checkout($id)
{
// Find the book by ID
$book = Book::findOrFail($id);
$book->status = 'checked_out';
$book->update();
return redirect()->route('books.index')->with('success', 'Book checked out successfully.');
}
// POST /books/{id}/return
public function return($id)
{
// Find the book by ID
$book = Book::findOrFail($id);
$book->status = 'available';
$book->update();
return redirect()->route('books.index')->with('success', 'Book returned successfully.');
}
}
Models/Book.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
use HasFactory;
protected $fillable = [
'title',
'author',
'description',
'published_date',
'pages',
'isbn',
'status'
];
// If you have relationships, define them here
// e.g., public function user() { return $this->belongsTo(User::class); }
}
database/migration/bookmigration.php
Comments
Post a Comment
Please do not enter any spam link in the comment box.