Add post DELETE route
Add admin permissions
This commit is contained in:
parent
79d6d6238b
commit
7a4d7aa7ca
@ -3,10 +3,11 @@
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class BlogPost extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
@ -24,6 +25,6 @@ class BlogPost extends Model
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongs('App\User');
|
||||
return $this->belongsTo('App\User');
|
||||
}
|
||||
}
|
||||
|
@ -49,10 +49,10 @@ class BlogPostController extends Controller
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\BlogPost $blogPost
|
||||
* @param \App\BlogPost $post
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(BlogPost $blogPost)
|
||||
public function show(BlogPost $post)
|
||||
{
|
||||
//
|
||||
}
|
||||
@ -60,10 +60,10 @@ class BlogPostController extends Controller
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\BlogPost $blogPost
|
||||
* @param \App\BlogPost $post
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(BlogPost $blogPost)
|
||||
public function edit(BlogPost $post)
|
||||
{
|
||||
//
|
||||
}
|
||||
@ -72,10 +72,10 @@ class BlogPostController extends Controller
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\BlogPost $blogPost
|
||||
* @param \App\BlogPost $post
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, BlogPost $blogPost)
|
||||
public function update(Request $request, BlogPost $post)
|
||||
{
|
||||
//
|
||||
}
|
||||
@ -83,11 +83,15 @@ class BlogPostController extends Controller
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\BlogPost $blogPost
|
||||
* @param \App\BlogPost $post
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(BlogPost $blogPost)
|
||||
public function destroy(BlogPost $post)
|
||||
{
|
||||
//
|
||||
$this->authorize('delete', $post);
|
||||
|
||||
$post->delete();
|
||||
|
||||
return view('posts.delete', compact('post'));
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Auth;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
@ -23,6 +24,6 @@ class HomeController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('home');
|
||||
return view('posts.index', ['user' => Auth::user()]);
|
||||
}
|
||||
}
|
||||
|
99
app/Policies/BlogPostPolicy.php
Normal file
99
app/Policies/BlogPostPolicy.php
Normal file
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\BlogPost;
|
||||
use App\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class BlogPostPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any blog posts.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function viewAny(User $user)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the blog post.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\BlogPost $blogPost
|
||||
* @return mixed
|
||||
*/
|
||||
public function view(User $user, BlogPost $blogPost)
|
||||
{
|
||||
if ($blogPost->deleted_at !== null)
|
||||
{
|
||||
return $user->admin || $user->id === $blogPost->user_id;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create blog posts.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function create(User $user)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the blog post.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\BlogPost $blogPost
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(User $user, BlogPost $blogPost)
|
||||
{
|
||||
return $user->admin || $user->id === $blogPost->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the blog post.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\BlogPost $blogPost
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete(User $user, BlogPost $blogPost)
|
||||
{
|
||||
return $user->admin || $user->id === $blogPost->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the blog post.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\BlogPost $blogPost
|
||||
* @return mixed
|
||||
*/
|
||||
public function restore(User $user, BlogPost $blogPost)
|
||||
{
|
||||
return $user->admin || $user->id === $blogPost->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the blog post.
|
||||
*
|
||||
* @param \App\User $user
|
||||
* @param \App\BlogPost $blogPost
|
||||
* @return mixed
|
||||
*/
|
||||
public function forceDelete(User $user, BlogPost $blogPost)
|
||||
{
|
||||
return $user->admin || $user->id === $blogPost->user_id;
|
||||
}
|
||||
}
|
@ -5,6 +5,10 @@ namespace App\Providers;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
use App\BlogPost;
|
||||
use App\Policies\BlogPostPolicy;
|
||||
use Illuminate\Auth\SessionGuard;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
@ -13,7 +17,7 @@ class AuthServiceProvider extends ServiceProvider
|
||||
* @var array
|
||||
*/
|
||||
protected $policies = [
|
||||
// 'App\Model' => 'App\Policies\ModelPolicy',
|
||||
BlogPost::class => BlogPostPolicy::class,
|
||||
];
|
||||
|
||||
/**
|
||||
@ -24,7 +28,12 @@ class AuthServiceProvider extends ServiceProvider
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
}
|
||||
|
||||
//
|
||||
public function register()
|
||||
{
|
||||
SessionGuard::macro('admin', function () {
|
||||
return \Auth::user()->admin;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,10 @@ class CreateUsersTable extends Migration
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
|
||||
$table->boolean('admin')
|
||||
->default(false);
|
||||
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
@ -11,6 +11,7 @@ class DatabaseSeeder extends Seeder
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// $this->call(UsersTableSeeder::class);
|
||||
$this->call(UserSeeder::class);
|
||||
$this->call(BlogPostSeeder::class);
|
||||
}
|
||||
}
|
||||
|
35
database/seeds/UserSeeder.php
Normal file
35
database/seeds/UserSeeder.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\User;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class UserSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$users = [
|
||||
'alex' => 'Alex Thomassen',
|
||||
'martin' => 'Martin Onsrud',
|
||||
'stian' => 'Stian Larsen',
|
||||
'oyvind' => 'Øyvind Finsrud',
|
||||
];
|
||||
|
||||
foreach ($users as $username => $name)
|
||||
{
|
||||
$user = new User;
|
||||
$user->username = $username;
|
||||
$user->name = $name;
|
||||
$user->email = $username . '@example.com';
|
||||
$user->password = Hash::make('Kaffekopp123');
|
||||
$user->admin = true;
|
||||
|
||||
$user->save();
|
||||
}
|
||||
}
|
||||
}
|
5
resources/views/errors/401.blade.php
Normal file
5
resources/views/errors/401.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Unauthorized'))
|
||||
@section('code', '401')
|
||||
@section('message', __('Unauthorized'))
|
5
resources/views/errors/403.blade.php
Normal file
5
resources/views/errors/403.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Forbidden'))
|
||||
@section('code', '403')
|
||||
@section('message', __($exception->getMessage() ?: 'Forbidden'))
|
5
resources/views/errors/404.blade.php
Normal file
5
resources/views/errors/404.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Not Found'))
|
||||
@section('code', '404')
|
||||
@section('message', __('Not Found'))
|
5
resources/views/errors/419.blade.php
Normal file
5
resources/views/errors/419.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Page Expired'))
|
||||
@section('code', '419')
|
||||
@section('message', __('Page Expired'))
|
5
resources/views/errors/429.blade.php
Normal file
5
resources/views/errors/429.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Too Many Requests'))
|
||||
@section('code', '429')
|
||||
@section('message', __('Too Many Requests'))
|
5
resources/views/errors/500.blade.php
Normal file
5
resources/views/errors/500.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Server Error'))
|
||||
@section('code', '500')
|
||||
@section('message', __('Server Error'))
|
5
resources/views/errors/503.blade.php
Normal file
5
resources/views/errors/503.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Service Unavailable'))
|
||||
@section('code', '503')
|
||||
@section('message', __($exception->getMessage() ?: 'Service Unavailable'))
|
486
resources/views/errors/illustrated-layout.blade.php
Normal file
486
resources/views/errors/illustrated-layout.blade.php
Normal file
@ -0,0 +1,486 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<title>@yield('title')</title>
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="dns-prefetch" href="//fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
|
||||
|
||||
<!-- Styles -->
|
||||
<style>
|
||||
html {
|
||||
line-height: 1.15;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
header,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
figcaption,
|
||||
main {
|
||||
display: block;
|
||||
}
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
-webkit-text-decoration-skip: objects;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
font-family: sans-serif;
|
||||
font-size: 100%;
|
||||
line-height: 1.15;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
button {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
button,
|
||||
html [type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
button:-moz-focusring,
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
legend {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
display: table;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
[type="search"]::-webkit-search-cancel-button,
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
-webkit-box-sizing: inherit;
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: 1px dotted;
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
border-width: 0;
|
||||
border-style: solid;
|
||||
border-color: #dae1e7;
|
||||
}
|
||||
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
input::-webkit-input-placeholder {
|
||||
color: inherit;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
input:-ms-input-placeholder {
|
||||
color: inherit;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
input::-ms-input-placeholder {
|
||||
color: inherit;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
input::placeholder {
|
||||
color: inherit;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
button,
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.bg-transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bg-white {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.bg-teal-light {
|
||||
background-color: #64d5ca;
|
||||
}
|
||||
|
||||
.bg-blue-dark {
|
||||
background-color: #2779bd;
|
||||
}
|
||||
|
||||
.bg-indigo-light {
|
||||
background-color: #7886d7;
|
||||
}
|
||||
|
||||
.bg-purple-light {
|
||||
background-color: #a779e9;
|
||||
}
|
||||
|
||||
.bg-no-repeat {
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.bg-cover {
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.border-grey-light {
|
||||
border-color: #dae1e7;
|
||||
}
|
||||
|
||||
.hover\:border-grey:hover {
|
||||
border-color: #b8c2cc;
|
||||
}
|
||||
|
||||
.rounded-lg {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
|
||||
.border-2 {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.items-center {
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.justify-center {
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.font-sans {
|
||||
font-family: Nunito, sans-serif;
|
||||
}
|
||||
|
||||
.font-light {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.font-black {
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.h-1 {
|
||||
height: .25rem;
|
||||
}
|
||||
|
||||
.leading-normal {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.m-8 {
|
||||
margin: 2rem;
|
||||
}
|
||||
|
||||
.my-3 {
|
||||
margin-top: .75rem;
|
||||
margin-bottom: .75rem;
|
||||
}
|
||||
|
||||
.mb-8 {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.max-w-sm {
|
||||
max-width: 30rem;
|
||||
}
|
||||
|
||||
.min-h-screen {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.py-3 {
|
||||
padding-top: .75rem;
|
||||
padding-bottom: .75rem;
|
||||
}
|
||||
|
||||
.px-6 {
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
}
|
||||
|
||||
.pb-full {
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
|
||||
.absolute {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pin {
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.text-black {
|
||||
color: #22292f;
|
||||
}
|
||||
|
||||
.text-grey-darkest {
|
||||
color: #3d4852;
|
||||
}
|
||||
|
||||
.text-grey-darker {
|
||||
color: #606f7b;
|
||||
}
|
||||
|
||||
.text-2xl {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.text-5xl {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.antialiased {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.tracking-wide {
|
||||
letter-spacing: .05em;
|
||||
}
|
||||
|
||||
.w-16 {
|
||||
width: 4rem;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.md\:bg-left {
|
||||
background-position: left;
|
||||
}
|
||||
|
||||
.md\:bg-right {
|
||||
background-position: right;
|
||||
}
|
||||
|
||||
.md\:flex {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.md\:my-6 {
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.md\:min-h-screen {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.md\:pb-0 {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.md\:text-3xl {
|
||||
font-size: 1.875rem;
|
||||
}
|
||||
|
||||
.md\:text-15xl {
|
||||
font-size: 9rem;
|
||||
}
|
||||
|
||||
.md\:w-1\/2 {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.lg\:bg-center {
|
||||
background-position: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="antialiased font-sans">
|
||||
<div class="md:flex min-h-screen">
|
||||
<div class="w-full md:w-1/2 bg-white flex items-center justify-center">
|
||||
<div class="max-w-sm m-8">
|
||||
<div class="text-black text-5xl md:text-15xl font-black">
|
||||
@yield('code', __('Oh no'))
|
||||
</div>
|
||||
|
||||
<div class="w-16 h-1 bg-purple-light my-3 md:my-6"></div>
|
||||
|
||||
<p class="text-grey-darker text-2xl md:text-3xl font-light mb-8 leading-normal">
|
||||
@yield('message')
|
||||
</p>
|
||||
|
||||
<a href="{{ app('router')->has('home') ? route('home') : url('/') }}">
|
||||
<button class="bg-transparent text-grey-darkest font-bold uppercase tracking-wide py-3 px-6 border-2 border-grey-light hover:border-grey rounded-lg">
|
||||
{{ __('Go Home') }}
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative pb-full md:flex md:pb-0 md:min-h-screen w-full md:w-1/2">
|
||||
@yield('image')
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
57
resources/views/errors/layout.blade.php
Normal file
57
resources/views/errors/layout.blade.php
Normal file
@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>@yield('title')</title>
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="dns-prefetch" href="//fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
|
||||
|
||||
<!-- Styles -->
|
||||
<style>
|
||||
html, body {
|
||||
background-color: #fff;
|
||||
color: #636b6f;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
font-weight: 100;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.full-height {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.position-ref {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36px;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex-center position-ref full-height">
|
||||
<div class="content">
|
||||
<div class="title">
|
||||
@yield('message')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
62
resources/views/errors/minimal.blade.php
Normal file
62
resources/views/errors/minimal.blade.php
Normal file
@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>@yield('title')</title>
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="dns-prefetch" href="//fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
|
||||
|
||||
<!-- Styles -->
|
||||
<style>
|
||||
html, body {
|
||||
background-color: #fff;
|
||||
color: #636b6f;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
font-weight: 100;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.full-height {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.position-ref {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.code {
|
||||
border-right: 2px solid;
|
||||
font-size: 26px;
|
||||
padding: 0 15px 0 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.message {
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex-center position-ref full-height">
|
||||
<div class="code">
|
||||
@yield('code')
|
||||
</div>
|
||||
|
||||
<div class="message" style="padding: 10px;">
|
||||
@yield('message')
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
9
resources/views/posts/delete.blade.php
Normal file
9
resources/views/posts/delete.blade.php
Normal file
@ -0,0 +1,9 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<h1>Post deleted!</h1>
|
||||
<p><strong>Title:</strong> {{ $post->title }}</p>
|
||||
<p><strong>ID:</strong> {{ $post->id }}</p>
|
||||
</div>
|
||||
@endsection
|
@ -13,12 +13,35 @@
|
||||
<div class="user-post-body">
|
||||
@markdown($post->body)
|
||||
</div>
|
||||
<p class="text-muted">
|
||||
Created: {{ $post->created_at }}
|
||||
@if ($post->created_at->diffInSeconds($post->updated_at) > 1)
|
||||
| Last updated: {{ $post->updated_at }}
|
||||
|
||||
<div class="row">
|
||||
<span class="col align-self-center text-muted">
|
||||
Created: {{ $post->created_at }}
|
||||
@if ($post->created_at->diffInSeconds($post->updated_at) > 1)
|
||||
| Last updated: {{ $post->updated_at }}
|
||||
@endif
|
||||
</span>
|
||||
|
||||
@can('delete', $post)
|
||||
<span class="col align-self-center text-right">
|
||||
<form action="{{ route('posts.delete', $post->id) }}" method="post">
|
||||
@method('delete')
|
||||
@csrf
|
||||
|
||||
<button class="btn btn-danger" type="submit"><i class="fas fa-trash fa-fw"></i> Delete</button>
|
||||
</form>
|
||||
</span>
|
||||
@endcan
|
||||
</div>
|
||||
|
||||
@auth
|
||||
@if (Auth::admin() && Auth::id() !== $user->id)
|
||||
<!-- TODO: Fix design -->
|
||||
<div class="col alert alert-danger">
|
||||
<i class="fas fa-exclamation-triangle fa-fw"></i> Be careful! You have permissions to delete all blog posts, so keep that in mind before clicking on buttons.
|
||||
</div>
|
||||
@endif
|
||||
</p>
|
||||
@endauth
|
||||
</div>
|
||||
@endforeach
|
||||
@endif
|
||||
|
@ -19,6 +19,8 @@ Auth::routes();
|
||||
|
||||
Route::get('/home', 'HomeController@index')->name('home');
|
||||
|
||||
Route::group(['prefix' => 'posts'], function() {
|
||||
Route::get('/u/{username}', ['uses' => 'BlogPostController@index']);
|
||||
Route::group(['prefix' => 'posts', 'as' => 'posts.'], function() {
|
||||
Route::get('/u/{username}', ['as' => 'index', 'uses' => 'BlogPostController@index']);
|
||||
|
||||
Route::delete('/delete/{post}', ['as' => 'delete', 'uses' => 'BlogPostController@destroy']);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user