TASKS 08 : Project Review & Desk Module Setup - RadLeoOFC/laravel-admin-panel GitHub Wiki
The primary goal of this project is to integrate a new Desk entity into an existing Laravel application. The Desk entity will be used for managing desks (workspaces) in an office, a coworking space, or any similar environment.
- A CRUD (Create, Read, Update, Delete) system for managing desks.
- A structured database table to store desk information.
- Laravel MVC (Model-View-Controller) implementation.
Before starting the development, the following technologies and tools were installed and configured:
- Laravel 10+ (PHP framework)
- PHP 8.1+ (Programming language)
- MySQL 8+ (Database)
- Composer (Dependency manager)
- VS Code / PHPStorm (Code editor)
- Postman (API Testing Tool)
Screenshot: Laravel version check command
php artisan --version
..jpg?raw=true)
To create the desks table, the following command was executed:
php artisan make:migration create_desks_table --create=desks
public function up()
{
Schema::create('desks', function (Blueprint $table) {
$table->id(); // Primary Key
$table->string('name'); // Desk Name
$table->string('location')->nullable(); // Location of the desk
$table->enum('status', ['available', 'occupied'])->default('available'); // Status
$table->timestamps(); // created_at & updated_at
});
}After editing, the migration was executed:
php artisan migrate

The Desk model was generated using the following command:
php artisan make:model Desk
In app/Models/Desk.php, the $fillable attributes were defined to allow mass assignment:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Desk extends Model
{
use HasFactory;
protected $fillable = ['name', 'location', 'status'];
}
To manage desk-related logic, a resource controller was created using the following command:
php artisan make:controller DeskController --resource
This command automatically generates a controller with predefined methods for handling CRUD operations.
The generated controller file app/Http/Controllers/DeskController.php contains the following methods:
namespace App\Http\Controllers;
<?php
<?php
namespace App\Http\Controllers;
use App\Models\Desk;
use Illuminate\Http\Request;
class DeskController extends Controller
{
/**
* Display a listing of the resource
*/
public function index()
{
$desks = Desk::all();
return view('desks.index', compact('desks'));
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view('desks.create');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'location' => 'required',
'status' => 'required',
]);
Desk::create($request->all());
return redirect()->route('desks.index')->with('success', 'Desk created successfully.');
}
/**
* Display the specified resource.
*/
public function show(Desk $desk)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Desk $desk)
{
return view('desks.edit', compact('desk'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, Desk $desk)
{
$request->validate([
'name' => 'required',
'location' => 'required',
'status' => 'required',
]);
$desk->update($request->all());
return redirect()->route('desks.index')->with('success', 'Desk updated successfully.');
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Desk $desk)
{
$desk->delete();
return redirect()->route('desks.index')->with('success', 'Desk deleted successfully.');
}
}
}Screenshot: Generated DeskController.php file in VS Code

In routes/web.php, a resourceful route was added:
use App\Http\Controllers\DeskController;
Route::resource('desks', DeskController::class);This route automatically maps the following endpoints to respective controller actions:
Each of these routes corresponds to a function inside the DeskController, automatically handling the necessary HTTP requests.
Screenshot: web.php route definition

When visiting /desks, the index method retrieves all desk records and passes them to the corresponding view:
public function index()
{
$desks = Desk::all();
return view('desks.index', compact('desks'));
}When navigating to /desks/create, the create method returns a form to create a new desk:
public function create()
{
return view('desks.create');
}When accessing /desks/{desk}/edit, the edit method fetches the desk's data and returns the edit form:
public function edit(Desk $desk)
{
return view('desks.edit', compact('desk'));
}Fetching the Desk Data:
The method retrieves the existing Desk record using route model binding. Returning the Edit View:
The method passes the Desk record to the edit view for editing.
Screenshot: Desk edit form in the UI

After submitting the create form, the store method is triggered via a POST request to /desks:
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'location' => 'nullable|string|max:255',
'status' => 'required|in:available,occupied'
]);
Desk::create($request->all());
return redirect()->route('desks.index')->with('success', 'Desk added successfully');
}-
The
namefield is required and must be a string with a maximum length of 255 characters. -
The
locationfield is optional but must be a string with a maximum length of 255 characters if provided. -
The
statusfield must be eitheravailableoroccupiedormaintenance.
- The method creates a new
Deskrecord using mass assignment.
- After storing the record, the user is redirected back to the list of desks with a success message.
Screenshot: Desk creation form in the UI

When submitting the edit form, the update method is triggered via a PUT/PATCH request to /desks/{desk}:
public function update(Request $request, Desk $desk)
{
$request->validate([
'name' => 'required|string|max:255',
'location' => 'nullable|string|max:255',
'status' => 'required|in:available,occupied'
]);
$desk->update($request->all());
return redirect()->route('desks.index')->with('success', 'Desk updated successfully');
}The method first validates the incoming request to ensure:
-
The
namefield is required and must be a string with a maximum length of 255 characters. -
The
locationfield is optional but must be a string with a maximum length of 255 characters if provided. -
The
statusfield must be eitheravailableoroccupiedormaintenance.
After successful validation, the update method updates the existing Desk record using mass assignment.
After updating the record, the user is redirected back to the list of desks with a success message.
Screenshot: Desk update form in the UI

