Skip to main content

Command Palette

Search for a command to run...

Laravel 11 Workgroup: Creating Collaborative Environments (Linked By Email)

Updated
5 min read
Laravel 11 Workgroup: Creating Collaborative Environments (Linked By Email)
M

Mohamad's interest is in Programming (Mobile, Web, Database and Machine Learning). He is studying at the Center For Artificial Intelligence Technology (CAIT), Universiti Kebangsaan Malaysia (UKM).

that caters for different project requirements, communication styles, and workflow preferences.

[0] Create Laravel project with Auth API

Follow the previous article, or download a quick start project.

[1] Create migration

Run Artisan command:

php artisan make:migration create_workgroups_table

Edit the migration file.

(file → database\migrations\yyyy_mm_dd_hhmmss_create_workgroups_table.php)

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateWorkgroupsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('workgroups', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('refr');
            $table->text('desc');
            $table->string('locn');
            $table->integer('estartdate');
            $table->string('key1');
            $table->string('key2');
            $table->string('key3');
            $table->string('key4');
            $table->string('key5');
            $table->integer('n');
            $table->integer('admn');
            $table->integer('cord');
            $table->integer('oper');
            $table->integer('mngr');
            $table->string('mngr_email');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('workgroups');
    }
}

Create Workgroup model.

php artisan make:model Workgroup

Edit Workgroup model.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Workgroup extends Model
{
    use HasFactory;
    protected $fillable = [
        'name',
        'refr',
        'desc',
        'locn',
        'estartdate',
        'key1',
        'key2',
        'key3',
        'key4',
        'key5',
        'n',
        'admn',
        'cord',
        'oper',
        'mngr',
        'mngr_email',
    ];  
}

Run Artisan command to perform migration.

php artisan migrate

[2] Create Web Controller

Create controller script file

php artisan make:controller WorkgroupsController

Edit controller script file.

(file → app\Http\Controllers\WorkgroupsController.php)

<?php

namespace App\Http\Controllers;

use App\Models\Workgroup;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class WorkgroupsController extends Controller
{
    public function index()
    {
        $user = Auth::user();
        $workgroups = Workgroup::where('mngr_email', $user->email)
                               ->get();

        return view('workgroups.index', [
            'workgroups' => $workgroups,
        ]);
    }

    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required|string|max:255',
            'refr' => 'required|string',
            'desc' => 'required|string',
            'locn' => 'required|string',
            'estartdate' => 'required|integer',
            'key1' => 'required|string',
            'key2' => 'required|string',
            'key3' => 'required|string',
            'key4' => 'required|string',
            'key5' => 'required|string',
            'n' => 'required|integer',
        ]);

        $user = Auth::user();

        $workgroup = Workgroup::create([
            'mngr_email' => $user->email,
            'name' => $validatedData['name'],
            'refr' => $validatedData['refr'],
            'desc' => $validatedData['desc'],
            'locn' => $validatedData['locn'],
            'estartdate' => $validatedData['estartdate'],
            'key1' => $validatedData['key1'],
            'key2' => $validatedData['key2'],
            'key3' => $validatedData['key3'],
            'key4' => $validatedData['key4'],
            'key5' => $validatedData['key5'],
            'admn' => 0,
            'cord' => 0,
            'oper' => 0,
            'mngr' => $user->id,
            'n' => $validatedData['n'],
        ]);

        return redirect()->route('workgroups.index')
            ->with('success', 'Workgroup created successfully.');
    }
}

[3] Create Web View

This step assumes that you have integrated Breeze into your system. Refer to Blade Templates guide for more information about the package.

Edit workgroups.index:

(file → resources\views\workgroups\index.blade.php)

