Commit fa3cbbbf authored by Trung Lê Đình's avatar Trung Lê Đình

them tinh nang them sua cua bai viet

parent 85c7b8e6
......@@ -3,27 +3,46 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use App\Models\Post;
use App\Models\Category;
class PostController extends Controller
{
public function index(Request $request) {
return view('post.index');
$posts = Post::latest()->paginate();
$categories = Category::orderBy('title', 'asc')->get();
return view('post.index', compact('posts', 'categories'));
}
public function ajax(Request $request) {
return view('post.ajax');
}
public function create(Request $request) {
return view('post.index');
}
public function edit(Post $post, Request $request) {
return view('post.index');
$categories = Category::orderBy('title', 'asc')->whereNull('parent_id')->get();
return view('post.form', compact('categories'));
}
public function store(Request $request) {
return view('post.index');
$request->merge([
'user_id' => Auth::user()->id,
]);
$post = Post::create($request->only([
'title',
'user_id'
]));
$post->categories()->sync($request->category_ids);
return redirect()->route('posts.index')->with('message', 'Tạo mới thành công');
}
public function edit(Post $post, Request $request) {
$categories = Category::orderBy('title', 'asc')->whereNull('parent_id')->get();
return view('post.form', compact('post', 'categories'));
}
public function update(Post $post, Request $request) {
return view('post.index');
$post->update($request->only([
'title',
]));
$post->categories()->sync($request->category_ids);
return redirect()->route('posts.index')->with('message', 'Cập nhật thành công');
}
public function destroy($id, Request $request) {
return view('post.index');
......
......@@ -12,6 +12,9 @@ class Category extends Model
public function parent() {
return $this->belongsTo(Category::class);
}
public function children() {
return $this->hasMany(Category::class, 'parent_id');
}
public function posts() {
return $this->belongsToMany(Post::class);
}
......
......@@ -3,6 +3,7 @@
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Pagination\Paginator;
class AppServiceProvider extends ServiceProvider
{
......@@ -23,6 +24,6 @@ public function register()
*/
public function boot()
{
//
Paginator::useBootstrap();
}
}
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "cf14086919a839fe740e00554e4baff6",
"content-hash": "4131a5c03b502adbf91a68a0b8d73c71",
"packages": [
{
"name": "asm89/stack-cors",
......@@ -5162,6 +5162,90 @@
}
],
"packages-dev": [
{
"name": "barryvdh/laravel-debugbar",
"version": "v3.7.0",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-debugbar.git",
"reference": "3372ed65e6d2039d663ed19aa699956f9d346271"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/3372ed65e6d2039d663ed19aa699956f9d346271",
"reference": "3372ed65e6d2039d663ed19aa699956f9d346271",
"shasum": ""
},
"require": {
"illuminate/routing": "^7|^8|^9",
"illuminate/session": "^7|^8|^9",
"illuminate/support": "^7|^8|^9",
"maximebf/debugbar": "^1.17.2",
"php": ">=7.2.5",
"symfony/finder": "^5|^6"
},
"require-dev": {
"mockery/mockery": "^1.3.3",
"orchestra/testbench-dusk": "^5|^6|^7",
"phpunit/phpunit": "^8.5|^9.0",
"squizlabs/php_codesniffer": "^3.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.6-dev"
},
"laravel": {
"providers": [
"Barryvdh\\Debugbar\\ServiceProvider"
],
"aliases": {
"Debugbar": "Barryvdh\\Debugbar\\Facades\\Debugbar"
}
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Barryvdh\\Debugbar\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"description": "PHP Debugbar integration for Laravel",
"keywords": [
"debug",
"debugbar",
"laravel",
"profiler",
"webprofiler"
],
"support": {
"issues": "https://github.com/barryvdh/laravel-debugbar/issues",
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.7.0"
},
"funding": [
{
"url": "https://fruitcake.nl",
"type": "custom"
},
{
"url": "https://github.com/barryvdh",
"type": "github"
}
],
"time": "2022-07-11T09:26:42+00:00"
},
{
"name": "doctrine/instantiator",
"version": "1.4.1",
......@@ -5677,6 +5761,72 @@
},
"time": "2022-08-31T16:38:14+00:00"
},
{
"name": "maximebf/debugbar",
"version": "v1.18.1",
"source": {
"type": "git",
"url": "https://github.com/maximebf/php-debugbar.git",
"reference": "ba0af68dd4316834701ecb30a00ce9604ced3ee9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/ba0af68dd4316834701ecb30a00ce9604ced3ee9",
"reference": "ba0af68dd4316834701ecb30a00ce9604ced3ee9",
"shasum": ""
},
"require": {
"php": "^7.1|^8",
"psr/log": "^1|^2|^3",
"symfony/var-dumper": "^2.6|^3|^4|^5|^6"
},
"require-dev": {
"phpunit/phpunit": "^7.5.20 || ^9.4.2",
"twig/twig": "^1.38|^2.7|^3.0"
},
"suggest": {
"kriswallsmith/assetic": "The best way to manage assets",
"monolog/monolog": "Log using Monolog",
"predis/predis": "Redis storage"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.18-dev"
}
},
"autoload": {
"psr-4": {
"DebugBar\\": "src/DebugBar/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maxime Bouroumeau-Fuseau",
"email": "maxime.bouroumeau@gmail.com",
"homepage": "http://maximebf.com"
},
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"description": "Debug bar in the browser for php application",
"homepage": "https://github.com/maximebf/php-debugbar",
"keywords": [
"debug",
"debugbar"
],
"support": {
"issues": "https://github.com/maximebf/php-debugbar/issues",
"source": "https://github.com/maximebf/php-debugbar/tree/v1.18.1"
},
"time": "2022-03-31T14:55:54+00:00"
},
{
"name": "mockery/mockery",
"version": "1.5.1",
......
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class CategoryFactory extends Factory
{
public function definition()
{
return [
'title' => $this->faker->name(),
'parent_id' => rand(0, 1) ? null : rand(1, 10),
];
}
}
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
use App\Models\Post;
class PostFactory extends Factory
{
public function definition()
{
return [
'title' => $this->faker->name(),
'status' => Post::IS_PUBLISHED,
];
}
}
......@@ -3,6 +3,8 @@
namespace Database\Seeders;
use App\Models\User;
use App\Models\Category;
use App\Models\Post;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
......@@ -17,6 +19,7 @@ public function run()
User::factory(1)->create([
'role' => User::ROLE_ADMIN
]);
User::factory(9)->create();
User::factory(9)->has(Post::factory()->hasCategories(1)->count(30), 'posts')->create();
Category::factory(10)->create();
}
}
......@@ -9,6 +9,7 @@
<!-- Page content -->
<div class="page-content">
@include('partials.sidebar')
@include('partials.messages')
<!-- Main content -->
<div class="content-wrapper">
......
......@@ -5,31 +5,34 @@
<!-- Global stylesheets -->
<link href="https://fonts.googleapis.com/css?family=Roboto:400,300,100,500,700,900" rel="stylesheet" type="text/css">
<link href="../../../../global_assets/css/icons/icomoon/styles.min.css" rel="stylesheet" type="text/css">
<link href="assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="assets/css/bootstrap_limitless.min.css" rel="stylesheet" type="text/css">
<link href="assets/css/layout.min.css" rel="stylesheet" type="text/css">
<link href="assets/css/components.min.css" rel="stylesheet" type="text/css">
<link href="assets/css/colors.min.css" rel="stylesheet" type="text/css">
<link href="/global_assets/css/icons/icomoon/styles.min.css" rel="stylesheet" type="text/css">
<link href="/assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="/assets/css/bootstrap_limitless.min.css" rel="stylesheet" type="text/css">
<link href="/assets/css/layout.min.css" rel="stylesheet" type="text/css">
<link href="/assets/css/components.min.css" rel="stylesheet" type="text/css">
<link href="/assets/css/colors.min.css" rel="stylesheet" type="text/css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" rel="stylesheet" type="text/css">
<!-- /global stylesheets -->
<!-- Core JS files -->
<script src="../../../../global_assets/js/main/jquery.min.js"></script>
<script src="../../../../global_assets/js/main/bootstrap.bundle.min.js"></script>
<script src="../../../../global_assets/js/plugins/loaders/blockui.min.js"></script>
<script src="../../../../global_assets/js/plugins/ui/ripple.min.js"></script>
<script src="/global_assets/js/main/jquery.min.js"></script>
<script src="/global_assets/js/main/bootstrap.bundle.min.js"></script>
<script src="/global_assets/js/plugins/loaders/blockui.min.js"></script>
<script src="/global_assets/js/plugins/ui/ripple.min.js"></script>
<!-- /core JS files -->
<!-- Theme JS files -->
<script src="../../../../global_assets/js/plugins/visualization/d3/d3.min.js"></script>
<script src="../../../../global_assets/js/plugins/visualization/d3/d3_tooltip.js"></script>
<script src="../../../../global_assets/js/plugins/forms/styling/switchery.min.js"></script>
<script src="../../../../global_assets/js/plugins/forms/selects/bootstrap_multiselect.js"></script>
<script src="../../../../global_assets/js/plugins/ui/moment/moment.min.js"></script>
<script src="../../../../global_assets/js/plugins/pickers/daterangepicker.js"></script>
<script src="../../../../global_assets/js/plugins/ui/perfect_scrollbar.min.js"></script>
<script src="/global_assets/js/plugins/forms/selects/select2.min.js"></script>
<script src="/global_assets/js/plugins/visualization/d3/d3.min.js"></script>
<script src="/global_assets/js/plugins/visualization/d3/d3_tooltip.js"></script>
<script src="/global_assets/js/plugins/forms/styling/switchery.min.js"></script>
<script src="/global_assets/js/plugins/forms/selects/bootstrap_multiselect.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
<script src="/global_assets/js/plugins/ui/moment/moment.min.js"></script>
<script src="/global_assets/js/plugins/pickers/daterangepicker.js"></script>
<script src="/global_assets/js/plugins/ui/perfect_scrollbar.min.js"></script>
<script src="assets/js/app.js"></script>
<script src="../../../../global_assets/js/demo_pages/dashboard.js"></script>
<script src="../../../../global_assets/js/demo_pages/layout_fixed_sidebar_custom.js"></script>
<script src="/assets/js/app.js"></script>
<script src="/global_assets/js/demo_pages/dashboard.js"></script>
<script src="/global_assets/js/demo_pages/layout_fixed_sidebar_custom.js"></script>
<!-- /theme JS files -->
@if(session('message'))
<script>
toastr.success('{{ session('message') }}')
</script>
@endif
\ No newline at end of file
......@@ -81,7 +81,7 @@
<!-- Main -->
<li class="nav-item-header"><div class="text-uppercase font-size-xs line-height-xs">Main</div> <i class="icon-menu" title="Main"></i></li>
<li class="nav-item">
<a href="index.html" class="nav-link">
<a href="/" class="nav-link">
<i class="icon-home4"></i>
<span>
Dashboard
......@@ -90,15 +90,10 @@
</a>
</li>
<li class="nav-item nav-item-submenu">
<a href="#" class="nav-link"><i class="icon-copy"></i> <span>Layouts</span></a>
<a href="#" class="nav-link"><i class="icon-copy"></i> <span>Bài viết</span></a>
<ul class="nav nav-group-sub" data-submenu-title="Layouts">
<li class="nav-item"><a href="index.html" class="nav-link active">Default layout</a></li>
<li class="nav-item"><a href="../../../../layout_2/LTR/material/full/index.html" class="nav-link">Layout 2</a></li>
<li class="nav-item"><a href="../../../../layout_3/LTR/material/full/index.html" class="nav-link">Layout 3</a></li>
<li class="nav-item"><a href="../../../../layout_4/LTR/material/full/index.html" class="nav-link">Layout 4</a></li>
<li class="nav-item"><a href="../../../../layout_5/LTR/material/full/index.html" class="nav-link">Layout 5</a></li>
<li class="nav-item"><a href="../../../../layout_6/LTR/material/full/index.html" class="nav-link disabled">Layout 6 <span class="badge bg-transparent align-self-center ml-auto">Coming soon</span></a></li>
<ul class="nav nav-group-sub" data-submenu-title="Bài viết">
<li class="nav-item"><a href="{{ route('posts.index') }}" class="nav-link active">Tất cả bài viết</a></li>
</ul>
</li>
<li class="nav-item nav-item-submenu">
......
@extends('layouts.app')
@section('content')
<form method="POST" action="{{ $post->id ? route('posts.update', $post->id) : route('posts.store') }}">
@csrf
@if ($post->id)
@method('PUT')
@endif
<!-- Page header -->
<div class="page-header page-header-light">
<div class="page-header-content header-elements-md-inline">
<div class="page-title d-flex">
<h4>
<i class="icon-arrow-left52 mr-2"></i> <span class="font-weight-semibold">Bài viết</span> -
@if($post->id)
Sửa
@else
Thêm mới
@endif
</h4>
<a href="#" class="header-elements-toggle text-default d-md-none"><i class="icon-more"></i></a>
</div>
<div class="header-elements d-none">
<div class="d-flex justify-content-center">
<button type="submit" class="btn btn-link btn-float font-size-sm font-weight-semibold text-default">
<i class="icon-calendar5 text-pink-300"></i>
<span>Lưu</span>
</button>
</div>
</div>
</div>
</div>
<!-- /page header -->
<!-- Content area -->
<div class="content">
<!-- Horizontal form options -->
<div class="row">
<div class="col-md-12">
<!-- Basic layout-->
<div class="card">
<div class="card-body">
<div class="form-group row">
<label class="col-lg-3 col-form-label">Tiêu đề</label>
<div class="col-lg-9">
<input type="text" required class="form-control" value="{{ $post->title }}" placeholder="Tiêu đề" name="title">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label">Password:</label>
<div class="col-lg-9">
<input type="password" class="form-control" placeholder="Your strong password">
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label">Your state:</label>
<div class="col-lg-9">
<select class="form-control form-control-select2" data-fouc>
<optgroup label="Alaskan/Hawaiian Time Zone">
<option value="AK">Alaska</option>
<option value="HI">Hawaii</option>
</optgroup>
<optgroup label="Pacific Time Zone">
<option value="CA">California</option>
<option value="NV">Nevada</option>
<option value="WA">Washington</option>
</optgroup>
<optgroup label="Mountain Time Zone">
<option value="AZ">Arizona</option>
<option value="CO">Colorado</option>
<option value="WY">Wyoming</option>
</optgroup>
<optgroup label="Central Time Zone">
<option value="AL">Alabama</option>
<option value="AR">Arkansas</option>
<option value="KY">Kentucky</option>
</optgroup>
<optgroup label="Eastern Time Zone">
<option value="CT">Connecticut</option>
<option value="DE">Delaware</option>
<option value="FL">Florida</option>
</optgroup>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label">Gender:</label>
<div class="col-lg-9">
<div class="form-check form-check-inline">
<label class="form-check-label">
<input type="radio" class="form-input-styled" name="gender" checked data-fouc>
Male
</label>
</div>
<div class="form-check form-check-inline">
<label class="form-check-label">
<input type="radio" class="form-input-styled" name="gender" data-fouc>
Female
</label>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label">Your avatar:</label>
<div class="col-lg-9">
<input type="file" class="form-input-styled" data-fouc>
<span class="form-text text-muted">Accepted formats: gif, png, jpg. Max file size 2Mb</span>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label">Danh mục:</label>
<div class="col-lg-9">
<select multiple="multiple" data-placeholder="Chọn danh mục" name="category_ids[]" class="form-control select2" data-fouc>
@foreach($categories as $category)
<optgroup label="{{ $category->title }}">
@foreach($category->children as $child)
<option {{ in_array($child->id, $post->categories->pluck('id')->all()) ? 'selected' : '' }} value="{{ $child->id }}">{{ $child->title }}</option>
@endforeach
</optgroup>
@endforeach
</select>
</div>
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label">Your message:</label>
<div class="col-lg-9">
<textarea rows="5" cols="5" class="form-control" placeholder="Enter your message here"></textarea>
</div>
</div>
<div class="text-right">
<button type="submit" class="btn btn-primary">Lưu <i class="icon-paperplane ml-2"></i></button>
</div>
</div>
</div>
<!-- /basic layout -->
</div>
</div>
</div>
<!-- /content area -->
</form>
<script>
$(function(){
$('.select2').select2()
})
</script>
@endsection
@extends('layouts.app')
@section('content')
<!-- Page header -->
<div class="page-header page-header-light">
<div class="page-header-content header-elements-md-inline">
<div class="page-title d-flex">
<h4>Tất cả bài viết</h4>
<a href="#" class="header-elements-toggle text-default d-md-none"><i class="icon-more"></i></a>
</div>
<div class="header-elements d-none">
<div class="d-flex justify-content-center">
<a href="#" class="btn btn-link btn-float font-size-sm font-weight-semibold text-default">
<i class="icon-trash text-pink-300"></i>
<span>Xóa</span>
</a>
<a href="{{ route('posts.create') }}" class="btn btn-link btn-float font-size-sm font-weight-semibold text-default">
<i class="icon-calendar5 text-pink-300"></i>
<span>Thêm mới</span>
</a>
</div>
</div>
</div>
</div>
<!-- /page header -->
<!-- Content area -->
<div class="content">
<!-- Basic table -->
<div class="card">
<div class="card-body">
<form action="" class="row">
<div class="col-md-3">
<input name="keyword" placeholder="Từ khóa" class="form-control">
</div>
<div class="col-md-3">
<select name="category_id" class="form-control select2">
<option value="">Chọn</option>
@foreach($categories as $category)
<option value="{{ $category->id }}">{{ $category->title }}</option>
@endforeach
</select>
</div>
<div class="col-md-3">
<button type="submit" class="btn btn-primary">Lọc</button>
</div>
</form>
</div>
<div class="table-responsive">
<div class="my-2">
{{ $posts->links() }}
</div>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Ảnh</th>
<th>Tiêu đề</th>
<th>Danh mục</th>
<th>Người tạo</th>
<th>Tác vụ</th>
</tr>
</thead>
<tbody>
@foreach($posts as $post)
<tr>
<td>
<input type="checkbox" class="form-input-styled">
</td>
<td>
<img src="{{ $post->image }}" height="30">
</td>
<td>{{ $post->title }}</td>
<td>{{ $post->categories()->first()->title ?? '' }}</td>
<td>{{ $post->user->name }}</td>
<td>
<div class="list-icons">
<a href="{{ route('posts.edit', $post->id) }}" class="list-icons-item" title="Sửa">
<i class="icon-pencil7"></i>
</a>
<a href="#" class="text-danger list-icons-item" title="Xóa">
<i class="icon-trash"></i>
</a>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="my-2">
{{ $posts->links() }}
</div>
</div>
</div>
<!-- /basic table -->
</div>
<!-- /content area -->
<script>
$(function(){
$('.select2').select2()
})
</script>
@endsection
......@@ -23,5 +23,6 @@
Route::prefix('posts')->name('posts.')->group(function() {
Route::post('ajax', [PostController::class, 'ajax'])->name('ajax');
});
Route::get('/', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment