How to build a Project Management App in Laravel 5 – Part 2
Let’s continue from our previous post.
We refreshed the page and it gave us an error because we deleted the view responsible for showing us the Laravel 5 page.
1. Create Home Controller and Index Template
You can run the artisan command like so:
1 |
php artisan make:controller HomeController |
..and that will create a HomeController.php file with some boilerplate methods for a basic CRUD operation on a controller.
OR
You can just create the HomeController.php file manually.
I created the HomeController.php file using the artisan command and I have added a line of code to the index function to return a view. Delete the other methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php namespace Prego\Http\Controllers; use Illuminate\Http\Request; use Prego\Http\Requests; use Prego\Http\Controllers\Controller; class HomeController extends Controller { /** * Displays the index page of the app * * @return Response */ public function index() { return view('index'); } } |
Let’s go to our routes.php.
Eliminate the code there and add this:
1 2 3 4 |
Route::get('/', [ 'uses' => 'Prego\Http\Controllers\HomeController@index', 'as' => 'index' ]); |
Let’s go ahead and create our index.blade.php in the resources/views folder.
index.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@extends('layouts.master') @section('content') <h1>Project Management for Human Beings</h1> <p>The promise of Prego is simple. All your projects and todos on one screen without having to filter by team or users. Finally, project management built just for humanbeings. Very Intuitve, Slick and crafted with the power of Laravel</p> <p><img src="{{ asset('images/projectmanagement.gif') }}" /></p> <a class="btn btn-large btn-info" href="/auth/register">Sign Up</a> <p class="login">Already signed up? <a class="btn btn-large btn-info" href="/auth/signin">Login</a></p> @stop |
Then create a layouts folder and inside the folder, create a master.blade.php file
master.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width"> <title>Prego - Project Management App</title> <meta name="description" content="Prego is a project management app built for learning purposes"> <!-- Typekit Fonts --> <script src="//use.typekit.net/udt8boc.js"></script> <script>try{Typekit.load();}catch(e){}</script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> </head> <body> <div class="container"> @yield('content') </div> </body> </html> |
Create a css and images folder within the public directory and create an app.css file in the css folder. projectmanagement.gif is just an image I downloaded. You can use any image for this, just make sure it is within the images folder.
In the master.blade.php, add this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width"> <title>Prego - Project Management App</title> <meta name="description" content="Prego is a project management app built for learning purposes"> <!-- Typekit Fonts --> <script src="//use.typekit.net/udt8boc.js"></script> <script>try{Typekit.load();}catch(e){}</script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> </head> <body> <div class="container"> @yield('content') </div> </body> </html> |
Now, let’s refresh our page, it should look like this:
Aha!!..Nice. We are getting somewhere but wait we have only just begun!
Now commit to git if you haven’t done that.
2. Create the alerts partial template
Head over to the layouts folder and create a partials folder within it. Now, this is where all our different partial templates would reside.
So the first partial template we’ll create would be alerts.blade.php. Go ahead and create it.
alerts.blade.php
1 2 3 4 5 |
@if ( session()->has('info')) <div class="alert alert-info" role-"alert"> {{ session()->get('info') }} </div> @endif |
All our status messages and notifications would be rendered with this template.
So, go to your master.blade.php and include the alerts template. Now your master.blade.php would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width"> <title>Prego - Project Management App</title> <meta name="description" content="Prego is a project management app built for learning purposes"> <!-- Typekit Fonts --> <script src="//use.typekit.net/udt8boc.js"></script> <script>try{Typekit.load();}catch(e){}</script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> </head> <body> <div class="container"> @include('layouts.partials.alerts') @yield('content') </div> </body> </html> |
4. Database Migrations
Now, it’s time for us to create our migrations for this project. These are the tables I have in mind.
Note: I haven’t pre-built this app, I am building as I am teaching, so some things might changes along the way but it’s
User table (users)
id
username
password
first_name
last_name
avatar_url
remember_token
timestamps – created_at, updated_at
Project table ( projects)
id
project_name
project_notes
project_status
user_id – ( Foreign Key )
due_date
timestamps – created_at, updated_at
Task table (tasks)
id
task_name
timestamps – created_at, updated_at
project_id
Todo table (todos)
id
todo_name
todo_description
todo_status
user_id ( Foreign Key )
due_date
timestamps – created_at, updated_at
Comment table (comments)
id
comments
project_id
user_id
timestamps – created_at, updated_at
File table ( files)
id
file_name
file_url
project_id
timestamps – created_at, updated_at
Project – Collaborators table ( project_collaborator )
id
project_id
collaborator_id
Let’s make our migrations now. Laravel has a command line tool where commands can be run to create migration files. Run all these commands from the terminal to create boilerplates for the different tables.
1 |
php artisan make:migration create_users_table |
1 |
php artisan make:migration create_projects_table |
1 |
php artisan make:migration create_tasks_table |
1 |
php artisan make:migration create_todos_table |
1 |
php artisan make:migration create_comments_table |
1 |
php artisan make:migration create_files_table |
1 |
php artisan make:migration create_projects_collaborators_table |
DATE_create_users_table.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?php use IlluminateDatabaseSchemaBlueprint; use IlluminateDatabaseMigrationsMigration; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function(Blueprint $table) { $table->increments('id')->unsigned(); $table->string('username')->unique(); $table->string('email')->unique(); $table->string('password'); $table->string('first_name')->nullable(); $table->string('last_name')->nullable(); $table->string('avatar_url')->nullable()->default(NULL); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('users'); } } |
DATE_projects_table.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<?php use IlluminateDatabaseSchemaBlueprint; use IlluminateDatabaseMigrationsMigration; class CreateProjectsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('projects', function(Blueprint $table) { $table->increments('id')->unsigned(); $table->string('project_name'); $table->longText('project_notes'); $table->string('project_status')->default('Upcoming'); $table->integer('user_id')->unsigned(); $table->date('due_date'); $table->timestamps(); $table->foreign('user_id') ->references('id')->on('users') ->onUpdate('cascade') ->onDelete('cascade'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('projects'); } } |
DATE_create_tasks_table.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?php use IlluminateDatabaseSchemaBlueprint; use IlluminateDatabaseMigrationsMigration; class CreateTasksTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('tasks', function(Blueprint $table) { $table->increments('id')->unsigned(); $table->longText('task_name'); $table->integer('project_id')->unsigned(); $table->timestamps(); $table->foreign('project_id') ->references('id')->on('projects') ->onUpdate('cascade') ->onDelete('cascade'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('tasks'); } } |
DATE_todos_table.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateTodosTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('todos', function(Blueprint $table) { $table->increments('id')->unsigned(); $table->string('todo_name'); $table->longText('todo_description'); $table->string('todo_status')->default('Will do'); $table->integer('user_id')->unsigned(); $table->date('due_date'); $table->timestamps(); $table->foreign('user_id') ->references('id')->on('users') ->onUpdate('cascade') ->onDelete('cascade'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('todos'); } } |
DATE_create_comments_table.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateCommentsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('comments', function(Blueprint $table) { $table->increments('id')->unsigned(); $table->longText('comments'); $table->integer('project_id')->unsigned(); $table->integer('user_id')->unsigned(); $table->timestamps(); $table->foreign('project_id') ->references('id')->on('projects') ->onUpdate('cascade') ->onDelete('cascade'); $table->foreign('user_id') ->references('id')->on('users') ->onUpdate('cascade') ->onDelete('cascade'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('comments'); } } |
DATE_create_files_table.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateFilesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('files', function(Blueprint $table) { $table->increments('id')->unsigned(); $table->string('file_name'); $table->mediumText('file_url'); $table->integer('project_id')->unsigned(); $table->timestamps(); $table->foreign('project_id') ->references('id')->on('projects') ->onUpdate('cascade') ->onDelete('cascade'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('files'); } } |
DATE_create_projects_collaborators_table.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateProjectsCollaboratorsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('project_collaborator', function($table) { $table->increments('id')->unsigned(); $table->integer('project_id')->unsigned(); $table->integer('collaborator_id')->unsigned(); $table->timestamps(); $table->foreign('project_id') ->references('id')->on('projects') ->onUpdate('cascade') ->onDelete('cascade'); $table->foreign('collaborator_id') ->references('id')->on('users') ->onUpdate('cascade') ->onDelete('cascade'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('project_collaborator'); } } |
Now, go ahead and run the migrations
1 |
php artisan migrate |
Make sure you have the database set in your .env file . Every Laravel project must have a .env file your database and secret credentials. This is mine currently. Remember to gitignore this file. It must not be pushed to GitHub because you don’t want others seeing your secret credentials.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
DB_HOST=localhost DB_DATABASE=prego DB_USERNAME=homestead DB_PASSWORD=secret CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=sync MAIL_DRIVER=smtp MAIL_HOST=mailtrap.io MAIL_PORT=2525 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null |
My username and password are homestead and secret respectively because I am using a homestead box
Check your database, All these tables would have been created now just by running a command. Awesome!
It’s good that you have gotten to this stage, there’s still more to explore. Let’s keep moving!.
Watch out for the next post!
Please if you have any questions or observations, feel free to drop it the comments section below.
- How to build your own Youtube – Part 10 - August 1, 2016
- How to build your own Youtube – Part 9 - July 25, 2016
- How to build your own Youtube – Part 8 - July 23, 2016
- How to build your own Youtube – Part 6 - July 6, 2016
- Introducing Laravel Password v1.0 - July 3, 2016
- How to build your own Youtube – Part 5 - June 28, 2016
- How to build your own Youtube – Part 4 - June 23, 2016
- How to build your own Youtube – Part 3 - June 15, 2016
- How to build your own Youtube – Part 2 - June 8, 2016
- How to build your own Youtube – Part 1 - June 1, 2016