Proyecto Sistema de Historia Clínica en Laravel



GitHub: petrix12 / Sistema-de-Historia-Cl-nica-en-Laravel
Proyecto Sistema de Historia Clínica en Laravel
===============================================


VIDEO 01:
GENERAR NUEVO PROYECTO LARAVEL
==============================
001. Crear proyecto:
$ composer create-project laravel/laravel clinic "5.7.*"

*** COMMIT 1: "Proyecto Laravel 5.7 nuevo" ***
*** Iniciar repositorio: $ git init ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Proyecto Laravel 5.7 nuevo" ***

VIDEO 02: 
*** Instalación de Laravel ***

VIDEO 03:
CREAR UN HOST VIRTUAL
=====================
002. Agregar el siguiente código al final del archivo C:\Windows\System32\drivers\etc\hosts
    # Host virtual para el proyecto Sistema de Historia Clínica en Laravel (Lado del cliente) 
    127.0.0.1 clinic.com
    NOTA: Editar con el block de notas en modo de administrador.

003. Agregar el siguiente código al final del archivo C:\xampp\apache\conf\extra\httpd-vhosts.conf
    # Host virtual para el proyecto Sistema de Historia Clínica en Laravel (Lado del servidor)
    <VirtualHost *:80>
        DocumentRoot "C:\xampp\htdocs\cursos\02laravel_clinic\clinic\public"
        ServerName clinic.com
    </VirtualHost>
    NOTA: En el archivo C:\xampp\apache\conf\httpd.conf las línea:
        Include conf/extra/httpd-vhosts.conf
    y
        LoadModule rewrite_module modules/mod_rewrite.so
    no deben estar comentada con #.

004. Reiniciar el servidor Apache.

CREAR SISTEMA DE AUTENTICACIÓN
==============================
005. En resources\views\welcome.blade.php cambiar Laravel por Historia Clínica App.

VIDEO 04:
006. Agregar la implementación MustVerifyEmail a la clase User de app\User.php
***
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;
***

007. Crear sistema de autenticación:
    $ php artisan make:auth

*** COMMIT 2: "Crear sistema autenticación" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Crear sistema autenticación" ***
*** Ver todos los commit's: $ git log --pretty=oneline ***

VIDEO 05:
CONFIGURAR BD
=============
008. Establecer juego de caracteres utf8_unicode_ci en config\database.php:
***
        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST''127.0.0.1'),
            'port' => env('DB_PORT''3306'),
            'database' => env('DB_DATABASE''forge'),
            'username' => env('DB_USERNAME''forge'),
            'password' => env('DB_PASSWORD'''),
            'unix_socket' => env('DB_SOCKET'''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
        ],
***

009. Configurar conexión de BD en archivo .env:
    ***
    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=clinic
    DB_USERNAME=root
    DB_PASSWORD=
    ***

010. Crear BD clinic en MySQL con el juego de caracteres utf8_unicode_ci

011. Ejecutar migración:
    $ php artisan migrate

*** COMMIT 3: "Configurar BD" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Configurar BD" ***

VERIFICACIÓN DE EMAIL
=====================
012. En routes\web.php reemplazar
Auth::routes();
    por
Auth::routes(['verify' => true]);

VIDEO 06:
*** Diseño de diagrama Entidad - Relación (E-R) ***
*** Se recomienda descargar yEd Graph Editor en https://www.yworks.com/downloads#yEd ***

VIDEO 07:
013. Registrarse el Mailtrap en https://mailtrap.io

014. Crear Inbox de nommbre clinic.

015. Copiar credenciales para Laravel y pegarlas en el archivo .env:
    ***
    MAIL_MAILER=smtp
    MAIL_HOST=smtp.mailtrap.io
    MAIL_PORT=2525
    MAIL_USERNAME=635f7f7d9b8246
    MAIL_PASSWORD=d9e996c89b4412
    MAIL_ENCRYPTION=tls
    ***

016. Registrar un usuario de prueba en nuestro proyecto.
    http://clinic.com/register

*** Ir a Mailtrap y verificar el email: https://mailtrap.io/signin ***
*** Resetear contraseña en el proyecto que estamos creando: http://clinic.com/password/reset ***

017. En el archivo .env cambiar la línea:
        APP_URL=http://localhost
    por
        APP_URL=http://clinic.com

*** COMMIT 4: "Verificación de email" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Verificación de email" ***

VIDEO 08:
*** Configuración de Desktop GitHub: ***
*** Descargar Desktop GitHub en https://desktop.github.com e instalar ***
*** En caso de haber iniciado el repositorio: $ git init ***
*** Ejecutar Desktop GitHub y añadir el repositorio del proyecto ***

VIDEO 09:
*** Establecer diagrama E-R para la estructura de roles y permisos. Parte I ***

VIDEO 10:
*** Establecer diagrama E-R para la estructura de roles y permisos. Parte II ***

ESTRUCTURA PARA SISTEMA DE ROLES Y PERMISOS
===========================================
018. Crear migración junto con su modelo de la tabla roles:
    $ php artisan make:model Role -m -c -r

VIDEO 11:
019. Crear migración junto con su modelo de la tabla permissions:
    $ php artisan make:model Permission -m -c -r

020. Modificar el método up en database\migrations\2021_01_31_192808_create_roles_table.php
    para agregar campos a la table roles:
    public function up()
    {
        Schema::create('roles'function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('slug')->unique();
            $table->string('description')->nullable();
            $table->timestamps();
        });
    }

VIDEO 12:
021. Establecer los atributos de asignación masiva y relaciones entre modelos en app\Role.php:
***
class Role extends Model
{
    // ATRIBUTOS DE ASIGNACIÓN MASIVA
    protected $fillable = [
        'name''description''slug'
    ];

    // RELACIONES ENTRE LOS MODELOS
    public function permissions(){
        // Relación uno a muchos
        return $this->hasMany('App\Permission');
    }

    public function users(){
        // Relación muchos a muchos
        return $this->belongsToMany('App\User');
    }
***

VIDEO 13:
022. Modificar el método up en database\migrations\2021_01_31_193703_create_permissions_table.php 
    para agregar campos a la table permissions:
    public function up()
    {
        Schema::create('permissions'function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('slug')->unique();
            $table->string('description')->nullable();
            $table->unsignedInteger('role_id');
            $table->foreign('role_id')->references('id')->on('roles')->onUpdate('cascade')->onDelete('cascade');
            $table->timestamps();
        });
    }

023. Establecer los atributos de asignación masiva y relaciones entre modelos en app\Permission.php:
***
class Permission extends Model
{
    // ATRIBUTOS DE ASIGNACIÓN MASIVA
    protected $fillable = [
        'name''slug''description''role_id'
    ];

    // RELACIONES ENTRE LOS MODELOS
    public function role(){
        // Relación muchos a uno
        return $this->belongsTo('App\Role');
    }

    public function users(){
        // Relación muchos a muchos
        return $this->belongsToMany('App\User')->withTimestamps();
    }
***

024. Establecer las relaciones entre modelos en app\User.php:
***
class User extends Authenticatable implements MustVerifyEmail
{
***
    // RELACIONES ENTRE LOS MODELOS
    public function permissions(){
        // Relación muchos a muchos
        return $this->belongsToMany('App\Permission');
    }

    public function roles(){
        // Relación muchos a muchos
        return $this->belongsToMany('App\Role')->withTimestamps();
    }
***

VIDEO 14:
025. Crear tabla pivote en la migración para role_user:
    $ php artisan make:migration create_role_user_table --create=role_user
    NOTA: incluir en la migración los campos:
    role_id int(10)
    user_id int(10)

026. Crear tabla pivote en la migración para permission_user:
    $ php artisan make:migration create_permission_user_table --create=permission_user
    NOTA: incluir en la migración los campos:
    permission_id int(10)
    user_id int(10)

027. Modificar el método up en database\migrations\2021_02_01_140320_create_role_user_table.php
    para agregar campos y restricciones a la table role_user:
    public function up()
    {
        Schema::create('role_user', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('role_id');
            $table->foreign('role_id')->references('id')->on('roles')->onUpdate('cascade')->onDelete('cascade');
            $table->unsignedInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
            $table->timestamps();
        });
    }

028. Modificar el método up en database\migrations\2021_02_01_140535_create_permission_user_table.php
    para agregar campos y restricciones a la table permission_user:
    public function up()
    {
        Schema::create('permission_user', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('permission_id');
            $table->foreign('permission_id')->references('id')->on('permissions')->onUpdate('cascade')->onDelete('cascade');
            $table->unsignedInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
            $table->timestamps();
        });
    }

