adding genres to the manga

This commit is contained in:
Htet Phone Aung 2023-09-24 22:24:08 +06:30
parent c844ef2ff5
commit e29ab0cde8
28 changed files with 384 additions and 82 deletions

View File

@ -2,9 +2,56 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Genre;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class GenreController extends Controller class GenreController extends Controller
{ {
// public function index()
{
$genres = Genre::latest()->paginate(10)->withQueryString();
return view('genres.index', compact('genres'));
}
public function create()
{
return view('genres.create');
}
public function store(Request $request)
{
$request->validate([
'name' => 'required|min:1|max:255|unique:genres,name'
], [
'name.required' => 'Genre name is required'
]);
$request->user()->genres()->create($request->only('name'));
return back()->with(['message' => 'New genre has been added!!']);
}
public function edit(Genre $genre)
{
return view('genres.edit',['genre' => $genre]);
}
public function update(Request $request, Genre $genre)
{
$request->validate([
'name' => 'required|min:1|max:255|unique:genres,name,'.$genre->id
],[
'name.required' => 'Genre field is required!',
'name.unique' => 'Genre already exists!'
]);
$genre->update(['name' => $request->name]);
return redirect()->route('genres.index')->with(['message' => 'Genre has been updated!']);
}
public function destroy(Genre $genre)
{
$genre->delete();
return back()->with(['message' => 'Genre has been deleted']);
}
} }

View File

