TASKS 08 : Project Review & Desk Module Setup - RadLeoOFC/laravel-admin-panel GitHub Wiki

Project Report: Desk Module Implementation

1. Project Overview

Objective

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.

Key Features

  • A CRUD (Create, Read, Update, Delete) system for managing desks.
  • A structured database table to store desk information.
  • Laravel MVC (Model-View-Controller) implementation.

2. Project Setup & Environment

Environment Setup

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

Checking the correct environment setup (Laravel, PHP, MySQL).


3. Database Schema & Migration

Creating the Migration

To create the desks table, the following command was executed:

php artisan make:migration create_desks_table --create=desks

The generated migration file was updated as follows:

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 
    });
}

Executing the Migration

After editing, the migration was executed:

php artisan migrate

desks_table


4. Model Implementation

Creating the Model

The Desk model was generated using the following command:

php artisan make:model Desk

Defining Fillable Attributes

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'];
}

desk model


5. Controller & Routes

Generating the Controller

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

Desk Controller

Defining Routes

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

routes of desks


Understanding Route Functionality

Displaying All Desks

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'));
}

Creating a Desk

When navigating to /desks/create, the create method returns a form to create a new desk:

public function create()
{
    return view('desks.create');
}

Editing an Existing Desk

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'));
}

Explanation:

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

Desk edit form in the UI

Saving a New Desk

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');
}

Explanation

Validation

  • The name field is required and must be a string with a maximum length of 255 characters.
  • The location field is optional but must be a string with a maximum length of 255 characters if provided.
  • The status field must be either available or occupied or maintenance.

Storing the Desk Record

  • The method creates a new Desk record using mass assignment.

Redirecting the User

  • 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

Desk creation form in the UI

Updating Desk Information

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');
}

Explanation

Validation

The method first validates the incoming request to ensure:

  • The name field is required and must be a string with a maximum length of 255 characters.

  • The location field is optional but must be a string with a maximum length of 255 characters if provided.

  • The status field must be either available or occupied or maintenance.

Updating the Desk Record

After successful validation, the update method updates the existing Desk record using mass assignment.

Redirecting the User

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

Desk updated successfully

Deleting a Desk

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');
}

Explanation:

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

Warning before deletion ะพf desk

Desk after deliting


7. Views

Overview

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

Listing All Desks (index.blade.php)

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>

Explanation

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

Desks index page

Creating a New Desk (create.blade.php)

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>

Explanation

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

Create desk form in the UI

Editing an Existing Desk (edit.blade.php)

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>

Explanation

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

Edit desk form with dropping list


Summary

  • 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

Full Desk module views in the UI


8. Git Version Control

Initializing Git

To start tracking changes, initialize Git in the project directory:

git init

Adding and Committing Changes

Check the status of modified files:

git status

Add all changes and commit them:

git add .

git commit -m "Added Desk module with CRUD"

Pushing to GitHub

git push origin develop

The project was successfuly pushed on GitHub


Conclusion

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.


โš ๏ธ **GitHub.com Fallback** โš ๏ธ