029. Ejecutar migración:
    $ php artisan migrate

*** En caso de querer deshacer la migración ejecutar: ***
*** $ php artisan migrate:rollback ***

*** COMMIT 5: "Estructura para sistema de roles y permisos" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Estructura roles y permisos" ***

VIDEO 15:
*** Introducción a framework materialize y al motor de plantillas blade de laravel ***

VIDEO 16:
VISTAS Y DISEÑO DE PLANTILLAS
=============================
030. Descargar plantilla basada en el framework materialize en https://bit.ly/2NCb2rS

031. Crear directorios:
    resources\views\theme
    resources\views\theme\backoffice
    resources\views\theme\backoffice\layouts
    resources\views\theme\backoffice\layouts\includes
    resources\views\theme\backoffice\pages
    resources\views\theme\frontoffice
    resources\views\theme\frontoffice\layouts
    resources\views\theme\frontoffice\pages

032. Crear archivos:
    resources\views\theme\backoffice\layouts\admin.blade.php

033. Copiar el contenido del archivo index.html de la plantilla descargada en el archivo 
    admin.blade.php creado anteriormente y modificarla como se muestra a continuación:
{{-- 
    title
    head
    content
--}}
<!DOCTYPE html>
<html lang="es">
<head>
    <title>@yield('title')</title>
    @include('theme.backoffice.layouts.includes.head')
</head>
<body>
    @include('theme.backoffice.layouts.includes.loader')
    @include('theme.backoffice.layouts.includes.header')
    <div id="main">
        <div class="wrapper">
            @include('theme.backoffice.layouts.includes.left-sidebar')
            <section id="content">
                @include('theme.backoffice.layouts.includes.breadcrumbs')
                <div class="container">
                    @yield('content')
                </div>
            </section>
        </div>
    </div>
    @include('theme.backoffice.layouts.includes.footer')
    @include('theme.backoffice.layouts.includes.foot')
</body>
</html>

VIDEO 17:
*** Adaptación del archivo index.html de la plantilla de materialize a nuestro proyecto ***
*** soportes\template\index.html ***

VIDEO 18:
034. Crear directorios:
    public\assets
    public\assets\backoffice
    public\assets\backoffice\css
    public\assets\frontoffice\js
    public\assets\frontoffice
    public\assets\frontoffice\css
    public\assets\frontoffice\js
    public\assets\plugins


035. En el directorio public\assets\backoffice\css copiar todos los archivos css requeridos en 
    resources\views\theme\backoffice\layouts\admin.blade.php de la plantilla descargada
    anteriormente.

036. Copiar el contenido de la carpeta vendor de la plantilla en public\assets\plugins

037. En el directorio public\assets\backoffice\js copiar todos los archivos js requeridos en 
    resources\views\theme\backoffice\layouts\admin.blade.php de la plantilla descargada
    anteriormente.

VIDEO 19:
038. Crear resources\views\theme\backoffice\layouts\includes\head.blade.php
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="msapplication-tap-highlight" content="no">

<link href="{{ asset('assets\backoffice\css\materialize.css') }}" type="text/css" rel="stylesheet">
<link href="{{ asset('assets\backoffice\css\style.css') }}" type="text/css" rel="stylesheet">
<link href="{{ asset('assets\backoffice\css\custom.css') }}" type="text/css" rel="stylesheet">
<link href="{{ asset('assets\plugins\perfect-scrollbar\perfect-scrollbar.css') }}" type="text/css" rel="stylesheet">
<link href="{{ asset('assets\plugins\flag-icon\css\flag-icon.min.css') }}" type="text/css" rel="stylesheet">

@yield('head')

039. Crear resources\views\theme\backoffice\layouts\includes\loader.blade.php
<!-- Start Page Loading -->
<div id="loader-wrapper">
    <div id="loader"></div>
    <div class="loader-section section-left"></div>
    <div class="loader-section section-right"></div>
</div>
<!-- End Page Loading -->

040. Crear resources\views\theme\backoffice\layouts\includes\header.blade.php
<!-- START HEADER -->
<header id="header" class="page-topbar">
    <!-- start header nav-->
    <div class="navbar-fixed">
        <nav class="navbar-color gradient-45deg-light-blue-cyan">
            <div class="nav-wrapper">

                <ul class="left">
                    <li>
                        <h1 class="logo-wrapper">
                            <a href="{{ asset('index.php') }}" class="brand-logo darken-1">
                                <img src="{{ asset('assets\images\logo\materialize-logo.png') }}" alt="clinic logo">
                                <span class="logo-text hide-on-med-and-down">Clinic</span>
                            </a>
                        </h1>
                    </li>
                </ul>

                <div class="header-search-wrapper hide-on-med-and-down">
                    <i class="material-icons">search</i>
                    <input type="text" name="Search" class="header-search-input z-depth-2" placeholder="¿Qué deseas buscar?" />
                </div>

                <ul class="right hide-on-med-and-down">
                    <li>
                        <a href="javascript:void(0);" class="waves-effect waves-block waves-light toggle-fullscreen">
                            <i class="material-icons">settings_overscan</i>
                        </a>
                    </li>

                    <li>
                        <a href="javascript:void(0);" class="waves-effect waves-block waves-light profile-button" data-activates="profile-dropdown">
                            <span class="avatar-status avatar-online">
                                <img src="{{ asset('assets\images\avatar\avatar-7.png') }}" alt="avatar">
                                <i></i>
                            </span>
                        </a>
                    </li>
                </ul>

                <!-- profile-dropdown -->
                <ul id="profile-dropdown" class="dropdown-content">
                    <li>
                        <a href="#" class="grey-text text-darken-1">
                        <i class="material-icons">face</i> Perfil</a>
                    </li>
                    <li>
                        <a href="#" class="grey-text text-darken-1">
                        <i class="material-icons">settings</i> Ajustes</a>
                    </li>
                    <li>
                        <a href="#" class="grey-text text-darken-1">
                        <i class="material-icons">live_help</i> Ayuda</a>
                    </li>
                    <li class="divider"></li>
                    <li>
                        <a href="#" class="grey-text text-darken-1">
                        <i class="material-icons">keyboard_tab</i> Salir</a>
                    </li>
                </ul>
            </div>
        </nav>
    </div>
    <!-- end header nav-->
</header>
<!-- END HEADER -->

041. Crear resources\views\theme\backoffice\layouts\includes\left-sidebar.blade.php
<!-- START LEFT SIDEBAR NAV-->
<aside id="left-sidebar-nav">
    <ul id="slide-out" class="side-nav fixed leftside-navigation">
        <li class="user-details cyan darken-2">
            <div class="row">
                <div class="col col s4 m4 l4">
                    <img src="{{ asset('assets\images\avatar\avatar-7.png') }}" alt="" class="circle responsive-img valign profile-image cyan">
                </div>
                <div class="col col s8 m8 l8">
                    <ul id="profile-dropdown-nav" class="dropdown-content">
                        <li>
                            <a href="#" class="grey-text text-darken-1">
                            <i class="material-icons">face</i> Perfil</a>
                        </li>
                        <li>
                            <a href="#" class="grey-text text-darken-1">
                            <i class="material-icons">settings</i> Ajustes</a>
                        </li>
                        <li>
                            <a href="#" class="grey-text text-darken-1">
                            <i class="material-icons">live_help</i> Ayuda</a>
                        </li>
                        <li class="divider"></li>
                        <li>
                            <a href="#" class="grey-text text-darken-1">
                            <i class="material-icons">keyboard_tab</i> Salir</a>
                        </li>
                    </ul>
                    <a class="btn-flat dropdown-button waves-effect waves-light white-text profile-btn" href="#" data-activates="profile-dropdown-nav">Pedro<i class="mdi-navigation-arrow-drop-down right"></i></a>
                    <p class="user-roal">Administrator</p>
                </div>
            </div>
        </li>

        <li class="no-padding">
            <ul class="collapsible" data-collapsible="accordion">
                <li class="bold">
                    <a href="{{ asset('index.php') }}" class="waves-effect waves-cyan">
                        <i class="material-icons">pie_chart_outlined</i>
                        <span class="nav-text">Panel de administración</span>
                    </a>
                </li>

                <li class="bold">
                    <a href="{{ route('backoffice.user.index') }}" class="waves-effect waves-cyan">
                        <i class="material-icons">people</i>
                        <span class="nav-text">Usuarios del sistema</span>
                    </a>
                </li>

                <li class="bold">
                    <a href="{{ route('backoffice.role.index') }}" class="waves-effect waves-cyan">
                        <i class="material-icons">perm_identity</i>
                        <span class="nav-text">Roles del sistema</span>
                    </a>
                </li>

                <li class="bold">
                    <a href="{{ route('backoffice.permission.index') }}" class="waves-effect waves-cyan">
                        <i class="material-icons">vpn_key</i>
                        <span class="nav-text">Permisos del sistema</span>
                    </a>
                </li>
            </ul>
        </li>
    </ul>
    <a href="#" data-activates="slide-out" class="sidebar-collapse btn-floating btn-medium waves-effect waves-light hide-on-large-only">
        <i class="material-icons">menu</i>
    </a>