When sending a DELETE request to /desks/{desk}, the destroy method is triggered to remove the desk:
public function destroy(Desk $desk)
{
$desk->delete();
return redirect()->route('desks.index')->with('success', 'Desk deleted successfully');
}Deleting the Desk Record:
The method finds the specified Desk record and calls the delete() method to remove it from the database.
Redirecting the User:
After deletion, the user is redirected back to the list of desks with a success message.
Screenshots: Delete confirmation dialog in the UI


In Laravel, views are responsible for rendering the user interface. They are stored in the resources/views/ directory and use Blade templating engine (.blade.php).
For the Desk module, three view files were created inside resources/views/desks/:
resources/views/desks/
โโโ index.blade.php โ View for listing all desks
โโโ create.blade.php โ View for creating a new desk
โโโ edit.blade.php โ View for editing an existing desk
This view displays all desks in a table with options to edit and delete each desk.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Desk List</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h1 class="mb-4">Desks</h1>
<a href="{{ route('desks.create') }}" class="btn btn-primary mb-3">Create New Desk</a>
@if(session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Location</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach ($desks as $desk)
<tr>
<td>{{ $desk->name }}</td>
<td>{{ $desk->location }}</td>
<td>{{ $desk->status }}</td>
<td>
<a href="{{ route('desks.edit', $desk->id) }}" class="btn btn-warning btn-sm">Edit</a>
<form action="{{ route('desks.destroy', $desk->id) }}" method="POST" class="d-inline">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure?')">Delete</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</body>
</html>The view extends layouts.app, ensuring a consistent layout. A button links to the create page (desks.create). It displays a success message if a desk is added, updated, or deleted. A table loops through $desks and displays each desk with edit and delete options. A confirmation dialog prevents accidental deletions.
Screenshot: Desk listing page in the UI

This view contains a form to add a new desk.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Create Desk</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h1>Create New Desk</h1>
<a href="{{ route('desks.index') }}" class="btn btn-secondary mb-3">Back to List</a>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('desks.store') }}" method="POST">
@csrf
<div class="mb-3">
<label class="form-label">Desk Name</label>
<input type="text" name="name" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Location</label>
<input type="text" name="location" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Status</label>
<select name="status" class="form-select">
<option value="available">Available</option>
<option value="occupied">Occupied</option>
<option value="maintenance">Maintenance</option>
</select>
</div>
<button type="submit" class="btn btn-success">Create Desk</button>
</form>
</div>
</body>
</html>A back button allows navigation back to the list (desks.index). If there are validation errors, they are displayed in an alert. The form uses POST and includes CSRF protection (@csrf). The status field uses a dropdown () to ensure valid inputs.
Screenshot: Create desk form in the UI

This view loads an existing desk's data into an editable form.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Edit Desk</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h1>Edit Desk</h1>
<a href="{{ route('desks.index') }}" class="btn btn-secondary mb-3">Back to List</a>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('desks.update', $desk->id) }}" method="POST">
@csrf
@method('PUT')
<div class="mb-3">
<label class="form-label">Desk Name</label>
<input type="text" name="name" class="form-control" value="{{ $desk->name }}" required>
</div>
<div class="mb-3">
<label class="form-label">Location</label>
<input type="text" name="location" class="form-control" value="{{ $desk->location }}" required>
</div>
<div class="mb-3">
<label class="form-label">Status</label>
<select name="status" class="form-select">
<option value="available" {{ $desk->status == 'available' ? 'selected' : '' }}>Available</option>
<option value="occupied" {{ $desk->status == 'occupied' ? 'selected' : '' }}>Occupied</option>
<option value="maintenance" {{ $desk->status == 'maintenance' ? 'selected' : '' }}>Maintenance</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Update Desk</button>
</form>
</div>
</body>
</html>The form is pre-filled with the desk's current data using value="{{ $desk->field }}".
The selected status is dynamically set with selected.
The form sends a PUT request using @method('PUT') to update the desk.
Screenshot: Edit desk form in the UI

- index.blade.php โ displays a list of desks with edit and delete buttons.
- create.blade.php โ provides a form for adding a new desk.
- edit.blade.php โ Loads existing desk data for editing.
Screenshot: Full Desk module views in the UI

git init
git status
git add .
git commit -m "Added Desk module with CRUD"
git push origin develop

In this project, a CRUD system for managing desks was successfully implemented using Laravel. The key takeaways include:
- Understanding Laravel migrations and models.
- Implementing a RESTful controller with CRUD methods.
- Creating views for user interaction.
- Managing database records efficiently.
This module can be extended with features like desk booking, user roles, and integration in future iterations.