@ -8,6 +8,7 @@ use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use App\Http\Requests\StoreMangaRequest; use App\Http\Requests\StoreMangaRequest;
use App\Http\Requests\UpdateMangaRequest; use App\Http\Requests\UpdateMangaRequest;
use App\Models\Genre;
use Illuminate\Support\Facades\Request as FacadesRequest; use Illuminate\Support\Facades\Request as FacadesRequest;
class MangaController extends Controller class MangaController extends Controller
@ -17,13 +18,13 @@ class MangaController extends Controller
*/ */
public function index() public function index()
{ {
$mangas = Manga::when(auth()->user()->role != 'admin', function($q) { $mangas = Manga::when(auth()->user()->role != 'admin', function ($q) {
$user_id = auth()->id(); $user_id = auth()->id();
$q->where('author_id', $user_id); $q->where('author_id', $user_id);
}) })
->latest('id') ->latest('id')
->paginate(10) ->paginate(10)
->withQueryString(); ->withQueryString();
return view('manga.index', compact('mangas')); return view('manga.index', compact('mangas'));
} }
@ -32,7 +33,8 @@ class MangaController extends Controller
*/ */
public function create() public function create()
{ {
return view('manga.create'); $genres = Genre::latest('id')->get();
return view('manga.create', ['genres' => $genres]);
} }
/** /**
@ -47,9 +49,14 @@ class MangaController extends Controller
if ($request->hasFile('cover')) { if ($request->hasFile('cover')) {
$formData['cover'] = $request->file('cover')->store('covers', 'public'); $formData['cover'] = $request->file('cover')->store('covers', 'public');
} }
Manga::create($formData); Manga::create($formData);
//genres
$genres = [];
foreach ($request->genres as $genre) {
$genres[] = $genre;
}
$manga = Manga::latest()->first();
$manga->genres()->attach($genres);
return redirect()->route('manga.index')->with(['message' => 'A New Manga is created']); return redirect()->route('manga.index')->with(['message' => 'A New Manga is created']);
} }
@ -68,7 +75,7 @@ class MangaController extends Controller
public function edit(Manga $manga) public function edit(Manga $manga)
{ {
$this->authorize('update', $manga); $this->authorize('update', $manga);
// dd($manga->genres->contains('id','1'));
return view('manga.edit', compact('manga')); return view('manga.edit', compact('manga'));
} }
@ -85,8 +92,15 @@ class MangaController extends Controller
if ($request->hasFile('cover')) { if ($request->hasFile('cover')) {
$formData['cover'] = $request->file('cover')->store('covers', 'public'); $formData['cover'] = $request->file('cover')->store('covers', 'public');
} }
$manga->update($formData); $manga->update($formData);
//adding data to medium table for many to many rs
if ($request->genres) {
$genres = [];
foreach ($request->genres as $genre) {
$genres[] = $genre;
}
$manga->genres()->sync($genres);
}
return redirect()->back()->with(['message' => 'Manga has been updated!']); return redirect()->back()->with(['message' => 'Manga has been updated!']);
} }
@ -100,5 +114,4 @@ class MangaController extends Controller
$manga->delete(); $manga->delete();
return redirect()->back()->with(['message' => 'Manga has been deleted!']); return redirect()->back()->with(['message' => 'Manga has been deleted!']);
} }
} }

View File

@ -29,35 +29,21 @@ class PageController extends Controller
$chapters = $manga->chapters() $chapters = $manga->chapters()
->latest('chapter_no') ->latest('chapter_no')
->paginate(10); ->paginate(10);
$firstChapter = $manga->chapters()
->orderBy('chapter_no', 'asc')->first();
$lastChapter = $manga->chapters()
->latest('chapter_no')
->first();
$hotMangas = Manga::with(['chapters']) $hotMangas = Manga::with(['chapters'])
->latest('id')->limit('3')->get(); ->latest('id')->limit('3')->get();
return view('manga',[ return view('manga',[
'manga' => $manga, 'manga' => $manga,
'hotMangas' => $hotMangas,
'chapters' => $chapters, 'chapters' => $chapters,
'firstChapter' => $firstChapter, 'hotMangas' => $hotMangas,
'lastChapter' => $lastChapter
]); ]);
} }
public function chapter(Manga $manga,Chapter $chapter) public function chapter(Manga $manga,Chapter $chapter)
{ {
$firstChapter = $manga->chapters()
->orderBy('chapter_no', 'asc')
->first();
$lastChapter = $manga->chapters()
->latest('chapter_no')
->first();
return view('chapter_page', [ return view('chapter_page', [
'chapter' => $chapter,
'manga' => $manga, 'manga' => $manga,
'firstChapter' => $firstChapter, 'chapter' => $chapter,
'lastChapter' => $lastChapter 'comments' => $chapter->comments()->latest('id')->get()
]); ]);
} }

View File

@ -18,7 +18,7 @@ class AdminAccess
{ {
//prevent normal users form accessing admin dashboard //prevent normal users form accessing admin dashboard
if(Auth::user()) { if(Auth::user()) {
if(Auth::user()->role == "user") { if(Auth::user()->role === "user") {
return redirect()->route('page.index')->with(['message' => 'You are not an admin!!']); return redirect()->route('page.index')->with(['message' => 'You are not an admin!!']);
} }
} }

View File

@ -24,7 +24,8 @@ class StoreMangaRequest extends FormRequest
return [ return [
'title' => 'required|min:3|max:100', 'title' => 'required|min:3|max:100',
'summary' => 'required|min:3', 'summary' => 'required|min:3',
'cover' => 'file|required|mimes:png,jpg' 'cover' => 'file|required|mimes:png,jpg',
'genres' => 'required'
]; ];
} }
@ -32,7 +33,8 @@ class StoreMangaRequest extends FormRequest
public function messages() public function messages()
{ {
return [ return [
'cover.required' => 'Please Select Cover Image' 'cover.required' => 'Please Select Cover Image',
'genres.required' => 'A single genre is requied at least'
]; ];
} }
} }

View File

@ -24,7 +24,8 @@ class UpdateMangaRequest extends FormRequest
return [ return [
'title' => 'required|min:3', 'title' => 'required|min:3',
'summary' => 'required|min:3|max:2000', 'summary' => 'required|min:3|max:2000',
'cover' => 'file|required|mimes:png,jpg' 'cover' => 'file|mimes:png,jpg',
'genres' => 'required'
]; ];
} }
@ -32,7 +33,8 @@ class UpdateMangaRequest extends FormRequest
public function messages() public function messages()
{ {
return [ return [
'cover.required' => 'Please Select Cover Image' 'cover.required' => 'Please Select Cover Image',
'genres.required' => 'A single genre is requied at least'
]; ];
} }
} }

View File

@ -8,4 +8,12 @@ use Illuminate\Database\Eloquent\Model;
class Genre extends Model class Genre extends Model
{ {
use HasFactory; use HasFactory;
protected $fillable = ['name', 'user_id'];
public function manga()
{
return $this->belongsToMany(Manga::class);
}
} }

View File

@ -11,7 +11,6 @@ class Manga extends Model
protected $fillable = ['title', 'slug', 'summary', 'excerpt', 'cover', 'author_id']; protected $fillable = ['title', 'slug', 'summary', 'excerpt', 'cover', 'author_id'];
public function user() public function user()
{ {
return $this->belongsTo(User::class, 'author_id'); return $this->belongsTo(User::class, 'author_id');
@ -21,4 +20,24 @@ class Manga extends Model
{ {
return $this->hasMany(Chapter::class); return $this->hasMany(Chapter::class);
} }
//latest and oldest chapter
// public function latestChap()
// {
// return $this->chapters()->one()->latestOfMany();
// }
public function lastChap()
{
return $this->chapters()->one()->ofMany('chapter_no', 'max');
}
public function firstChap()
{
return $this->chapters()->one()->ofMany('chapter_no', 'min');
}
public function genres()
{
return $this->belongsToMany(Genre::class);
}
} }

View File

@ -57,4 +57,9 @@ class User extends Authenticatable
{ {
return $this->hasMany(Reply::class); return $this->hasMany(Reply::class);
} }
public function genres()
{
return $this->hasMany(Genre::class);
}
} }

View File

@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('genre_manga', function (Blueprint $table) {
$table->foreignId('genre_id')->constrained()->cascadeOnDelete();
$table->foreignId('manga_id')->constrained()->cascadeOnDelete();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('genre_manga');
}
};

View File

@ -1,6 +1,7 @@
@props(['manga', 'chapters', 'firstChapter', 'lastChapter']) @props(['manga', 'chapters'])
<div> <div>
<h5 class="fw-semibold my-3 text-primary"> <i class="bi bi-award-fill"></i> {{ $manga->title }}</h5> <h5 class="fw-semibold my-3 text-primary"> <i class="bi bi-award-fill"></i> {{ $manga->title }}</h5>
<div class="row my-3"> <div class="row my-3">
<div class="col-12 col-md-4"> <div class="col-12 col-md-4">
<div class="text-center"> <div class="text-center">
@ -9,25 +10,32 @@
</div> </div>
<div class="col-12 col-md-7"> <div class="col-12 col-md-7">
<p> <span class="fw-semibold">Author</span> - {{ $manga->user->name }} </p> <p> <span class="fw-semibold">Author</span> - {{ $manga->user->name }} </p>
<p> <span class="fw-semibold">Genre</span> - </p> <p>
<span class="fw-semibold">Genre</span> -
@foreach ($manga->genres as $genre)
<span class="text-primary"> {{$genre->name}} </span> /
@endforeach
</p>
<p class="d-flex"> <p class="d-flex">
<a href="{{ route('page.chapter', [$manga->slug, $firstChapter->chapter_no]) }}" class="btn btn-primary me-1">Read First</a> <a href="{{ route('page.chapter', [$manga, $manga->firstChap]) }}" class="btn btn-primary me-1">Read First</a>
<a href="{{ route('page.chapter', [$manga->slug, $lastChapter->chapter_no]) }}" class="btn btn-primary">Read Last</a> <a href="{{ route('page.chapter', [$manga, $manga->lastChap]) }}" class="btn btn-primary">Read Last</a>
</p> </p>
</div> </div>
</div> </div>
<div class="my-5"> <div class="my-5">
<h5 class="fw-semibold text-primary"> <i class="bi bi-award-fill"></i> Summary </h5> <h5 class="fw-semibold text-primary"> <i class="bi bi-award-fill"></i> Summary </h5>
<hr> <hr>
<p class="text-black-50"> {{ $manga->summary }} </p> <p class="text-black-50"> {{ $manga->summary }} </p>
</div> </div>
<ul class="list-group my-3 mt-5 mx-auto"> <ul class="list-group my-3 mt-5 mx-auto">
<h5 class="w-semibold text-primary"> <h5 class="w-semibold text-primary">
<i class="bi bi-award-fill"></i> Latest Chapter Release <i class="bi bi-award-fill"></i> Latest Chapter Release
</h5> </h5>
@forelse ($chapters as $chapter) @forelse ($chapters as $chapter)
<a href="{{ route('page.chapter', [$manga->slug, $chapter->chapter_no]) }}" <a href="{{ route('page.chapter', [$manga, $chapter]) }}"
class="list-group-item list-group-item-action pb-0 border-0 border-bottom class="list-group-item list-group-item-action pb-0 border-0 border-bottom
d-inline-block d-flex align-items-center justify-content-between"> d-inline-block d-flex align-items-center justify-content-between">
<p> Chapter {{ $chapter->chapter_no }} - {{ $chapter->title ?? '' }} </p> <p> Chapter {{ $chapter->chapter_no }} - {{ $chapter->title ?? '' }} </p>

View File

@ -1,7 +1,7 @@
@props(['manga', 'chapter']) @props(['manga', 'chapter'])
<div class="d-flex justify-content-between flex-wrap mb-2"> <div class="d-flex justify-content-between flex-wrap mb-2">
<a href="{{ route('page.chapter', [$manga->slug, $chapter->chapter_no]) }}" <a href="{{ route('page.chapter', [$manga, $chapter]) }}"
class="text-decoration-none text-white small bg-secondary rounded-pill px-1"> class="text-decoration-none text-white small bg-secondary rounded-pill px-1">
Chapter {{ $chapter->chapter_no }} Chapter {{ $chapter->chapter_no }}
</a> </a>

View File

@ -1,6 +1,9 @@
@props(['mangas']) @props(['mangas'])
<h5>Manga List</h5> <div class="d-flex align-items-center">
<h5>Manga List</h5>
<a href="{{route('manga.create')}}" class="btn btn-sm btn-dark ms-auto"><i class="bi bi-plus-circle"></i> Create Manga</a>
</div>
<hr> <hr>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover table-striped"> <table class="table table-hover table-striped">
@ -8,7 +11,8 @@
<tr> <tr>
<th scope="col">#</th> <th scope="col">#</th>
<th scope="col" style="min-width: 20%">Title</th> <th scope="col" style="min-width: 20%">Title</th>
<th>Author</th> <th>Genre</th>
<th>Author/Creator</th>
<th scope="col">Total Chapters</th> <th scope="col">Total Chapters</th>
<th scope="col">Handle</th> <th scope="col">Handle</th>
</tr> </tr>
@ -21,6 +25,11 @@
<p class="mb-0">{{ $manga->title }}</p> <p class="mb-0">{{ $manga->title }}</p>
<span class="small text-black-50">{{ $manga->excerpt }}</span> <span class="small text-black-50">{{ $manga->excerpt }}</span>
</td> </td>
<td>
@foreach ($manga->genres as $genre)
<span class="small">{{$genre->name}} </span> /
@endforeach
</td>
<td> <td>
{{ $manga->user->name }} {{ $manga->user->name }}
</td> </td>
@ -52,7 +61,6 @@
action="{{ route('manga.destroy', $manga->id) }}" class="d-inline-block"> action="{{ route('manga.destroy', $manga->id) }}" class="d-inline-block">
@csrf @csrf
@method('delete') @method('delete')
</form> </form>
</td> </td>
</tr> </tr>

View File

@ -0,0 +1,17 @@
@extends('layouts.app')
@section('content')
<x-card-card-body>
<form method="POST" action="{{ route('genres.create') }}" enctype="multipart/form-data">
@csrf
<div class="mb-3">
<label for="">Genre Name</label>
<input type="text" name="name" class="form-control">
@error('name')
<p class="text-danger small">{{ $message }}</p>
@enderror
</div>
<button type="submit" class="btn btn-outline-dark">Create</button>
</form>
</x-card-card-body>
@endsection

View File

@ -0,0 +1,20 @@
@extends('layouts.app')
@section('content')
<x-card-card-body>
<h5 class="text-primary"> <i class="bi bi-pencil-square"></i> Edit Genre </h5>
<hr>
<form method="POST" action="{{ route('genres.update', $genre) }}" enctype="multipart/form-data">
@csrf
@method('PUT')
<div class="mb-3">
<label for="">Genre Name</label>
<input type="text" name="name" class="form-control" value="{{old('name', $genre->name)}}">
@error('name')
<p class="text-danger small">{{ $message }}</p>
@enderror
</div>
<button type="submit" class="btn btn-outline-dark">Update</button>
</form>
</x-card-card-body>
@endsection

View File

@ -0,0 +1,61 @@
@extends('layouts.app')
@section('content')
<x-card-card-body>
<h5>Genres List</h5>
<hr>
<div class="table-responsive">
<table class="table table-hover table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col" style="min-width: 20%">Genre Name</th>
<th scope="col">Created_at</th>
<th>Option</th>
</tr>
</thead>
<tbody>
@forelse ($genres as $key => $genre)
<tr>
<td> {{ $key }} </td>
<td> {{ $genre->name }} </td>
<td>
<p class="mb-0 small"> <i class="bi bi-clock-history"></i>
{{ $genre->created_at->format('H:i a') }} </p>
<p class="mb-0 small"> <i class="bi bi-calendar-check"></i>
{{ $genre->created_at->format('d-m-Y') }} </p>
</td>
<td>
<div class="btn-group">
<a href="{{route('genres.edit', $genre)}}" class="btn text-info"> <i class="bi bi-pencil-square"></i> </a>
<form method="POST" action="{{route('genres.destroy', $genre)}}" class="form-inline">
@csrf
@method('DELETE')
<button onclick="return confirm('Are you sure to delete?')" class="btn text-danger"><i class="bi bi-trash"></i></button>
</form>
</div>
</td>
</tr>
@empty
<tbody>
<tr>
<td colspan="3">
<div class="d-flex align-items-center justify-content-center">
<p class="text-danger fw-semibold mb-0 me-3">No genre Yet</p>
<a href="{{ route('genres.create') }}" class="btn btn-dark btn-sm">
<i class="bi bi-plus-circle"></i>
</a>
</div>
</td>
</tr>
</tbody>
@endforelse
</tbody>
</table>
</div>
<div>
{{ $genres->links() }}
</div>
</x-card-card-body>
@endsection

View File

@ -93,6 +93,7 @@
</div> </div>
@include('components.footer')
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
</body> </body>

View File

@ -6,7 +6,7 @@
<div class="row mt-5"> <div class="row mt-5">
<div class="col-12 col-md-9"> <div class="col-12 col-md-9">
<x-inner-manga :manga="$manga" :chapters="$chapters" :firstChapter="$firstChapter" :lastChapter="$lastChapter" /> <x-inner-manga :manga="$manga" :chapters="$chapters" />
</div> </div>
<div class="col-12 col-md-3"> <div class="col-12 col-md-3">

View File

@ -5,7 +5,7 @@
@csrf @csrf
<div class="mb-3"> <div class="mb-3">
<label for="">Manga Title</label> <label for="">Manga Title</label>
<input type="text" name="title" class="form-control"> <input type="text" name="title" class="form-control" value="{{old('title')}}">
@error('title') @error('title')
<p class="text-danger small">{{ $message }}</p> <p class="text-danger small">{{ $message }}</p>
@enderror @enderror
@ -17,11 +17,24 @@
<p class="text-danger small">{{ $message }}</p> <p class="text-danger small">{{ $message }}</p>
@enderror @enderror
</div> </div>
<div class="mb-3">
<label class="d-block" for="">Genres</label>
@forelse ($genres as $genre)
<span class="me-2">
<input class="" type="checkbox" name="genres[]" value="{{$genre->id}}" id="{{ $genre->id }}">
<label for="{{ $genre->id }}"> {{ $genre->name }}</label>
</span>
@empty
@endforelse
@error('genres')
<p class="text-danger small">{{ $message }}</p>
@enderror
</div>
<div class="mb-3"> <div class="mb-3">
<label for="">Manga Summary</label> <label for="">Manga Summary</label>
<textarea name="summary" id="" cols="30" rows="6" class="form-control p-3" <textarea name="summary" id="" cols="30" rows="6" class="form-control p-3"
placeholder="Write A Summary"> placeholder="Write A Summary">
{{old('summary')}}
</textarea> </textarea>
@error('summary') @error('summary')
<p class="text-danger small">{{ $message }}</p> <p class="text-danger small">{{ $message }}</p>
@ -31,3 +44,4 @@
</form> </form>
</x-card-card-body> </x-card-card-body>
@endsection @endsection

View File

@ -2,12 +2,19 @@
@section('content') @section('content')
<div class="px-3 mb-4"> <div class="px-3 mb-4">
<a href="{{ url()->previous() }}" class="btn btn-dark">Back</a> <a href="{{ route('manga.index') }}" class="btn btn-dark"> <i class="bi bi-house"></i> Home</a>
<hr> <hr>
<div class=""> <div class="">
<h3 class="my-3"> Title : <span class="fw-semibold ">{{ $manga->title }}</span> </h3> <h3 class="my-3"> Title : <span class="fw-semibold ">{{ $manga->title }}</span> </h3>
<hr> <hr>
<p class="f">Cover Image :</p> <p>
Genres :
@foreach ($manga->genres as $genre)
<span class="small text-primary fw-semibold"> {{$genre->name}} </span> /
@endforeach
</p>
<hr>
<p class="">Cover Image :</p>
<div class="text-center mb-4"> <div class="text-center mb-4">
<img class="w-25" src="{{ asset('storage/'.$manga->cover) }}" alt=""> <img class="w-25" src="{{ asset('storage/'.$manga->cover) }}" alt="">
</div> </div>

View File

@ -1,7 +1,9 @@
@extends('layouts.app') @extends('layouts.app')
@section('content') @section('content')
<a href="{{route('manga.index')}}" class="btn btn-dark"> <i class="bi bi-house-heart-fill"></i> Home</a> <a href="{{ route('manga.index') }}" class="btn btn-dark"> <i class="bi bi-house-heart-fill"></i> Home</a>
<hr>
<h5 class="fw-semibold">Editing Manga</h5>
<hr> <hr>
<form method="POST" action="{{ route('manga.update', $manga->id) }}" enctype="multipart/form-data"> <form method="POST" action="{{ route('manga.update', $manga->id) }}" enctype="multipart/form-data">
@csrf @csrf
@ -14,10 +16,28 @@
@enderror @enderror
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="">Manga Cover</label> <label>Genres</label>
<img src="{{ $manga->cover ? asset($manga->cover) : null }}" class="w-50 d-block my-3" alt=""> <div>
<input type="file" name="cover" id="" class="form-control"> @foreach (App\Models\Genre::all() as $genre)
<input type="checkbox" name="genres[]" id="{{ $genre->id }}" value="{{ $genre->id }}"
{{ $manga->genres->contains('id', $genre->id) ? 'checked' : '' }}>
<label for="{{ $genre->id }}"> {{ $genre->name }} </label>
@endforeach
</div>
@error('genres')
<p class="text-danger small">{{ $message }}</p>
@enderror
</div> </div>
<div class="mb-3">
<label for="">Manga Cover</label>
<img src="{{ asset('storage/' . $manga->cover) }}" class="img-fluid d-block my-3" alt="">
<input type="file" name="cover" id="" class="form-control">
@error('cover')
<p class="text-danger small">{{ $message }}</p>
@enderror
</div>
<div class="mb-3"> <div class="mb-3">
<label for="">Manga Summary</label> <label for="">Manga Summary</label>
<textarea name="summary" id="" cols="30" rows="6" class="form-control p-3" <textarea name="summary" id="" cols="30" rows="6" class="form-control p-3"
@ -28,8 +48,12 @@
<p class="text-danger small">{{ $message }}</p> <p class="text-danger small">{{ $message }}</p>
@enderror @enderror
</div> </div>
<button type="submit" class="btn btn-outline-dark">Update</button> <button type="submit" class="btn btn-outline-dark">Update</button>
</form> </form>
@endsection @endsection
{{-- @section('footer')
@include('components.footer')
@endsection --}}

View File

@ -1,15 +1,15 @@
<div> <div>
<a <a
href="{{ route('page.chapter', [$manga->slug, $chapter->chapter_no - 1 ]) }}" href="{{ route('page.chapter', [$manga, $chapter->chapter_no - 1 ]) }}"
class="btn btn-{{$chapter->chapter_no == $firstChapter->chapter_no ? 'secondary' : 'dark' }} btn-small {" class="btn btn-{{$chapter->chapter_no == $manga->firstChap->chapter_no ? 'secondary' : 'dark' }} btn-small {"
style="pointer-events: {{ $chapter->chapter_no == $firstChapter->chapter_no ? 'none' : '' }}"> style="pointer-events: {{ $chapter->chapter_no == $manga->firstChap->chapter_no ? 'none' : '' }}">
Previous Previous
</a> </a>
{{-- <p> {{ }} </p> --}}
<a <a
href="{{ route('page.chapter', [$manga->slug, $chapter->chapter_no + 1 ]) }}" href="{{ route('page.chapter', [$manga, $chapter->chapter_no + 1 ]) }}"
class="btn btn-{{ $chapter->chapter_no == $lastChapter->chapter_no ? 'secondary' : 'dark' }} btn-small" class="btn btn-{{ $chapter->chapter_no == $manga->lastChap->chapter_no ? 'secondary' : 'dark' }} btn-small"
style="pointer-events: {{ $chapter->chapter_no == $lastChapter->chapter_no ? 'none' : '' }}"> style="pointer-events: {{ $chapter->chapter_no == $manga->lastChap->chapter_no ? 'none' : '' }}">
Next Next
</a> </a>
</div> </div>

View File

@ -1,11 +1,11 @@
<div class="col-4"> <div class="col-4">
<form action="{{route('select.chapter', [$manga->slug])}}" method="post" id="selectChapter" onchange="this.submit();"> <form action="{{route('select.chapter', $manga)}}" method="post" id="selectChapter" onchange="this.submit();">
@csrf @csrf
<select name="chapter_no" class="form-select"> <select name="chapter_no" class="form-select">
@foreach ($manga->chapters()->latest('chapter_no')->get() as $chap) @foreach ($manga->chapters()->latest('chapter_no')->get() as $chap)
<option value="{{ $chap->chapter_no }}" {{ $chap->chapter_no == $chapter->chapter_no ? 'selected' : '' }}> <option value="{{ $chap->chapter_no }}" {{ $chap->chapter_no == $chapter->chapter_no ? 'selected' : '' }}>
Chapter {{ $chap->chapter_no }} - {{ $chap->title ?? '' }} Chapter {{ $chap->chapter_no }} - {{ $chap->title ?? '' }}
</option> </option>
@endforeach @endforeach
</select> </select>
</form> </form>

View File

@ -31,7 +31,7 @@
<!-- comment outputs here --> <!-- comment outputs here -->
<div class="p-2"> <div class="p-2">
@forelse ($chapter->comments()->latest()->get() as $comment) @forelse ($comments as $comment)
<div class="mb-4 border-bottom"> <div class="mb-4 border-bottom">
<p class="mb-1"> <p class="mb-1">
<span class="fw-bold text-primary"> <i class="bi bi-person-fill"></i> {{ $comment->user->name }}</span> <span class="fw-bold text-primary"> <i class="bi bi-person-fill"></i> {{ $comment->user->name }}</span>

View File

@ -3,12 +3,12 @@
@forelse ($hotMangas as $hotManga) @forelse ($hotMangas as $hotManga)
<div class="row border-0 flex-wrap my-3 mb-4"> <div class="row border-0 flex-wrap my-3 mb-4">
<div class="overflow-hidden col-3 col-lg-4"> <div class="overflow-hidden col-3 col-lg-4">
<a href="{{ route('page.manga', $hotManga->slug) }}"> <a href="{{ route('page.manga', $hotManga) }}">
<img src="{{ asset('storage/' . $hotManga->cover) }}" alt="img" class="cover-img img-fluid"> <img src="{{ asset('storage/' . $hotManga->cover) }}" alt="img" class="cover-img img-fluid">
</a> </a>
</div> </div>
<div class="col-5 col-lg-8"> <div class="col-5 col-lg-8">
<a href="{{ route('page.manga', $hotManga->slug) }}" class="text-decoration-none"> <a href="{{ route('page.manga', $hotManga) }}" class="text-decoration-none">
<p class="fw-semibold mb-1"> {{ $hotManga->title }} </p> <p class="fw-semibold mb-1"> {{ $hotManga->title }} </p>
</a> </a>

View File

@ -1,22 +1,36 @@
<ul class="list-group"> <ul class="list-group">
<h5> <h5>
<a href="{{ route('home') }}" class="list-group-item list-group-item-action text-primary"><i class="bi bi-speedometer2"></i> Dashboard </a> <a href="{{ route('home') }}" class="list-group-item list-group-item-action text-primary">
<i class="bi bi-speedometer2"></i> Dashboard
</a>
</h5> </h5>
<h5>Manga</h5> <h5>Manga</h5>
<a href="{{ route('manga.index') }}" class="list-group-item list-group-item-action"><i class="bi bi-book"></i> Manga <a href="{{ route('manga.index') }}" class="list-group-item list-group-item-action">
List </a> <i class="bi bi-book"></i> Manga List
<a href="{{ route('manga.create') }}" class="list-group-item list-group-item-action"><i </a>
class="bi bi-plus-circle-fill"></i> Create Manga</a> <a href="{{ route('manga.create') }}" class="list-group-item list-group-item-action">
<i class="bi bi-plus-circle-fill"></i> Create Manga
</a>
<h5 class="mt-4">Chapters</h5> <h5 class="mt-4">Chapters</h5>
<a href=" {{ route('chapter.index') }} " class="list-group-item list-group-item-action"><i class="bi bi-book"></i> <a href=" {{ route('chapter.index') }} " class="list-group-item list-group-item-action">
Chapter List </a> <i class="bi bi-book"></i> Chapter List
<a href="{{ route('chapter.create') }}" class="list-group-item list-group-item-action"><i </a>
class="bi bi-plus-circle-fill"></i> Create Chapter</a> <a href="{{ route('chapter.create') }}" class="list-group-item list-group-item-action">
<i class="bi bi-plus-circle-fill"></i> Create Chapter
</a>
@can('admin-only') @can('admin-only')
<h5 class="mt-4">Genres</h5>
<a href="{{ route('genres.index') }}" class="list-group-item list-group-item-action">
<i class="bi bi-tags-fill"></i> Genres List
</a>
<a href="{{ route('genres.create') }}" class="list-group-item list-group-item-action">
<i class="bi bi-plus-circle-fill"></i> Create Genre
</a>
<h5 class="mt-4">Users</h5> <h5 class="mt-4">Users</h5>
<a href="{{ route('users.list') }}" class="list-group-item list-group-item-action"> <i class="bi bi-people"></i> <a href="{{ route('users.list') }}" class="list-group-item list-group-item-action">
Users List</a> <i class="bi bi-people"></i> Users List
</a>
@endcan @endcan
</ul> </ul>

View File

@ -31,13 +31,19 @@
</td> </td>
</tr> </tr>
@empty @empty
<p class="text-danger">No User Yet</p> <tbody>
<tr>
<td colspan="3">
<p class="text-danger fw-semibold mb-0">No User Yet</p>
</td>
</tr>
</tbody>
@endforelse @endforelse
</tbody> </tbody>
</table> </table>
</div> </div>
<div> <div>
{{$users->links()}} {{ $users->links() }}
</div> </div>
</x-card-card-body> </x-card-card-body>
@endsection @endsection

View File

@ -10,6 +10,7 @@ use App\Http\Controllers\MangaController;
use App\Http\Controllers\ReplyController; use App\Http\Controllers\ReplyController;
use App\Http\Controllers\ChapterController; use App\Http\Controllers\ChapterController;
use App\Http\Controllers\CommentController; use App\Http\Controllers\CommentController;
use App\Http\Controllers\GenreController;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -26,26 +27,38 @@ Route::controller(PageController::class)->group(function () {
Route::get('/', 'index')->name('page.index'); Route::get('/', 'index')->name('page.index');
Route::get('/MangaDex/manga/{manga:slug}', 'manga')->name('page.manga'); Route::get('/MangaDex/manga/{manga:slug}', 'manga')->name('page.manga');
Route::get('/manga/{manga:slug}/chapter-{chapter:chapter_no?}', 'chapter') Route::get('/manga/{manga:slug}/chapter-{chapter:chapter_no?}', 'chapter')
->name('page.chapter'); ->name('page.chapter');
Route::post('/{manga:slug}/chapter', 'select')->name('select.chapter'); Route::post('/{manga:slug}/chapter', 'select')->name('select.chapter');
}); });
//comment and reply
Route::resource('comments', CommentController::class)->middleware('auth'); Route::resource('comments', CommentController::class)->middleware('auth');
Route::resource('replies', ReplyController::class)->middleware('auth'); Route::resource('replies', ReplyController::class)->middleware('auth');
//auth
Auth::routes(); Auth::routes();
//home
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index']) Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])
->name('home'); ->name('home');
//admin dashboard
Route::middleware(['auth', 'admin.access'])->group(function () { Route::middleware(['auth', 'admin.access'])->group(function () {
Route::resource('manga', MangaController::class); Route::resource('manga', MangaController::class);
Route::resource('chapter', ChapterController::class); Route::resource('chapter', ChapterController::class);
Route::get('/chapters/manage/{manga:slug}', [ChapterController::class, 'manage']) Route::get('/chapters/manage/{manga:slug}', [ChapterController::class, 'manage'])
->name('chapters.manage'); ->name('chapters.manage');
Route::get('/users-list', [UserController::class, 'index'])->name('users.list')->middleware('can:admin-only'); Route::get('/users-list', [UserController::class, 'index'])->name('users.list')->middleware('can:admin-only');
});
Route::controller(GenreController::class)->group(function () {
Route::get('/genres', 'index')->name('genres.index');
Route::get('/genres/create', 'create')->name('genres.create');
Route::post('/genres/create', 'store');
Route::get('/genres/{genre:name}/edit', 'edit')->name('genres.edit');
Route::put('/genres/{genre:id}', 'update')->name('genres.update');
Route::delete('/genres/{genre:name}', 'destroy')->name('genres.destroy');
});
});