</aside>
<!-- END LEFT SIDEBAR NAV-->

042. Crear resources\views\theme\backoffice\layouts\includes\footer.blade.php
<!-- START FOOTER -->
<footer class="page-footer gradient-45deg-light-blue-cyan">
    <div class="footer-copyright">
        <div class="container">
            <span>Copyright © 2020 - 
                <script type="text/javascript">
                    document.write(new Date().getFullYear());
                </script> 
            </span>
        </div>
    </div>
</footer>
<!-- END FOOTER -->

043. Crear resources\views\theme\backoffice\layouts\includes\foot.blade.php
<script src="{{ asset('assets\plugins\jquery-3.2.1.min.js') }}"></script>
<script src="{{ asset('assets\backoffice\js\materialize.min.js') }}"></script>
<script src="{{ asset('assets\plugins\perfect-scrollbar\perfect-scrollbar.min.js') }}"></script>
<script src="{{ asset('assets\backoffice\js\plugins.js') }}"></script>
<script src="{{ asset('assets\backoffice\js\custom-script.js') }}"></script>

{{-- <script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script> --}}
<script src="{{ asset('assets\swal\sweetalert2@10') }}"></script>
@include('sweetalert::alert')

@yield('foot')

VIDEO 20:
*** Insertar yield en resources\views\theme\backoffice\layouts\admin.blade.php ***
*** Insertar yield en resources\views\theme\backoffice\layouts\head.blade.php ***

044. Crear vista resources\views\theme\backoffice\pages\demo.blade.php
@extends('theme.backoffice.layouts.admin')

@section('title''Título de demo')

@section('head')
@endsection

@section('breadcrumbs')
    {{-- <li><a href="#">XYZ</a></li> --}}
@endsection

@section('dropdown_settings')
    {{-- <li><a href="#" class="grey-text text-darken-2">XYZ</a></li> --}}
@endsection

@section('content')
    <h3>Contenido de demo</h3>
    <p>Contenido 1</p>
    <p>Contenido 2</p>
@endsection

@section('foot')
@endsection

045. Agregar una ruta demo en routes\web.php
// *** PRUEBAS *** //
Route::get('demo'function () {
    return view('theme.backoffice.pages.demo');
});

VIDEO 21:
*** Pegar las carpeta fonts e images de la plantilla en public\assets y ***
*** adecuar todas las rutas de imagenes y fuentes. ***

*** COMMIT 6: "Vistas y diseño de plantillas" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Vistas y diseño de plantillas" ***

VIDEO 22:
CRUD ROLES
==========
046. Eliminar o comentar todas las rutas de routes\web.php, dejar solo:
Auth::routes(['verify' => true]);

*** Para ver las rutas existentes escribir ***
*** $ php artisan rout:list ***

047. Agregar la siguiente ruta a routes\web.php:
    // Grupo de rutas del backoffice
    Route::group(['middleware' => ['auth'], 'as' => 'backoffice.'], function(){
        // Route::get('role', 'RoleController@index')->name('role.index');
        Route::resource('role', 'RoleController');
    });
***
// Grupo de rutas del backoffice
Route::group(['middleware' => ['auth'], 'as' => 'backoffice.'], function(){
    *** 
    Route::resource('role''RoleController');
    ***
});
***

048. Modificar el método index del controlador app\Http\Controllers\RoleController.php
    public function index()
    {
        // dd(Role::all());
        // return 'Hola desde RoleController index';

        // Pendiente: añadir autorización
        return view('theme.backoffice.pages.role.index', [
            'roles' => Role::all(),
        ]);
    }

VIDEO 23:
049. Crear policia relacionada con el modelo Role:
    $ php artisan make:policy RolePolicy --model=Role