<x-app-layout>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            {{ __('Your Workgroups') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
            <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                <div class="p-6 text-gray-900">

                    <script>
                        document.addEventListener('DOMContentLoaded', function() {
                            const buttonShowFormNewWorkgroup = document.getElementById('buttonShowFormNewWorkgroup');
                            const formNewWorkgroup = document.getElementById('newWorkgroupForm1');
                            const buttonCancelFormNewWorkgroup = document.getElementById('buttonCancelFormNewWorkgroup');

                            buttonShowFormNewWorkgroup.addEventListener('click', function() {
                                formNewWorkgroup.classList.toggle('hidden');
                                buttonShowFormNewWorkgroup.classList.add('hidden');
                            });

                            buttonCancelFormNewWorkgroup.addEventListener('click', function() {
                                formNewWorkgroup.classList.toggle('hidden');
                                buttonShowFormNewWorkgroup.classList.remove('hidden');
                            });

                        });
                    </script>

                    @if (session('success'))
                    <div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative" role="alert">
                        <strong class="font-bold">Success!</strong>
                        <span class="block sm:inline">{{ session('success') }}</span>
                    </div>
                    @endif
                    <br/>

                    <x-primary-button id="buttonShowFormNewWorkgroup">
                        New Workgroup
                    </x-primary-button>


                    <div id="newWorkgroupForm1" class="w-full sm:max-w-md mt-6 px-6 py-4 bg-white shadow-md overflow-hidden sm:rounded-lg hidden">
                    <h2 class="font-semibold text-xl text-gray-800 leading-tight">
                        {{ __('New Workgroup') }}
                    </h2>
                    <form action="{{ route('workgroups.store') }}" method="POST">
                        @csrf
                        <div class="mb-4">
                            <label for="name" class="block text-gray-700 font-semibold mb-2">Name</label>
                            <input type="text" id="name" name="name" value="-" class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring focus:border-blue-300">
                        </div>
                        <div class="mb-4">
                            <label for="refr" class="block text-gray-700 font-semibold mb-2">Reference</label>
                            <input type="text" id="refr" name="refr" value="-" class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring focus:border-blue-300">
                        </div>
                        <div class="mb-4">
                            <label for="desc" class="block text-gray-700 font-semibold mb-2">Description</label>
                            <textarea id="desc" name="desc" class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring focus:border-blue-300">-</textarea>
                        </div>
                        <div class="mb-4">
                            <label for="locn" class="block text-gray-700 font-semibold mb-2">Location</label>
                            <input type="text" id="locn" name="locn" value="-" class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring focus:border-blue-300">
                        </div>
                        <div class="mb-4">
                            <label for="estartdate" class="block text-gray-700 font-semibold mb-2">Start Date</label>
                            <input type="number" id="estartdate" value="0" name="estartdate" class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring focus:border-blue-300">
                        </div>
                        <div class="mb-4">
                            <label for="key1" class="block text-gray-700 font-semibold mb-2">Key 1</label>
                            <input type="text" id="key1" name="key1" value="-" class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring focus:border-blue-300">
                        </div>
                        <div class="mb-4">
                            <label for="key2" class="block text-gray-700 font-semibold mb-2">Key 2</label>
                            <input type="text" id="key2" name="key2" value="-" class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring focus:border-blue-300">
                        </div>
                        <div class="mb-4">
                            <label for="key3" class="block text-gray-700 font-semibold mb-2">Key 3</label>
                            <input type="text" id="key3" name="key3" value="-" class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring focus:border-blue-300">
                        </div>
                        <div class="mb-4">
                            <label for="key4" class="block text-gray-700 font-semibold mb-2">Key 4</label>
                            <input type="text" id="key4" name="key4" value="-" class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring focus:border-blue-300">
                        </div>
                        <div class="mb-4">
                            <label for="key5" class="block text-gray-700 font-semibold mb-2">Key 5</label>
                            <input type="text" id="key5" name="key5" value="-" class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring focus:border-blue-300">
                        </div>
                        <div class="mb-4">
                            <label for="n" class="block text-gray-700 font-semibold mb-2">N</label>
                            <input type="number" id="n" name="n" value="0" class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring focus:border-blue-300">
                        </div>

                        <x-secondary-button id="buttonCancelFormNewWorkgroup">
                            Cancel
                        </x-secondary-button>

                        <x-primary-button id="buttonSaveFormNewWorkgroup" type="submit">
                            Save Workgroup
                        </x-primary-button>

                    </form>
                </div>

                @if ($workgroups->count() > 0)
                <div class="mt-4 space-y-4">
                    @foreach ($workgroups as $workgroup)
                    <div class="bg-white shadow-md rounded-lg p-4 border border-gray-300 border-solid border-1">
                        <div class="flex items-center justify-between">
                            <div>
                                <h5 class="font-semibold">{{ $workgroup->name }}</h5>
                                <p class="text-gray-600">{{ $workgroup->desc }}</p>
                                <p class="text-gray-600">Reference: {{ $workgroup->refr }}</p>
                                <p class="text-gray-600">Location: {{ $workgroup->locn }}</p>
                                <p class="text-gray-600">Start Date: {{ $workgroup->estartdate }}</p>
                                <p class="text-gray-600">Key 1: {{ $workgroup->key1 }}</p>
                                <p class="text-gray-600">Key 2: {{ $workgroup->key2 }}</p>
                                <p class="text-gray-600">Key 3: {{ $workgroup->key3 }}</p>
                                <p class="text-gray-600">Key 4: {{ $workgroup->key4 }}</p>
                                <p class="text-gray-600">Key 5: {{ $workgroup->key5 }}</p>
                                <p class="text-gray-600">N: {{ $workgroup->n }}</p>
                            </div>
                            <div class="space-x-2">
                                <a href="#" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
                                    Edit
                                </a>
                                <a href="#" class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">
                                    Delete
                                </a>
                            </div>
                        </div>
                    </div>
                    @endforeach
                </div>
                @else
                <p class="mt-4 text-gray-600">You haven't created any workgroups yet.</p>
                @endif

                </div>
            </div>
        </div>
    </div>


</x-app-layout>

Add the navigation link for the workgroups page in the navigation layout file:

(file →resources\views\layouts\navigation.blade.php)

                <!-- Navigation Links -->
                <div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
                    <x-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">
                        {{ __('Dashboard') }}
                    </x-nav-link>
                    <x-nav-link :href="route('workgroups.index')" :active="request()->routeIs('workgroups.*')">
                        {{ __('Workgroups') }}
                    </x-nav-link>
                </div>

[4] Update Web Route

...
use App\Http\Controllers\WorkgroupsController;
Route::get('/workgroups', [WorkgroupsController::class, 'index'])->name('workgroups.index');
Route::get('/workgroups/create', [WorkgroupsController::class, 'create'])->name('workgroups.create');
Route::post('/workgroups', [WorkgroupsController::class, 'store'])->name('workgroups.store');
...

[5] Test

Click New Workgroup button.

Enter details of the Workgroup e.g.:

  • Name = Group1

  • Description=This is Group1

Click Save Workgroup button.

Outcome:

Download:

https://archive.org/download/laravelprojects/lara11breeze_userapi_workgroups_20240409.zip

Further reading:

If you want to implement belongs_to and has_many relationship, refer https://hashnotes.hashnode.dev/laravel-11-workgroup-creating-collaborative-environments