050. Registrar policia en app\Providers\AuthServiceProvider.php
***
class AuthServiceProvider extends ServiceProvider
{
    ***
    protected $policies = [
        //'App\Model' => 'App\Policies\ModelPolicy',
        'App\Role' => 'App\Policies\RolePolicy',
        'App\Permission' => 'App\Policies\PermissionPolicy',
    ];
    ***

051. En la clase RolePolicy de la policia app\Policies\RolePolicy.php modificar el método create:
    public function create(User $user)
    {
        // return $user->has_role('admin') && $user->has_permission('create-role');
        return true;
    }

VIDEO 24:
*** Diseño del formulario resources\views\theme\backoffice\pages\role\create.blade.php (Parte I) ***

052. Crear carpeta resources\views\theme\backoffice\pages\role

053. Crear archivo resources\views\theme\backoffice\pages\role\create.blade.php
    Basado en Materialize (https://materializecss.com/)
@extends('theme.backoffice.layouts.admin')

@section('title''Crear rol')

@section('head')
@endsection

@section('breadcrumbs')
    <li><a href="{{ route('backoffice.role.index') }}">Roles del sistema</a></li>
    <li>Crear rol</li>
@endsection

@section('content')
    <div class="section">
        <p class="caption">Introduce los datos para crear un nuevo rol</p>
        <div class="divider"></div>
        <div id="basic-form" class="section">
            <div class="row">
                <div class="col s12 m8 offset-m2">
                    <div class="card-panel">
                        <h4 class="header2">Crear rol</h4>
                        <div class="row">
                            <form class="col s12" method="post" action="{{ route('backoffice.role.store') }}">

                                {{ csrf_field() }}

                                <div class="row">
                                    <div class="input-field col s12">
                                        <input id="name" type="text" name="name">
                                        <label for="name">Nombre del rol</label>
                                        @if ($errors->has('name'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong style="color: red">{{ $errors->first('name'}}</strong>
                                            </span>
                                        @endif
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <textarea id="description" name="description" class="materialize-textarea"></textarea>
                                        <label for="description">Descripción del rol</label>
                                        @if ($errors->has('description'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong style="color: red">{{ $errors->first('description'}}</strong>
                                            </span>
                                        @endif
                                    </div>
                                    <div class="row">
                                        <div class="input-field col s12">
                                            <button class="btn waves-effect waves-light right" type="submit">Guardar
                                                <i class="material-icons right">send</i>
                                            </button>
                                        </div>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

@section('foot')
@endsection

054. Modificar el método create de la clase RoleController del controlador
    app\Http\Controllers\RoleController.php
    public function create()
    {
        return view('theme.backoffice.pages.role.create');
    }

VIDEO 25:
*** Diseño del formulario resources\views\theme\backoffice\pages\role\create.blade.php (Parte II) ***

055. Modificar el método store de la clase RoleController del controlador
    app\Http\Controllers\RoleController.php
    public function store(StoreRequest $requestRole $role)
    {
        // dd($request);
        $role = $role->store($request);
        // dd($role);
        // return 'Se ha almacenado el rol';
        return redirect()->route('backoffice.role.show'$role);
    }

VIDEO 26:
*** Configuración de Role/StoreRequest ***

056. Crear request para el método store del controlador Role:
    $ php artisan make:request Role/StoreRequest

057. Modificar el archivo app\Http\Requests\Role\StoreRequest.php
<?php

namespace App\Http\Requests\Role;

use App\Role;
use Illuminate\Foundation\Http\FormRequest;

class StoreRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|unique:roles|max:255',
            'description' => 'required',
        ];
    }

    public function messages(){
        return [
            'name.required' => 'El campo de nombre es requerido',
            'name.unique' => 'El nombre ya está ocupado',
            'description.required' => 'La descripción es requerida',
        ];
    }
}

058. Añadir el siguiente código en 'use' a app\Http\Controllers\RoleController.php:
    use App\Http\Requests\Role\StoreRequest;

VIDEO 27:
059. Establecer almacenamiento de registros en app\Role.php creando el método store:
    // ALMACENAMIENTO
    public function store($request){
        $slug = str_slug($request->name'-');
        // Alert::alert('Éxito', 'El rol se ha guardado', 'success')->showConfirmButton();
        // toast('El rol se ha guardado','success','top-right');
        alert('Éxito''Rol guardado''success')->showConfirmButton();
        return self::create($request->all() + [
            'slug' => $slug,
        ]);
    }

VIDEO 28:
060. Crear archivo resources\views\theme\backoffice\pages\role\show.blade.php
    Basado en Materialize (https://materializecss.com/)
@extends('theme.backoffice.layouts.admin')

@section('title'$role->name)

@section('head')
@endsection

@section('breadcrumbs')
    <li><a href="{{ route('backoffice.role.index') }}">Roles del sistema</a></li>
    <li>{{ $role->name }}</li>
@endsection

@section('content')
    <div class="section">
        <p class="caption"><strong>Rol:</strong> {{ $role->name }}</p>
        <div class="divider"></div>
        <div id="basic-form" class="section">
            <div class="row">
                <div class="col s12 m8 offset-m2">
                    <div class="card-panel">
                        <h4 class="header2">Usuarios con el rol de {{ $role->name }}</h4>
                        <div class="row">
                            <p><strong>Slug:</strong> {{ $role->slug }}</p>
                            <p><strong>Descripción:</strong> {{ $role->description }}</p>
                            <div class="card-action">
                                <a href="{{ route('backoffice.role.edit', $role}}">EDITAR</a>
                                <a href="#" style="color: red" onclick="enviar_formulario()">ELIMINAR</a>
                            </div>
                        </div>
                    </div>
                    <div class="card-panel">
                        <div class="row">
                            <div class="col s12 m8 offset-m2">
                                <div class="card-panel">
                                    <h4 class="header2">Permisos del rol</h4>
            
                                    <table>
                                        <thead>
                                            <tr>
                                                <th>Nombre</th>
                                                <th>Slug</th>
                                                <th>Descripción</th>
                                                <th>Acciones</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            @foreach($permissions as $permission)
                                            <tr>
                                                <td><a href="{{ route('backoffice.permission.show', $permission}}">{{ $permission->name }}</a></td>
                                                <td>{{ $permission->slug }}</td>
                                                <td>{{ $permission->description }}</td>
                                                <td><a href="{{ route('backoffice.permission.edit', $permission}}">Editar</a></td>
                                            </tr>
                                            @endforeach
                                        </tbody>
                                    </table>
                                    
                                </div>
                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </div>
    </div>
    <form method="post" action="{{ route('backoffice.role.destroy', $role}}" name="delete_form">
        {{ csrf_field() }}
        {{ method_field('DELETE'}}
    </form>
@endsection

@section('foot')
    <script>
        function enviar_formulario(){
            Swal.fire({
                title: "¿Deseas eliminar este rol?",
                text: "Esta acción no se puede deshacer",
                type: "warning",
                showCancelButton: true,
                confirmButtonText: "Si, continuar",
                cancelButtonText: "No, cancelar",
                closeOnCancel: false,
                closeOnConfirm: true
            }).then((result=> {
                if(result.value){
                    document.delete_form.submit();
                }else{
                    Swal.fire(
                        'Operación cancelada',
                        'Registro no eliminado',
                        'error'
                    );
                }
            });
            // document.delete_form.submit();
        }
    </script>
@endsection

VIDEO 29:
*** Rediseño del método index del controlador app\Http\Controllers\RoleController.php ***

061. Crear archivo resources\views\theme\backoffice\pages\role\index.blade.php
    Basado en Materialize (https://materializecss.com/)
@extends('theme.backoffice.layouts.admin')

@section('title''Roles del sistema')

@section('head')
@endsection

@section('breadcrumbs')
    <li><a href="{{ route('backoffice.role.index') }}">Roles del sistema</a></li>
@endsection

@section('dropdown_settings')
    <li><a href="{{ route('backoffice.role.create') }}" class="grey-text text-darken-2">Crear rol</a></li>
@endsection

@section('content')
<div class="section">
    <p class="caption"><strong>Roles del sistema</strong></p>
    <div class="divider"></div>
    <div id="basic-form" class="section">
        <div class="row">
            <div class="col s12 m12">
                <div class="card-panel">
                    <div class="row">
                        <table>
                            <thead>
                                <tr>
                                    <th>Nombre</th>
                                    <th>Slug</th>
                                    <th>Descripción</th>
                                    <th>Acciones</th>
                                </tr>
                            </thead>
                            <tbody>
                                @foreach($roles as $role)
                                <tr>
                                    <td><a href="{{ route('backoffice.role.show', $role}}">{{ $role->name }}</a></td>
                                    <td>{{ $role->slug }}</td>
                                    <td>{{ $role->description }}</td>
                                    <td><a href="{{ route('backoffice.role.edit', $role}}">Editar</a></td>
                                </tr>
                                @endforeach
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

@section('foot')
@endsection

VIDEO 30:
061. Crear archivo resources\views\theme\backoffice\pages\role\edit.blade.php
    Basado en Materialize (https://materializecss.com/)
@extends('theme.backoffice.layouts.admin')

@section('title''Editar rol: ' . $role->name)

@section('head')
@endsection

@section('breadcrumbs')
    <li><a href="{{ route('backoffice.role.index') }}">Roles del sistema</a></li>
    <li><a href="{{ route('backoffice.role.show', $role}}">{{ $role->name }}</a></li>
    <li>Edición de rol</li>
@endsection

@section('content')
    <div class="section">
        <p class="caption">Edición del rol {{ $role->name }}</p>
        <div class="divider"></div>
        <div id="basic-form" class="section">
            <div class="row">
                <div class="col s12 m8 offset-m2">
                    <div class="card-panel">
                        <h4 class="header2">Editar rol</h4>
                        <div class="row">
                            <form class="col s12" method="post" action="{{ route('backoffice.role.update', $role}}">

                                {{ csrf_field() }}

                                {{ method_field('PUT'}}

                                <div class="row">
                                    <div class="input-field col s12">
                                        <input id="name" type="text" name="name" value="{{ $role->name }}">
                                        <label for="name">Nombre del rol</label>
                                        @if ($errors->has('name'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong style="color: red">{{ $errors->first('name'}}</strong>
                                            </span>
                                        @endif
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <textarea id="description" name="description" class="materialize-textarea">{{ $role->description }}</textarea>
                                        <label for="description">Descripción del rol</label>
                                        @if ($errors->has('description'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong style="color: red">{{ $errors->first('description'}}</strong>
                                            </span>
                                        @endif
                                    </div>
                                    <div class="row">
                                        <div class="input-field col s12">
                                            <button class="btn waves-effect waves-light right" type="submit">Actualizar
                                                <i class="material-icons right">send</i>
                                            </button>
                                        </div>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

@section('foot')
@endsection

062. Modificar el método edit de la clase RoleController del controlador
    app\Http\Controllers\RoleController.php
    public function edit(Role $role)
    {
        return view('theme.backoffice.pages.role.edit', [
            'role' => $role,
        ]);
    }

063. Modificar el método update de la clase RoleController del controlador
    app\Http\Controllers\RoleController.php
    public function update(UpdateRequest $requestRole $role)
    {
        // dd($request, 'Validación exitosa');
        $role->my_update($request);
        return redirect()->route('backoffice.role.show'$role);
    }

VIDEO 31:
064. Crear request para el método update del controlador Role:
    $ php artisan make:request Role/UpdateRequest

065. Modificar el archivo app\Http\Requests\Role\UpdateRequest.php
<?php

namespace App\Http\Requests\Role;

use Illuminate\Foundation\Http\FormRequest;

class UpdateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        //dd($this->route('role'));
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' =>  'required|unique:roles,name,' . $this->route('role')->id . '|max:255',
            'description' => 'required',
        ];
    }

    public function messages(){
        return [
            'name.required' => 'El campo de nombre es requerido',
            'name.unique' => 'El nombre ya está ocupado',
            'description.required' => 'La descripción es requerida',
        ];
    }
}

066. Añadir el siguiente código en 'use' a app\Http\Controllers\RoleController.php:
    use App\Http\Requests\Role\UpdateRequest;

VIDEO 32:
*** Culminación del diseño del método update del controlador app\Http\Controllers\RoleController.php ***

067. Establecer actualización de registros en app\Role.php creando el método my_update:
    // ALMACENAMIENTO
    ***
    public function my_update($request){
        $slug = str_slug($request->name'-');
        self::update($request->all() + [
            'slug' => $slug,
        ]);
        alert('Éxito''Rol actualizado''success')->showConfirmButton();
    }

VIDEO 33:
*** Inducción a la Libreria SweetAlert ***
*** https://github.com/realrashid/sweet-alert ***
*** https://realrashid.github.io/sweet-alert/ ***
*** https://github.com/sweetalert2/sweetalert2 ***
*** https://sweetalert2.github.io/ ***

068. Instalación de la Libreria SweetAlert:
    $ composer require realrashid/sweet-alert

*** Se incorpora @include('sweetalert::alert') ***
*** en resources\views\theme\backoffice\layouts\includes\foot.blade.php ***

069. Para configurar la Libreria SweetAlert:
    $ php artisan sweetalert:publish

070. Incorporar en app\Role.php
    Use Alert;

VIDEO 34:
*** Como invocar la libreria SweetAlert de forma local ***

VIDEO 35:
*** Adecuación del archivo resources\views\theme\backoffice\pages\role\show.blade.php ***
*** para eliminar registro ***

VIDEO 36:
071. Modificar el método destroy de la clase RoleController del controlador
    app\Http\Controllers\RoleController.php
    public function destroy(Role $role)
    {
        // Pendiente: añadir autorización
        // dd($role);
        $role->delete();  
        alert('Éxito''Rol eliminado''success')->showConfirmButton();
        return redirect()->route('backoffice.role.index');
    }

VIDEO 37:
*** Observaciones a ciertas estandarizaciones de Materialize ***
*** Vaciar table roles ***

072. Crear archivo resources\views\theme\backoffice\layouts\includes\breadcrumbs.blade.php
    Basado en Materialize (https://materializecss.com/)
<div id="breadcrumbs-wrapper">
    <!-- Search for small screen -->
    <div class="header-search-wrapper grey lighten-2 hide-on-large-only">
        <input type="text" name="Search" class="header-search-input z-depth-2" placeholder="Explore Materialize">
    </div>
    <div class="container">
        <div class="row">
            <div class="col s10 m6 l6">
                <h5 class="breadcrumbs-title">@yield('title')</h5>
                <ol class="breadcrumbs">
                    <li><a href="#">Panel de Administración</a></li>
                    @yield('breadcrumbs')
                </ol>
            </div>
            <div class="col s2 m6 l6">
                <a class="btn dropdown-settings waves-effect waves-light breadcrumbs-btn right" href="#!" data-activates="dropdown1">
                    <i class="material-icons hide-on-med-and-up">settings</i>
                    <span class="hide-on-small-onl">Acciones</span>
                    <i class="material-icons right">arrow_drop_down</i>
                </a>
                <ul id="dropdown1" class="dropdown-content">
                    @yield('dropdown_settings')
                </ul>
            </div>
        </div>
    </div>
</div>

*** COMMIT 7: "CRUD de roles" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "CRUD de roles" ***

VIDEO 38:
*** Repaso de la estructura y documentación del proyecto ***

VIDEO 39:
CRUD PERMISOS
=============
073. Definir ruta en grupo de backoffice del archivo routes\web.php
// Grupo de rutas del backoffice
Route::group(['middleware' => ['auth'], 'as' => 'backoffice.'], function(){
    *** 
    Route::resource('permission''PermissionController');
});


074. Crear policia relacionada con el modelo Permission:
    $ php artisan make:policy PermissionPolicy --model=Permission

075. Registrar policia del modelo Permission en app\Providers\AuthServiceProvider.php
    ***
    protected $policies = [
        ***
        'App\Permission' => 'App\Policies\PermissionPolicy',
    ];
    ***

076. Crear directorio resources\views\theme\backoffice\pages\permission

077. Crear los archivos de vistas del CRUD permisos:
    resources\views\theme\backoffice\pages\permission\create.blade.php
    resources\views\theme\backoffice\pages\permission\edit.blade.php
    resources\views\theme\backoffice\pages\permission\index.blade.php
    resources\views\theme\backoffice\pages\permission\show.blade.php

VIDEO 40:
*** Trabajar vista y método create de permisos ***

078. Modificar el método create del controlador app\Http\Controllers\PermissionController.php
    public function create()
    {
        return view('theme.backoffice.pages.permission.create', [
            'roles' => Role::all()
        ]);
    }

079. Editar vista resources\views\theme\backoffice\pages\permission\create.blade.php
@extends('theme.backoffice.layouts.admin')

@section('title''Crear permiso')

@section('head')
@endsection

@section('breadcrumbs')
    {{-- <li><a href="{{ route('backoffice.role.index') }}">Roles del sistema</a></li> --}}
    <li>Crear permiso</li>
@endsection

@section('content')
    <div class="section">
        <p class="caption">Introduce los datos para crear un nuevo permiso</p>
        <div class="divider"></div>
        <div id="basic-form" class="section">
            <div class="row">
                <div class="col s12 m8 offset-m2">
                    <div class="card-panel">
                        <h4 class="header2">Crear permiso</h4>
                        <div class="row">
                            <form class="col s12" method="post" action="{{ route('backoffice.permission.store') }}">

                                {{ csrf_field() }}

                                <div class="row">
                                    <div class="input-field col s12">
                                        <input id="name" type="text" name="name">
                                        <label for="name">Nombre del permiso</label>
                                        @if ($errors->has('name'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong style="color: red">{{ $errors->first('name'}}</strong>
                                            </span>
                                        @endif
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <select name="role_id">
                                            <option value="" disabled selected>Selecciona un rol</option>
                                            @foreach($roles as $role)
                                                <option value="{{ $role->id }}">{{ $role->name }}</option>
                                            @endforeach
                                        </select>
                                        @if ($errors->has('role_id'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong style="color: red">{{ $errors->first('role_id'}}</strong>
                                            </span>
                                        @endif
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <textarea id="description" name="description" class="materialize-textarea"></textarea>
                                        <label for="description">Descripción del permiso</label>
                                        @if ($errors->has('description'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong style="color: red">{{ $errors->first('description'}}</strong>
                                            </span>
                                        @endif
                                    </div>
                                    <div class="row">
                                        <div class="input-field col s12">
                                            <button class="btn waves-effect waves-light right" type="submit">Guardar
                                                <i class="material-icons right">send</i>
                                            </button>
                                        </div>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

@section('foot')
@endsection

080. Modificar el método store del controlador app\Http\Controllers\PermissionController.php
    public function store(StoreRequest $requestPermission $permission)
    {
        // dd($request);
        $permission = $permission->store($request);
        // dd('El permiso se ha creado');
        return redirect()->route('backoffice.permission.show'$permission);
    }

VIDEO 41:
081. Crear request para el método store del controlador Permission:
    $ php artisan make:request Permission/StoreRequest

082. Incluir llamada del request en el controlador app\Http\Controllers\PermissionController.php
    use App\Http\Requests\Permission\StoreRequest;

083. Agregar método store al modelo app\Permission.php
    // ALMACENAMIENTO
    public function store($request){
        $slug = str_slug($request->name'-');
        alert('Éxito''Permiso guardado''success')->showConfirmButton();
        return self::create($request->all() + [
            'slug' => $slug,
        ]);
    }

084. Modificar el método authorize de la clase app\Http\Requests\Permission\StoreRequest.php
    public function authorize()
    {
        return true;
    }

085. Editar el archivo app\Http\Requests\Permission\StoreRequest.php
<?php

namespace App\Http\Requests\Permission;

use App\Permission;
use Illuminate\Foundation\Http\FormRequest;

class StoreRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|unique:roles|max:255',
            'description' => 'required',
            'role_id' => 'required|numeric'
        ];
    }

    public function messages(){
        return [
            'name.required' => 'El campo de nombre es requerido',
            'name.unique' => 'El nombre ya está ocupado',
            'description.required' => 'La descripción es requerida',
            'role_id.required' => 'El campo de rol es requerido',
            'role_id.numeric' => 'El formato no es correcto'
        ];
    }
}

VIDEO 42:
086. Modificar el método show del controlador app\Http\Controllers\PermissionController.php
    public function show(Permission $permission)
    {
        return view('theme.backoffice.pages.permission.show', [
            'permission' => $permission,
        ]);
    }

087. Editar resources\views\theme\backoffice\pages\permission\show.blade.php
@extends('theme.backoffice.layouts.admin')

@section('title'$permission->name)

@section('head')
@endsection

@section('breadcrumbs')
    {{-- <li><a href="{{ route('backoffice.permission.index') }}">Permisos del sistema</a></li> --}}
    <li><a href="{{ route('backoffice.role.index') }}">Roles del sistema</a></li>
    <li><a href="{{ route('backoffice.role.show', $permission->role}}">Rol: {{ $permission->role->name }}</a></li>
    <li>{{ $permission->name }}</li>
@endsection

@section('content')
    <div class="section">
        <p class="caption"><strong>Permiso:</strong> {{ $permission->name }}</p>
        <div class="divider"></div>
        <div id="basic-form" class="section">
            <div class="row">
                <div class="col s12 m8 offset-m2">
                    <div class="card-panel">
                        <h4 class="header2">Usuarios con el permiso de {{ $permission->name }}</h4>
                        <div class="row">
                            <p><strong>Slug:</strong> {{ $permission->slug }}</p>
                            <p><strong>Descripción:</strong> {{ $permission->description }}</p>
                            <div class="card-action">
                                <a href="{{ route('backoffice.permission.edit', $permission}}">EDITAR</a>
                                <a href="#" style="color: red" onclick="enviar_formulario()">ELIMINAR</a>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <form method="post" action="{{ route('backoffice.permission.destroy', $permission}}" name="delete_form">
        {{ csrf_field() }}
        {{ method_field('DELETE'}}
    </form>
@endsection

@section('foot')
    <script>
        function enviar_formulario(){
            Swal.fire({
                title: "¿Deseas eliminar este permiso?",
                text: "Esta acción no se puede deshacer",
                type: "warning",
                showCancelButton: true,
                confirmButtonText: "Si, continuar",
                cancelButtonText: "No, cancelar",
                closeOnCancel: false,
                closeOnConfirm: true
            }).then((result=> {
                if(result.value){
                    document.delete_form.submit();
                }else{
                    Swal.fire(
                        'Operación cancelada',
                        'Registro no eliminado',
                        'error'
                    );
                }
            });
            // document.delete_form.submit();
        }
    </script>
@endsection

VIDEO 43:
088. Modificar el método index del controlador app\Http\Controllers\PermissionController.php
    public function index()
    {
        // Pendiente: añadir autorización
        return view('theme.backoffice.pages.permission.index', [
            'permissions' => Permission::all(),
        ]);
    }

089. Editar resources\views\theme\backoffice\pages\permission\index.blade.php
@extends('theme.backoffice.layouts.admin')

@section('title''Permisos del sistema')

@section('head')
@endsection

@section('breadcrumbs')
    <li><a href="{{ route('backoffice.permission.index') }}">Permisos del sistema</a></li>
@endsection

@section('dropdown_settings')
    <li><a href="{{ route('backoffice.permission.create') }}" class="grey-text text-darken-2">Crear permiso</a></li>
@endsection

@section('content')
<div class="section">
    <p class="caption"><strong>Permisos del sistema</strong></p>
    <div class="divider"></div>
    <div id="basic-form" class="section">
        <div class="row">
            <div class="col s12 m12">
                <div class="card-panel">
                    <div class="row">
                        <table>
                            <thead>
                                <tr>
                                    <th>Nombre</th>
                                    <th>Slug</th>
                                    <th>Descripción</th>
                                    <th>Rol</th>
                                    <th>Acciones</th>
                                </tr>
                            </thead>
                            <tbody>
                                @foreach($permissions as $permission)
                                <tr>
                                    <td><a href="{{ route('backoffice.permission.show', $permission}}">{{ $permission->name }}</a></td>
                                    <td>{{ $permission->slug }}</td>
                                    <td>{{ $permission->description }}</td>
                                    <td><a href="{{ route('backoffice.role.show', $permission->role}}">{{ $permission->role->name }}</a></td>
                                    <td><a href="{{ route('backoffice.permission.edit', $permission}}">Editar</a></td>
                                </tr>
                                @endforeach
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

@section('foot')
@endsection

VIDEO 44: 
090. Modificar el método edit del controlador app\Http\Controllers\PermissionController.php
    public function edit(Permission $permission)
    {
        return view('theme.backoffice.pages.permission.edit', [
            'permission' => $permission,
            'roles' => Role::all()
        ]);
    }

091. Editar resources\views\theme\backoffice\pages\permission\edit.blade.php
@extends('theme.backoffice.layouts.admin')

@section('title''Editar permiso ' . $permission->name)

@section('head')
@endsection

@section('breadcrumbs')
    {{-- <li><a href="{{ route('backoffice.role.index') }}">Roles del sistema</a></li> --}}
    <li>Editar permiso {{ $permission->name }} </li>
@endsection

@section('content')
    <div class="section">
        <p class="caption">Editar permiso</p>
        <div class="divider"></div>
        <div id="basic-form" class="section">
            <div class="row">
                <div class="col s12 m8 offset-m2">
                    <div class="card-panel">
                        <h4 class="header2">Editar permiso</h4>
                        <div class="row">
                            <form class="col s12" method="post" action="{{ route('backoffice.permission.update', $permission}}">

                                {{ csrf_field() }}
                                {{ method_field('PUT'}}

                                <div class="row">
                                    <div class="input-field col s12">
                                        <input id="name" type="text" name="name" value="{{ $permission->name }}">
                                        <label for="name">Nombre del permiso</label>
                                        @if ($errors->has('name'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong style="color: red">{{ $errors->first('name'}}</strong>
                                            </span>
                                        @endif
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <select name="role_id">
                                            <option value="{{ $permission->role->id }}" selected="">{{ $permission->role->name }}</option>
                                            @foreach($roles as $role)
                                                <option value="{{ $role->id }}">{{ $role->name }}</option>
                                            @endforeach
                                        </select>
                                        @if ($errors->has('role_id'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong style="color: red">{{ $errors->first('role_id'}}</strong>
                                            </span>
                                        @endif
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <textarea id="description" name="description" class="materialize-textarea">{{ $permission->description }}</textarea>
                                        <label for="description">Descripción del permiso</label>
                                        @if ($errors->has('description'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong style="color: red">{{ $errors->first('description'}}</strong>
                                            </span>
                                        @endif
                                    </div>
                                    <div class="row">
                                        <div class="input-field col s12">
                                            <button class="btn waves-effect waves-light right" type="submit">Actualizar
                                                <i class="material-icons right">send</i>
                                            </button>
                                        </div>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

@section('foot')
@endsection

092. Añadir clase Role al controlador app\Http\Controllers\PermissionController.php
    use App\Role;

093. Modificar el método update del controlador app\Http\Controllers\PermissionController.php
    public function update(UpdateRequest $requestPermission $permission)
    {
        // dd($request);
        $permission->my_update($request);
        return redirect()->route('backoffice.permission.show'$permission);
    }

VIDEO 45:
094. Establecer actualización de registros en app\Permissin.php creando el método my_update:
    // ALMACENAMIENTO
    ***
    public function my_update($request){
        $slug = str_slug($request->name'-');
        self::update($request->all() + [
            'slug' => $slug,
        ]);
        alert('Éxito''Permiso actualizado''success')->showConfirmButton();
    }  

VIDEO 46:
095. Crear request para el método update del controlador Permission:
    $ php artisan make:request Permission/UpdateRequest

096. Modificar el archivo app\Http\Requests\Permission\UpdateRequest.php
<?php

namespace App\Http\Requests\Permission;

use Illuminate\Foundation\Http\FormRequest;

class UpdateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|unique:roles|max:255',
            'description' => 'required',
            'role_id' => 'required|numeric'
        ];
    }

    public function messages(){
        return [
            'name.required' => 'El campo de nombre es requerido',
            'name.unique' => 'El nombre ya está ocupado',
            'description.required' => 'La descripción es requerida',
            'role_id.required' => 'El campo de rol es requerido',
            'role_id.numeric' => 'El formato no es correcto'
        ];
    }
}

097. Añadir el siguiente código en 'use' a app\Http\Controllers\PermissionController.php:
    use App\Http\Requests\Permission\UpdateRequest;

VIDEO 47:
098. Modificar el método destroy del controlador app\Http\Controllers\PermissionController.php
    public function destroy(Permission $permission)
    {
        $role = $permission->role;
        $permission->delete();  
        alert('Éxito''Permiso eliminado''success')->showConfirmButton();
        return redirect()->route('backoffice.role.show'$role);
    }

*** COMMIT 8: "CRUD de permisos" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "CRUD de permisos" ***

VIDEO 48:
*** Vaciar tablas de roles y permisos de la BD clinic ***

ASIGNACIÓN DE ROLES A USUARIOS
==============================
099. Crear rol de administrador:
    Rol: Administrador
    Descripción: Este es el rol que tiene todos los permisos dentro del sistema

VIDEO 49:
100. Crear controlador para el modelo app\User.php
    $ php artisan make:controller UserController -r

101. Crear carpeta resources\views\theme\backoffice\pages\user

102. Crear los archivos de vistas del CRUD usuarios:
    resources\views\theme\backoffice\pages\user\create.blade.php
    resources\views\theme\backoffice\pages\user\edit.blade.php
    resources\views\theme\backoffice\pages\user\index.blade.php
    resources\views\theme\backoffice\pages\user\show.blade.php

103. Editar resources\views\theme\backoffice\pages\user\index.blade.php
@extends('theme.backoffice.layouts.admin')

@section('title''Lista de usuarios')

@section('head')
@endsection

@section('breadcrumbs')
    <li><a href="{{ route('backoffice.user.index') }}">Usuarios del sistema</a></li>
@endsection

@section('dropdown_settings')
    <li><a href="{{ route('backoffice.user.create') }}" class="grey-text text-darken-2">Crear usuario</a></li>
@endsection

@section('content')
<div class="section">
    <p class="caption"><strong>Usuarios del sistema</strong></p>
    <div class="divider"></div>
    <div id="basic-form" class="section">
        <div class="row">
            <div class="col s12 m12">
                <div class="card-panel">
                    <div class="row">
                        <table>
                            <thead>
                                <tr>
                                    <th>Nombre</th>
                                    <th>Edad</th>
                                    <th>Correo</th>
                                    <th>Acciones</th>
                                </tr>
                            </thead>
                            <tbody>
                                @foreach($users as $user)
                                <tr>
                                    <td><a href="{{ route('backoffice.user.show', $user}}">{{ $user->name }}</a></td>
                                    <td>{{ $user->dob }}</td>
                                    <td>{{ $user->email }}</td>
                                    <td><a href="{{ route('backoffice.user.edit', $user}}">Editar</a></td>
                                </tr>
                                @endforeach
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

@section('foot')
@endsection

104. Modificar el método index del controlador app\Http\Controllers\UserController.php
    public function index()
    {
        return view('theme.backoffice.pages.user.index', [
            'users' => User::all(),
        ]);
    }

105. Agregar el la cabecera el modelo de usuario en el controlador app\Http\Controllers\UserController.php
    use App\User;

106. Definir grupo de rutas para el CRUD de usuarios en routes\web.php
// Grupo de rutas del backoffice
Route::group(['middleware' => ['auth'], 'as' => 'backoffice.'], function(){
    ***
    Route::resource('user''UserController');  
    ***
});


VIDEO 50:
107. Editar resources\views\theme\backoffice\pages\user\show.blade.php
@extends('theme.backoffice.layouts.admin')

@section('title'$user->name)

@section('head')
@endsection

@section('breadcrumbs')
    <li><a href="{{ route('backoffice.user.index') }}">Usuarios del sistema</a></li>
    <li>{{ $user->name }}</li>
@endsection

@section('content')
    <div class="section">
        <p class="caption"><strong>Usuario:</strong> {{ $user->name }}</p>
        <div class="divider"></div>
        <div id="basic-form" class="section">
            <div class="row">
                <div class="col s12 m8">
                    <div class="card-card">
                        <div class="card-content">
                            <span class="card-title">{{ $user->name }}</span>
                            {{-- <h4>Roles:</h4>
                            <ul>
                                @foreach($user->roles as $role)
                                    <li>{{ $role->name }}</li>
                                @endforeach
                            </ul> --}}
                        </div>
                        <div class="card-action">
                            <a href="{{ route('backoffice.user.edit', $user}}">EDITAR</a>
                            <a href="#" style="color: red" onclick="enviar_formulario()">ELIMINAR</a>
                        </div>
                    </div>
                </div>

                <div class="col s12 m4">
                    @include('theme.backoffice.pages.user.includes.user_nav')
                </div>
            </div>
        </div>
    </div>
    <form method="post" action="{{ route('backoffice.user.destroy', $user}}" name="delete_form">
        {{ csrf_field() }}
        {{ method_field('DELETE'}}
    </form>
@endsection

@section('foot')
    <script>
        function enviar_formulario(){
            Swal.fire({
                title: "¿Deseas eliminar a este usuario?",
                text: "Esta acción no se puede deshacer",
                type: "warning",
                showCancelButton: true,
                confirmButtonText: "Si, continuar",
                cancelButtonText: "No, cancelar",
                closeOnCancel: false,
                closeOnConfirm: true
            }).then((result=> {
                if(result.value){
                    document.delete_form.submit();
                }else{
                    Swal.fire(
                        'Operación cancelada',
                        'Registro no eliminado',
                        'error'
                    );
                }
            });
            // document.delete_form.submit();
        }
    </script>
@endsection

108. Modificar el método show del controlador app\Http\Controllers\UserController.php
    public function show(User $user)
    {
        return view('theme.backoffice.pages.user.show', [
            'user' => $user,
        ]);
    }

VIDEO 51:
109. Crear directorio resources\views\theme\backoffice\pages\user\includes

110. Crear plantilla resources\views\theme\backoffice\pages\user\includes\user_nav.blade.php
<div class="collection">
    {{-- <a href="#!" class="collection-item active">Alvin</a> --}}
    <a href="{{ route('backoffice.user.show', $user}}" class="collection-item active">{{ $user->name }}</a>
    <a href="{{ route('backoffice.user.assign_role', $user}}" class="collection-item">Asignar roles</a>
    <a href="{{ route('backoffice.user.assign_permission', $user}}" class="collection-item">Asignar permisos</a>
</div>

111. Crear método (assign_role) para mostrar formulario para asignar rol en el controlador
    app\Http\Controllers\UserController.php
    /*
    * Mostrar formulario para asignar roles
    */
    public function assign_role(User $user){
        return view('theme.backoffice.pages.user.assign_role', [
            'user' => $user,
            'roles' => Role::all()
        ]);
    }

112. Crear método (role_assignment) para asignar los roles en la bd en el controlador
    app\Http\Controllers\UserController.php
    /*
    * Asignar los roles en la tabla pivote o intermedia de la base de datos
    */
    public function role_assignment(Request $requestUser $user){
        $user->role_assignment($request);
        return redirect()->route('backoffice.user.show'$user);
    }

113. Crear vista resources\views\theme\backoffice\pages\user\assign_role.blade.php
@extends('theme.backoffice.layouts.admin')

@section('title''Asignar roles')

@section('head')
@endsection

@section('breadcrumbs')
    <li><a href="{{ route('backoffice.user.index') }}">Usuarios del sistema</a></li>
    <li><a href="{{ route('backoffice.user.show', $user}}">{{ $user->name }}</a></li>
    <li>Asignar roles</li>
@endsection

@section('content')
    <div class="section">
        <p class="caption">Selecciona los roles que deseas asignar</p>
        <div class="divider"></div>
        <div id="basic-form" class="section">
            <div class="row">
                <div class="col s12 m8">
                    <div class="card-panel">
                        <h4 class="header2">Asignar roles</h4>
                        <div class="row">
                            <form class="col s12" method="post" action="{{ route('backoffice.user.role_assignment', $user}}">

                                {{ csrf_field() }}

                                @foreach($roles as $role)
                                    <p>
                                        <input type="checkbox" id="{{ $role->id }}" name="roles[]" value="{{ $role->id }}" 
                                            @if($user->has_role($role->id)) checked @endif/>
                                        <label for="{{ $role->id }}">
                                            <span>{{ $role->name }}</span>
                                        </label>
                                    </p>
                                @endforeach

                                <div class="row">
                                    <div class="input-field col s12">
                                        <button class="btn waves-effect waves-light right" type="submit">Guardar
                                            <i class="material-icons right">send</i>
                                        </button>
                                    </div>
                                </div>

                            </form>
                        </div>
                    </div>
                </div>
                <div class="col s12 m4">
                    @include('theme.backoffice.pages.user.includes.user_nav')
                </div>
            </div>
        </div>
    </div>
@endsection

@section('foot')
@endsection

VIDEO 52:
114. Crear ruta para la asignación de roles en routes\web.php
e::resource('role', 'RoleController');
// Grupo de rutas del backoffice
Route::group(['middleware' => ['auth'], 'as' => 'backoffice.'], function(){  
    ***
    Route::resource('user''UserController');
    
    Route::get('user/{user}/assign_role''UserController@assign_role')->name('user.assign_role');
    ***
});


115. Crear ruta para guardar la asignación de roles en la bd en routes\web.php
// Grupo de rutas del backoffice
Route::group(['middleware' => ['auth'], 'as' => 'backoffice.'], function(){  
    ***
    Route::get('user/{user}/assign_role''UserController@assign_role')->name('user.assign_role');
    Route::post('user/{user}/role_assignment''UserController@role_assignment')->name('user.role_assignment');
  
    Route::resource('role''RoleController');
    ***
});


VIDEO 53:
116. Crear rol paciente:
    Nombre: Paciente
    Descripción: Rol predeterminado del sistema

117. Crear rol medico:
    Nombre: Medico
    Descripción: Atiende a pacientes

118. Agregar el la cabecera el modelo de rol en el controlador app\Http\Controllers\UserController.php
    use App\Role;

VIDEO 54:
NOTA: Si en la migración respectiva no creaste los campos de claves foraneas para la tabla role_user,
    entonces crear los siguientes campos:
    role_id int(10)
    user_id int(10)

VIDEO 55:
119. Crear método de validación has_role en el modelo app\User.php
    // ALMACENAMIENTO
    ***
    public function has_role($id){
        foreach($this->roles as $role){
            if ($role->id == $id || $role->slug == $idreturn true;
        }
        return false;
    }

*** COMMIT 9: "Asignación de roles a usuarios" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Asignación de roles a usuarios" ***

VIDEO 56:
ASIGNACIÓN DE PERMISOS
======================

120. Crear ruta para la asignación de permisos en routes\web.php
// Grupo de rutas del backoffice
Route::group(['middleware' => ['auth'], 'as' => 'backoffice.'], function(){
    ***
    Route::get('user/{user}/assign_permission''UserController@assign_permission')->name('user.assign_permission');
    ***
});

121. Crear ruta para guardar la asignación de permisos en la bd en routes\web.php
// Grupo de rutas del backoffice
Route::group(['middleware' => ['auth'], 'as' => 'backoffice.'], function(){
    ***
    Route::post('user/{user}/permission_assignment''UserController@permission_assignment')->name('user.permission_assignment');
    ***
});

122. Crear método (assign_permission) para mostrar formulario para asignar permisos en el controlador
    app\Http\Controllers\UserController.php
    /*
    * Mostrar formulario para asignar permisos
    */
    public function assign_permission(User $user){
        return view('theme.backoffice.pages.user.assign_permission', [
            'user' => $user
            'roles' => $user->roles,
            /* 'permissions' => Permission::all() */
        ]);
    }

123. Crear método (permission_assignment) para asignar los permisos en la bd en el controlador
    app\Http\Controllers\UserController.php
    /*
    * Asignar los permisos en la tabla pivote o intermedia de la base de datos
    */
    public function permission_assignment(Request $requestUser $user){
        // Asignación de permisos
        $user->permissions()->sync($request->permissions);
        alert('Éxito''Permisos asignados''success');
        return redirect()->route('backoffice.user.show'$user);
    }

VIDEO 57:
*** Reeditando resources\views\theme\backoffice\pages\user\assign_permission.blade.php ***
*** Reeditando app\Http\Controllers\UserController.php ***

VIDEO 58:
NOTA: Si en la migración respectiva no creaste los campos de claves foraneas para la tabla permission_user,
    entonces crear los siguientes campos:
    permission_id int(10)
    user_id         int(10)

124. Crear los siguientes permisos:
    Nombre: admin_1
    Rol: Administrador
    Descripción: ...

    Nombre: admin_2
    Rol: Administrador
    Descripción: ...

    Nombre: admin_3
    Rol: Administrador
    Descripción: ...

    NOTA: Y siguiendo la misma tónica, crear tres permisos por cada rol.

125. Crear método de validación has_permission en el modelo app\User.php
    // VALIDACIÓN
    ***
    public function has_permission($id){
        foreach($this->permissions as $permission){
            if ($permission->id == $id || $permission->slug == $idreturn true;
        }
        return false;
    }

*** COMMIT 10: "Asignación de permisos" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Asignación de permisos" ***

VIDEO 59:
CONFIGURACIÓN PARA EL ROL ADMINISTRADOR
=======================================
126. Editar el archivo .env y escribir en la última línea:
    ADMIN_ROLE=administrador

127. Editar el archivo config\app.php
<?php

return [
    'admin_role' => env('ADMIN_ROLE''admin'),
    ***

128. Agregar el método de validación is_admin en el modelo app\User.php
    // VALIDACIÓN
    public function is_admin(){
        $admin = config('app.admin_role');
        if($this->has_role($admin)){
            return true;
        }else{
            return false;
        }
    }

*** COMMIT 11: "Configuración rol administrador" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Configuración rol administrador" ***

VIDEO 60:
INTEGRIDAD EN LOS PERMISOS
==========================
129. Crear métod verify_permission_integrity en el módelo app\User.php
    // OTRAS OPERACIONES
    public function verify_permission_integrity(array $roles){
        $permissions = $this->permissions;
        foreach($permissions as $permission){
            // Si este usuario no tiene el rol del permiso
            //if(!$this->has_role($permission->role->id)){
            if(!in_array($permission->role->id$roles)){
                // Entonces le quitamos el permiso
                $this->permissions()->detach($permission->id);
            }

        }
    }

*** COMMIT 12: "Integridad en los permisos" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Integridad en los permisos" ***

VIDEO 61:
ASIGNACIÓN MASIVA DE PERMISO A ROLES
====================================
130. Crear método role_assignment en el modelo app\User.php
    // ALMACENAMIENTO
    public function role_assignment($request){
        //dd('Todo esta preparado');
        // dd($request->roles);

        // Asignación de roles
        $this->permission_mass_assignment($request->roles);
        $this->roles()->sync($request->roles);
        $this->verify_permission_integrity($request->roles);
        alert('Éxito''Roles asignados''success');
    }

131. Crear método permission_mass_assignment en el modelo app\User.php
    public function permission_mass_assignment(array $roles){
        foreach($roles as $role){
            $role_obj = \App\Role::findOrFail($role);
            $permissions = $role_obj->permissions;
            $this->permissions()->syncWithoutDetaching($permissions);
        }
    }

*** COMMIT 13: "Asignación masiva de permisos a roles" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Asignación masiva de permisos a roles" ***

VIDEO 62:
ASIGNACIÓN DE ROL POR DEFECTO
=============================

132. Crear ruta welcome en routes\web.php
Route::get('/'function () {
    return view('welcome');
});

133. Crear ruta home en routes\web.php
Route::get('home'function () {
    // return view('home')->middleware('auth');
    return view('home');
});

134. Modificar el métod create del controlador app\Http\Controllers\Auth\RegisterController.php
    protected function create(array $data)
    {
        /* return User::create([ */
        $user = User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);

        $patient = config('app.patient_role');
        // Obtener el primer paciente que encuentre
        $role = \App\Role::where('slug'$patient)->first();
        // Obtener los permisos del paciente encontrado anteriormente
        $permissions = $role->permissions;
        // Asignarle los permisos del paso anterior al usuario
        $user->roles()->attach($role);
        // Sincronizar (validar) los permisos
        $user->permissions()->sync($permissions);
        return $user;
    }

135. Registrar un nuevo usuario:
    Nombre: Nuevo usuario
    Correo: nuevo@usuario.com

    NOTA: Autenticar el usuario con la cuenta de Mailtrap creada al inicio.

136. Editar el archivo .env y escribir en la última línea:
    PATIENT_ROLE=paciente

137. Editar el archivo config\app.php
<?php

return [
    'admin_role' => env('ADMIN_ROLE''admin'),
    'patient_role' => env('PATIENT_ROLE''paciente'),
    ***

*** COMMIT 14: "Asignación de rol por defecto" ***
*** Añadir archivos a la zona index: $ git add . ***
*** Guardar archivos en repositorio: $ git commit -m "Asignación de rol por defecto" ***

*** Creamos un nuevo repositorio en https://github.com. Le damos el nombre: Sistema de Historia Clínica en Laravel ***
*** Desde la terminal: ***
*** $ git remote add origin https://github.com/petrix12/Sistema-de-Historia-Cl-nica-en-Laravel.git ***
*** $ git push -u origin master ***

Comentarios

  1. Para impedir que un usuario ingrese a la aplicación hasta no confirma su email:

    Auth::routes(['verify' => true]);

    Route::get('/home', 'HomeController@index')->name('home')->middleware('verified');

    ResponderBorrar
  2. Con respecto al comentario anterior, la url de redirección se encuentra en app/Http/Controllers/Auth/VerificationController.php en la parte del código: protected $redirectTo = '/home';

    ResponderBorrar
  3. Para la verificación de email:
    https://aprendible.com/series/novedades-laravel-5-7/lecciones/verificacion-de-emails

    ResponderBorrar
  4. Para generar las vistas de autenticación a partir de Laravel 6:
    $ composer require laravel/ui
    $ php artisan ui vue --auth
    $ npm install && npm run dev

    ResponderBorrar

Publicar un comentario

Entradas más populares de este blog

Ruta hacia el desarrollador web full stack en Soluciones++

Soluciones++ para VBA