still developing

This commit is contained in:
Htet Phone Aung 2023-08-30 21:15:58 +06:30
parent 1cc8d227e4
commit f1565c415f
46 changed files with 758 additions and 127 deletions

View File

@ -2,9 +2,11 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Chapter;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests\StoreChapterRequest; use App\Http\Requests\StoreChapterRequest;
use App\Http\Requests\UpdateChapterRequest; use App\Http\Requests\UpdateChapterRequest;
use App\Models\Chapter; use App\Models\Manga;
class ChapterController extends Controller class ChapterController extends Controller
{ {
@ -13,15 +15,17 @@ class ChapterController extends Controller
*/ */
public function index() public function index()
{ {
// $mangas = Manga::latest('id')->paginate(8)->withQueryString();
return view('chapter.index', compact('mangas'));
} }
/** /**
* Show the form for creating a new resource. * Show the form for creating a new resource.
*/ */
public function create() public function create()
{ {
// return view('chapter.create');
} }
/** /**
@ -29,7 +33,19 @@ class ChapterController extends Controller
*/ */
public function store(StoreChapterRequest $request) public function store(StoreChapterRequest $request)
{ {
// $formData = $request->validated();
$formData['user_id'] = Auth::id();
if($request->hasFile('images')) {
foreach ($request->file('images') as $image) {
$images[] = $image->store($request->manga_id.'OfChapter', 'public');
}
$formData['images'] = $images;
}
Chapter::create($formData);
return redirect()->route('home')->with(['message' => 'New Chapter has been added!!']);
} }
/** /**
@ -61,6 +77,12 @@ class ChapterController extends Controller
*/ */
public function destroy(Chapter $chapter) public function destroy(Chapter $chapter)
{ {
// $chapter->delete();
return back()->with(['message' => "Successfully Deleted!"]);
}
public function manage(Manga $manga)
{
return view('chapter.manageChapter', compact('manga'));
} }
} }

View File

@ -25,4 +25,6 @@ class HomeController extends Controller
{ {
return view('home'); return view('home');
} }
} }

View File

@ -2,9 +2,13 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Manga;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
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\Manga; use Illuminate\Support\Facades\Request as FacadesRequest;
class MangaController extends Controller class MangaController extends Controller
{ {
@ -13,7 +17,8 @@ class MangaController extends Controller
*/ */
public function index() public function index()
{ {
// $mangas = Manga::latest('id')->paginate(10)->withQueryString();
return view('manga.index', compact('mangas'));
} }
/** /**
@ -21,7 +26,7 @@ class MangaController extends Controller
*/ */
public function create() public function create()
{ {
// return view('manga.create');
} }
/** /**
@ -29,15 +34,26 @@ class MangaController extends Controller
*/ */
public function store(StoreMangaRequest $request) public function store(StoreMangaRequest $request)
{ {
// $formData = $request->validated();
$formData['slug'] = Str::slug($request->title);
$formData['excerpt'] = Str::words($request->summary, 10, '...');
$formData['author_id'] = Auth::id();
if ($request->hasFile('cover')) {
$formData['cover'] = $request->file('cover')->store('covers', 'public');
}
Manga::create($formData);
return redirect()->route('manga.index')->with(['message' => 'A New Manga is created']);
} }
/** /**
* Display the specified resource. * Display the specified resource.
*/ */
public function show(Manga $manga) public function show($slug)
{ {
// $manga = Manga::where('slug', $slug)->first();
return view('manga.detail', compact('manga'));
} }
/** /**
@ -45,7 +61,7 @@ class MangaController extends Controller
*/ */
public function edit(Manga $manga) public function edit(Manga $manga)
{ {
// return view('manga.edit', compact('manga'));
} }
/** /**
@ -53,7 +69,15 @@ class MangaController extends Controller
*/ */
public function update(UpdateMangaRequest $request, Manga $manga) public function update(UpdateMangaRequest $request, Manga $manga)
{ {
// $formData = $request->validated();
$formData['slug'] = Str::slug($request->title);
$formData['excerpt'] = Str::words($request->summary, 10, '...');
if ($request->hasFile('cover')) {
$formData['cover'] = $request->file('cover')->store('covers', 'public');
}
$manga->update($formData);
return redirect()->back()->with(['message' => 'Manga has been updated!']);
} }
/** /**
@ -61,6 +85,8 @@ class MangaController extends Controller
*/ */
public function destroy(Manga $manga) public function destroy(Manga $manga)
{ {
// $manga->delete();
return redirect()->back()->with(['message' => 'Manga has been deleted!']);
} }
} }

View File

@ -0,0 +1,32 @@
<?php
namespace App\Http\Controllers;
use App\Models\Chapter;
use App\Models\Manga;
use Illuminate\Http\Request;
class PageController extends Controller
{
public function index()
{
$mangas = Manga::latest('id')->paginate(10)->withQueryString();
$hotMangas = Manga::latest('id')->limit('3')->get();
return view('index', [
'mangas' => $mangas,
'hotMangas' => $hotMangas
]);
}
public function manga($slug)
{
$manga = Manga::where('slug', $slug)->first();
return view('manga', compact('manga'));
}
public function chapter(Manga $manga, Chapter $chapter )
{
return view('chapter_page', ['manga' => $manga, 'chapter' => $chapter]);
}
}

View File

@ -11,7 +11,7 @@ class StoreChapterRequest extends FormRequest
*/ */
public function authorize(): bool public function authorize(): bool
{ {
return false; return true;
} }
/** /**
@ -22,7 +22,16 @@ class StoreChapterRequest extends FormRequest
public function rules(): array public function rules(): array
{ {
return [ return [
// 'title' => 'min:3',
'manga_id' => 'required|exists:mangas,id'
];
}
public function messages()
{
return [
'manga_id.required' => 'Please Select the Manga',
'manga_id.exists' => 'Please Select the Manga'
]; ];
} }
} }

View File

@ -11,7 +11,7 @@ class StoreMangaRequest extends FormRequest
*/ */
public function authorize(): bool public function authorize(): bool
{ {
return false; return true;
} }
/** /**
@ -22,7 +22,8 @@ class StoreMangaRequest extends FormRequest
public function rules(): array public function rules(): array
{ {
return [ return [
// 'title' => 'required|min:3|max:100',
'summary' => 'required|min:3'
]; ];
} }
} }

View File

@ -11,7 +11,7 @@ class UpdateMangaRequest extends FormRequest
*/ */
public function authorize(): bool public function authorize(): bool
{ {
return false; return true;
} }
/** /**
@ -22,7 +22,8 @@ class UpdateMangaRequest extends FormRequest
public function rules(): array public function rules(): array
{ {
return [ return [
// 'title' => 'required|min:3',
'summary' => 'required|min:3|max:2000'
]; ];
} }
} }

View File

@ -8,4 +8,14 @@ use Illuminate\Database\Eloquent\Model;
class Chapter extends Model class Chapter extends Model
{ {
use HasFactory; use HasFactory;
protected $fillable = ['title', 'images', 'manga_id', 'user_id'];
protected $casts = [
'images' => 'array'
];
public function manga()
{
return $this->belongsTo(Manga::class, 'manga_id');
}
} }

View File

@ -8,4 +8,17 @@ use Illuminate\Database\Eloquent\Model;
class Manga extends Model class Manga extends Model
{ {
use HasFactory; use HasFactory;
protected $fillable = ['title', 'slug', 'summary', 'excerpt', 'cover', 'author_id'];
public function user()
{
return $this->belongsTo(User::class, 'author_id');
}
public function chapters()
{
return $this->hasMany(Chapter::class);
}
} }

View File

@ -2,6 +2,7 @@
namespace App\Providers; namespace App\Providers;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider class AppServiceProvider extends ServiceProvider
@ -19,6 +20,6 @@ class AppServiceProvider extends ServiceProvider
*/ */
public function boot(): void public function boot(): void
{ {
// Paginator::useBootstrapFive();
} }
} }

View File

@ -13,7 +13,7 @@ return [
| |
*/ */
'default' => env('FILESYSTEM_DISK', 'local'), 'default' => env('FILESYSTEM_DISK', 'public'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View File

@ -16,8 +16,15 @@ class ChapterFactory extends Factory
*/ */
public function definition(): array public function definition(): array
{ {
$images = [];
for ($i = 0; $i < 10; $i++) {
$images[] = fake()->imageUrl(400,400,'cats');
}
return [ return [
// 'title' => fake()->title(),
'images' => $images,
'manga_id' => rand(1, 10),
'user_id' => rand(1, 10)
]; ];
} }
} }

View File

@ -2,6 +2,9 @@
namespace Database\Factories; namespace Database\Factories;
use Illuminate\Support\Str;
use function Laravel\Prompts\text;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
/** /**
@ -16,8 +19,15 @@ class MangaFactory extends Factory
*/ */
public function definition(): array public function definition(): array
{ {
$title = fake()->name();
$summary = fake()->paragraph(5);
return [ return [
// 'title' => $title,
'slug' => Str::slug($title),
'summary' => $summary,
'excerpt' => Str::words($summary, 10, '...'),
'cover' => fake()->imageUrl(400, 400, 'cats'),
'author_id' => rand(1,10),
]; ];
} }
} }

View File

@ -3,6 +3,7 @@
namespace Database\Factories; namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str; use Illuminate\Support\Str;
/** /**
@ -21,7 +22,8 @@ class UserFactory extends Factory
'name' => fake()->name(), 'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(), 'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(), 'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 'password' => Hash::make('12345678'),
// 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10), 'remember_token' => Str::random(10),
]; ];
} }

View File

@ -15,6 +15,7 @@ return new class extends Migration
$table->id(); $table->id();
$table->string('name'); $table->string('name');
$table->string('email')->unique(); $table->string('email')->unique();
$table->enum('role', ['user', 'admin'])->default('user');
$table->timestamp('email_verified_at')->nullable(); $table->timestamp('email_verified_at')->nullable();
$table->string('password'); $table->string('password');
$table->rememberToken(); $table->rememberToken();

View File

@ -13,6 +13,12 @@ return new class extends Migration
{ {
Schema::create('mangas', function (Blueprint $table) { Schema::create('mangas', function (Blueprint $table) {
$table->id(); $table->id();
$table->string('title');
$table->string('slug')->nullable();
$table->longText('summary');
$table->string('excerpt')->nullable();
$table->string('cover')->nullable();
$table->foreignId('author_id');
$table->timestamps(); $table->timestamps();
}); });
} }

View File

@ -13,8 +13,13 @@ return new class extends Migration
{ {
Schema::create('chapters', function (Blueprint $table) { Schema::create('chapters', function (Blueprint $table) {
$table->id(); $table->id();
$table->string('title')->nullable();
$table->json('images');
$table->foreignId('manga_id')->constrained()->onDelete('cascade');
$table->foreignId('user_id');
$table->timestamps(); $table->timestamps();
}); });
} }
/** /**

View File

@ -2,6 +2,7 @@
namespace Database\Seeders; namespace Database\Seeders;
use App\Models\Chapter;
use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
@ -12,6 +13,6 @@ class ChapterSeeder extends Seeder
*/ */
public function run(): void public function run(): void
{ {
// Chapter::factory(50)->create();
} }
} }

View File

@ -3,6 +3,7 @@
namespace Database\Seeders; namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents; // use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder class DatabaseSeeder extends Seeder
@ -15,8 +16,14 @@ class DatabaseSeeder extends Seeder
// \App\Models\User::factory(10)->create(); // \App\Models\User::factory(10)->create();
// \App\Models\User::factory()->create([ // \App\Models\User::factory()->create([
// 'name' => 'Test User', // 'name' => 'Luke',
// 'email' => 'test@example.com', // 'email' => 'luke@gmail.com',
// 'password' => Hash::make('12345678'),
// ]); // ]);
$this->call([
UserSeeder::class,
MangaSeeder::class,
ChapterSeeder::class
]);
} }
} }

View File

@ -2,6 +2,7 @@
namespace Database\Seeders; namespace Database\Seeders;
use App\Models\Manga;
use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
@ -12,6 +13,6 @@ class MangaSeeder extends Seeder
*/ */
public function run(): void public function run(): void
{ {
// Manga::factory(10)->create();
} }
} }

View File

@ -0,0 +1,25 @@
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
class UserSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
User::factory(9)->create();
User::factory()->create([
'name' => 'Luke',
'email' => 'luke@gmail.com',
'password' => Hash::make('12345678'),
'role' => 'admin'
]);
}
}

View File

@ -18,23 +18,7 @@
// Bootstrap // Bootstrap
@import 'bootstrap/scss/bootstrap'; @import 'bootstrap/scss/bootstrap';
@import "../../node_modules/bootstrap/scss/functions";
.alert-msg {
// Required transform: translateX(-50%) translateY(10%);
@import "../../node_modules/bootstrap/scss/variables"; }
@import "../node_modules/bootstrap/scss/variables-dark";
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/root";
$custom-colors:(
'lightGrey' : #ebebeb,
'grey' : #7b7b7b
);
// Merge the maps
$theme-colors : map-merge($theme-colors, $custom-colors);

View File

@ -1,4 +1,4 @@
@extends('layouts.app') @extends('layouts.master')
@section('content') @section('content')
<div class="container"> <div class="container">

View File

@ -1,4 +1,4 @@
@extends('layouts.app') @extends('layouts.master')
@section('content') @section('content')
<div class="container"> <div class="container">

View File

@ -1,4 +1,4 @@
@extends('layouts.app') @extends('layouts.master')
@section('content') @section('content')
<div class="container"> <div class="container">

View File

@ -0,0 +1,33 @@
@extends('layouts.app')
@section('content')
<form method="POST" action="{{route('chapter.store')}}" enctype="multipart/form-data">
@csrf
<div class="mb-3">
<label for="">Choose Manga</label>
<select name="manga_id" id="" class="form-select">
<option>Select Manga</option>
@foreach (App\Models\Manga::latest('id')->get() as $manga)
<option value="{{$manga->id}}" {{ $manga->id == request()->manga_id ? 'selected' : ''}}> {{$manga->title}} </option>
@endforeach
</select>
@error('manga_id')
<p class="text-danger small">{{ $message }}</p>
@enderror
</div>
<div class="mb-3">
<label for="">Chapter Title <span class="text-danger">*Optinal</span></label>
<input type="text" name="title" class="form-control">
@error('title')
<p class="text-danger small">{{ $message }}</p>
@enderror
</div>
<div class="mb-3">
<label for="">Chapter Images</label>
<input type="file" name="images[]" id="" class="form-control" multiple>
</div>
<button type="submit" class="btn btn-outline-dark">Create</button>
</form>
@endsection

View File

@ -0,0 +1,24 @@
@extends('layouts.app')
@section('content')
<div class="row">
@foreach ($mangas as $manga)
<div class="col-6 col-md-3 mb-4">
<a class="text-decoration-none" href="{{ route('chapters.manage', $manga->slug) }}">
<card class="card card-body">
<div>
<img src="{{ asset($manga->cover) }}" class="w-100" alt="">
</div>
<p class="fw-semibold mt-2 mb-0"> {{ $manga->title }} </p>
<p class="text-black-50 small">Total Chapter :
<span class="bg-warning p-1 py-0 rounded-circle"> {{ $manga->chapters->count() }} </span>
</p>
</card>
</a>
</div>
@endforeach
</div>
<div>
{{ $mangas->links() }}
</div>
@endsection

View File

@ -0,0 +1,27 @@
@extends('layouts.app')
@section('content')
<div class="mb-4">
<a title="back" href="{{ url()->previous() }}" class="btn btn-dark"> <i class="bi bi-arrow-left"></i> </a>
<a href="{{ route('chapter.index') }}" class="btn btn-dark"> <i class="bi bi-book"></i> Chapter List</a>
</div>
<h3> {{ $manga->title }} </h3>
<hr>
<h5> Chapters </h5>
<div class="row">
@foreach ($manga->chapters()->latest('id')->get() as $chapter)
<div class="col-2">
<div class="d-flex p-2 border border-1 border-dark rounded align-items-center justify-content-between mb-3">
<p class="small mb-0"> {{ $chapter->title }} </p>
<div class="btn-group">
<form method="POST" action="{{ route('chapter.destroy', $chapter->id) }}">
@csrf
@method('delete')
<button onclick="return confirm('Do you want to delete this?')" class="btn btn-outline-dark btn-sm"> <i class="bi bi-trash"></i> </button>
</form>
</div>
</div>
</div>
@endforeach
</div>
@endsection

View File

@ -0,0 +1,57 @@
@extends('layouts.master')
@section('content')
<h3 class="fw-semibold my-4"> {{ $manga->title }} - {{ $chapter->title }} </h3>
<div class="text-center mx-auto my-5">
{{-- breadcrumb --}}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item text-decoration-none"><a href="{{ route('page.index') }}">Home</a></li>
<li class="breadcrumb-item text-decoration-none"><a href="{{ route('page.manga', $manga->slug) }}">
{{ $manga->title }} </a></li>
<li class="breadcrumb-item active" aria-current="page">Chapter {{ $chapter->id }} </li>
</ol>
</nav>
{{-- select box and paginate --}}
<div class="my-4 d-flex justify-content-between">
<div class="col-4">
<select name="" id="" class="form-select bg-dark text-white">
@foreach ($manga->chapters()->latest('id')->get() as $chap)
<option value="{{ $chap->id }}" {{ $chap->id == $chapter->id ? 'selected' : '' }}>
{{ $chap->title }} </option>
@endforeach
</select>
</div>
<div>
<a href="" class="btn btn-dark btn-small">Previous</a>
<a href="" class="btn btn-dark btn-small">Next</a>
</div>
</div>
{{-- manga images --}}
<div class="mb-4">
@foreach ($chapter->images as $image)
<img src="{{ asset($image) }}" class="mx-auto w-50 my-0" alt="">
@endforeach
</div>
<hr>
{{-- chapters and pagiantion --}}
<div class="my-5 d-flex justify-content-between">
<div class="col-4">
<select name="" id="" class="form-select bg-dark text-white">
@foreach ($manga->chapters()->latest('id')->get() as $chap)
<option value="{{ $chap->id }}" {{ $chap->id == $chapter->id ? 'selected' : '' }}>
{{ $chap->title }} </option>
@endforeach
</select>
</div>
<div>
<a href="" class="btn btn-dark btn-small">Previous</a>
<a href="" class="btn btn-dark btn-small">Next</a>
{{-- {{ $allChap->links() }} --}}
</div>
</div>
</div>
@endsection

View File

@ -1,9 +1,6 @@
@extends('layouts.app') @extends('layouts.app')
@section('content') @section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card"> <div class="card">
<div class="card-header">{{ __('Dashboard') }}</div> <div class="card-header">{{ __('Dashboard') }}</div>
@ -17,7 +14,4 @@
{{ __('You are logged in!') }} {{ __('You are logged in!') }}
</div> </div>
</div> </div>
</div>
</div>
</div>
@endsection @endsection

View File

@ -4,8 +4,36 @@
@section('content') @section('content')
<div class="row mt-5"> <div class="row mt-5">
<div class="col-12 col-md-9"> <div class="col-12 col-md-9">
<div class="row justify-content-center flex-wrap"> <div class="row flex-wrap">
@foreach ($mangas as $manga)
<div class="col-6 col-md-3"> <div class="col-6 col-md-3">
<div class="card border-0">
<div class="text-center">
<a href="{{ route('page.manga', $manga->slug) }}">
<img src="{{ asset( $manga->cover ) }}" alt="img"
class="w-100">
</a>
</div>
<div class="mt-2">
<h5 class="fw-semibold "> {{ $manga->title }} </h5>
@forelse ($manga->chapters()->latest('id')->limit(2)->get() as $chapter)
<a href="{{ route('page.chapter', [$chapter->manga->slug, $chapter->id]) }}"
class="d-block text-decoration-none text-white d-flex justify-content-between flex-wrap my-2">
<span class=" bg-secondary rounded-pill small py-0 px-2">
{{ $chapter->title }}
</span>
<span class="small text-black-50">
{{ $chapter->created_at->diffforhumans() }}
</span>
</a>
@empty
@endforelse
</div>
</div>
</div>
@endforeach
{{-- <div class="col-6 col-md-3">
<div class="card border-0"> <div class="card border-0">
<div class="text-center"> <div class="text-center">
<img src="{{ asset('img/sample.jpg') }}" alt="img" class="w-100 "> <img src="{{ asset('img/sample.jpg') }}" alt="img" class="w-100 ">
@ -26,57 +54,16 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div> --}}
<div class="col-6 col-md-3">
<div class="card border-0">
<div class="text-center">
<img src="{{ asset('img/sample.jpg') }}" alt="img" class="w-100 ">
</div>
<div class="mt-2">
<h5 class="fw-semibold ">The Villainous Desciple</h5>
<div class="d-flex justify-content-between flex-wrap mb-1">
<a href=""
class="text-decoration-none text-white bg-secondary rounded-pill py-0 px-2">Chapter
5</a>
<span class=" fs-6">5 mins ago</span>
</div>
<div class="d-flex justify-content-between flex-wrap mb-1">
<a href=""
class="text-decoration-none text-white bg-secondary rounded-pill py-0 px-2">Chapter
4</a>
<span class=" fs-6">4 mins ago</span>
</div>
</div>
</div>
</div>
<div class="col-6 col-md-3">dfg</div>
<div class="col-6 col-md-3">gdfg</div>
</div> </div>
</div> </div>
<div class="col-12 col-md-3"> <div class="col-12 col-md-3">
<h4 class="fw-semibold">Manga Hot</h4> @include('partials.hot-manga')
<div class="row">
<div class="col-12 mt-3">
<div class="d-flex align-items-start border-0">
<img src="{{ asset('img/sample.jpg') }}" alt="img" style="width: 80px">
<div class="ms-2">
<p class="fw-semibold mb-1">The Villainous Desciple</p>
<div class="d-flex justify-content-between flex-wrap mb-2">
<a href=""
class="text-decoration-none text-white fs-6 bg-secondary rounded-pill px-1">Chapter
5</a>
<span class=" fs-6">5 mins ago</span>
</div>
<div class="d-flex justify-content-between flex-wrap mb-2">
<a href=""
class="text-decoration-none text-white fs-6 bg-secondary rounded-pill px-1">Chapter
4</a>
<span class=" fs-6">4 mins ago</span>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
@endsection @endsection
@section('footer')
@include('partials.footer')
@endsection

View File

@ -1,5 +1,6 @@
<!doctype html> <!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
@ -16,6 +17,7 @@
<!-- Scripts --> <!-- Scripts -->
@vite(['resources/sass/app.scss', 'resources/js/app.js']) @vite(['resources/sass/app.scss', 'resources/js/app.js'])
</head> </head>
<body> <body>
<div id="app"> <div id="app">
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm"> <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
@ -23,7 +25,9 @@
<a class="navbar-brand" href="{{ url('/') }}"> <a class="navbar-brand" href="{{ url('/') }}">
{{ config('app.name', 'Laravel') }} {{ config('app.name', 'Laravel') }}
</a> </a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}"> <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
@ -50,7 +54,8 @@
@endif @endif
@else @else
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre> <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button"
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
{{ Auth::user()->name }} {{ Auth::user()->name }}
</a> </a>
@ -72,9 +77,24 @@
</div> </div>
</nav> </nav>
<main class="py-4"> <div class="container">
<main class="py-4 row">
<div class="col-2">
@include('partials.side-bar')
</div>
<div class="col-10">
@yield('content') @yield('content')
</div>
</main> </main>
</div> </div>
{{-- alert-smg --}}
@include('partials.alert-msg')
</div>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ config('app.name', 'MangaDex') }}</title>
<!-- Css -->
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
</head>
<body>
@include('partials.nav')
<div class="container">
<div class="row">
<!-- sidebar Here -->
<div class="col-3">
</div>
<!-- Content Here -->
<div class="main col-9">
@yield('content')
</div>
</div>
</div>
</body>
</html>

View File

@ -14,13 +14,14 @@
<body> <body>
<!-- Header Here --> <!-- Header Here -->
@include('partials.nav') @include('partials.nav')
@include('partials.patreon-nav')
<!-- Content Here --> <!-- Content Here -->
<div class="main container"> <div class="main container">
@yield('content') @yield('content')
</div> </div>
@yield('footer')
</body> </body>

View File

@ -0,0 +1,28 @@
@extends('layouts.master')
@section('content')
<a href="{{ url()->previous() }}" class="btn btn-dark">Back</a>
<div>
<div class="text-center">
<img class="w-25" src="{{ $manga->cover ? asset( $manga->cover) : '' }}" alt="">
</div>
<h3 class="text-center my-3">{{ $manga->title }}</h3>
<p> {{ $manga->summary }} </p>
<ul class="list-group my-3 mt-5 text-center w-50 mx-auto">
<h5 class="fw-bold mb-3">
Chapters
</h5>
@forelse ($manga->chapters()->latest('id')->get() as $chapter)
<a href="{{ route('page.chapter', [$manga->slug, $chapter->id]) }}" class="list-group-item list-group-item-action">
{{ $chapter->title }}
</a>
@empty
<p class="text-danger">No Chapter Yet!</p>
@endforelse
</ul>
</div>
@endsection
@section('footer')
@include('partials.footer')
@endsection

View File

@ -0,0 +1,29 @@
@extends('layouts.app')
@section('content')
<form method="POST" action="{{ route('manga.store') }}" enctype="multipart/form-data">
@csrf
<div class="mb-3">
<label for="">Manga Title</label>
<input type="text" name="title" class="form-control">
@error('title')
<p class="text-danger small">{{ $message }}</p>
@enderror
</div>
<div class="mb-3">
<label for="">Manga Cover</label>
<input type="file" name="cover" id="" class="form-control">
</div>
<div class="mb-3">
<label for="">Manga Summary</label>
<textarea name="summary" id="" cols="30" rows="6" class="form-control p-3"
placeholder="Write A Summary">
</textarea>
@error('summary')
<p class="text-danger small">{{ $message }}</p>
@enderror
</div>
<button type="submit" class="btn btn-outline-dark">Create</button>
</form>
@endsection

View File

@ -0,0 +1,28 @@
@extends('layouts.app')
@section('content')
<div class="px-3 mb-4">
<a href="{{ url()->previous() }}" class="btn btn-dark">Back</a>
<hr>
<div class="">
<h3 class="my-3"> Title : <span class="fw-semibold ">{{ $manga->title }}</span> </h3>
<hr>
<p class="f">Cover Image :</p>
<div class="text-center mb-4">
<img class="w-25" src="{{ $manga->cover ? asset( $manga->cover) : '' }}" alt="">
</div>
<hr>
<p class="mb-0">Summary :</p>
<p class="text-black-50 small"> {{ $manga->summary }} </p>
<div class="d-flex justify-content-between">
<p>Total Chapter : <span class="text-primary fw-semibold">{{$manga->chapters->count()}} chapters</span> </p>
<div>
<a href="" class="btn btn-outline-dark btn-sm">Go Manage Chapters <i class="bi bi-arrow-right-circle-fill"></i> </a>
</div>
</div>
<hr>
</div>
</div>
@endsection

View File

@ -0,0 +1,35 @@
@extends('layouts.app')
@section('content')
<a href="{{route('manga.index')}}" class="btn btn-dark"> <i class="bi bi-house-heart-fill"></i> Home</a>
<hr>
<form method="POST" action="{{ route('manga.update', $manga->id) }}" enctype="multipart/form-data">
@csrf
@method('PUT')
<div class="mb-3">
<label for="">Manga Title</label>
<input type="text" name="title" class="form-control" value="{{ $manga->title ?? old('title') }}">
@error('title')
<p class="text-danger small">{{ $message }}</p>
@enderror
</div>
<div class="mb-3">
<label for="">Manga Cover</label>
<img src="{{ $manga->cover ? asset($manga->cover) : null }}" class="w-50 d-block my-3" alt="">
<input type="file" name="cover" id="" class="form-control">
</div>
<div class="mb-3">
<label for="">Manga Summary</label>
<textarea name="summary" id="" cols="30" rows="6" class="form-control p-3"
placeholder="Write A Summary">
{{ $manga->summary ?? old('summary') }}
</textarea>
@error('summary')
<p class="text-danger small">{{ $message }}</p>
@enderror
</div>
<button type="submit" class="btn btn-outline-dark">Update</button>
</form>
@endsection

View File

@ -0,0 +1,68 @@
@extends('layouts.app')
@section('content')
<div class="card">
<div class="card-body">
<h5>Manga 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%">Title</th>
<th>Author</th>
<th scope="col">Total Chapters</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
@forelse ($mangas as $manga)
<tr>
<th scope="row"> {{ $manga->id }} </th>
<td>
<p class="mb-0">{{ $manga->title }}</p>
<span class="small text-black-50">{{ $manga->excerpt }}</span>
</td>
<td>
{{ $manga->user->name }}
</td>
<td class="text-center">
{{$manga->chapters->count()}}
</td>
<td>
<div class="btn-group">
<a href="{{route('manga.show', $manga->slug)}}" class="btn btn-outline-dark"><i class="bi bi-exclamation-diamond"></i></a>
<a href="{{ route('manga.edit', $manga->id) }}" class="btn btn-outline-dark"
title="edit">
<i class="bi bi-pencil-square"></i>
</a>
<button class="btn btn-outline-dark" form="deleteForm{{ $manga->id }}"
title="delete" onclick="return confirm('Are sure to delete?')">
<i class="bi bi-trash3"></i>
</button>
</div>
<form method="post" id="deleteForm{{ $manga->id }}"
action="{{ route('manga.destroy', $manga->id) }}" class="d-inline-block">
@csrf
@method('delete')
</form>
</td>
</tr>
@empty
@endforelse
</tbody>
</table>
</div>
<div class="">
{{ $mangas->links() }}
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,6 @@
@if (session()->has('message'))
<div x-data="{ show: true }" x-init="setTimeout(() => show = false, 3000)" x-show="show"
class="bg-dark text-center text-white rounded w-50 p-3 pb-1 position-fixed top-0 start-50 alert-msg" style="z-index:100000000">
<p>{{ session('message') }}</p>
</div>
@endif

View File

@ -0,0 +1,3 @@
<div class="bg-dark py-5 mt-5">
<p class="text-center fw-bold text-white">Copyright All Served @MangaDex</p>
</div>

View File

@ -0,0 +1,25 @@
<h4 class="fw-semibold">Manga Hot</h4>
<div class="row">
@foreach ($hotMangas as $hotManga)
<div class="col-12 mt-3">
<div class="d-flex border-0">
<div>
<a href="{{ route('page.manga', $hotManga->slug) }}"><img src="{{ asset($hotManga->cover) }}" alt="img" style="width: 80px"></a>
</div>
<div class="ms-2">
<p class="fw-semibold mb-1"> {{ $hotManga->title }} </p>
@foreach ($hotManga->chapters()->latest('id')->limit(2)->get() as $hotChap)
<div class="d-flex justify-content-between flex-wrap mb-2">
<a href="{{route('page.chapter',[$hotManga->slug, $hotChap->id])}}"
class="text-decoration-none text-white small bg-secondary rounded-pill px-1">
{{ $hotChap->title }}
</a>
<span class="small"> {{$hotChap->created_at->diffForHumans()}} </span>
</div>
@endforeach
</div>
</div>
</div>
@endforeach
</div>

View File

@ -1,6 +1,6 @@
<nav class="navbar navbar-expand-lg bg-primary py-3"> <nav class="navbar navbar-expand-lg bg-primary py-3">
<div class="container"> <div class="container">
<a class="navbar-brand" href="#">MangaDex</a> <a class="navbar-brand" href="{{ route('page.index') }}">MangaDex</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
@ -10,7 +10,7 @@
<div class="collapse navbar-collapse" id="navbarSupportedContent"> <div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0"> <ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">HOME</a> <a class="nav-link active" aria-current="page" href="{{ route('page.index') }}">HOME</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="#">CONTACT US</a> <a class="nav-link" href="#">CONTACT US</a>
@ -24,5 +24,29 @@
</div> </div>
</form> </form>
</div> </div>
<!--profile and logout -->
@auth
<div class="btn btn-outline-dark dropdown ms-3">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button"
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
<i class="bi bi-person-circle"></i> {{ Auth::user()->name }}
</a>
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
@csrf
</form>
</div>
</div>
@endauth
</div> </div>
</nav> </nav>

View File

@ -0,0 +1,20 @@
<!-- another nav-->
<ul class="d-flex flex-wrap container mt-3">
<div class="d-flex flex-wrap">
<a href="" class="list-group-item me-2">DISCORD</a>
<a href="" class="list-group-item me-2">PAYPAL</a>
<a href="" class="list-group-item me-2">PATREON</a>
<a href="" class="list-group-item me-2">GENRE</a>
</div>
<div class="ms-auto">
@guest
<a href="{{ route('login') }}" class="btn btn-sm btn-outline-dark rounded-pill">Login</a>
<a href="{{ route('register') }}" class="btn btn-sm btn-outline-dark rounded-pill">Register</a>
@endguest
@auth
<a href="{{ route('home') }}" class="btn btn-sm btn-dark rounded-pill"> <i class="bi bi-speedometer"></i> Go To Dashboard</a>
@endauth
</div>
</ul>
<hr>

View File

@ -0,0 +1,11 @@
<ul class="list-group">
<h5>Manga</h5>
<a href="{{route('manga.index')}}" class="list-group-item list-group-item-action"><i class="bi bi-book"></i> Manga List </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>
<a href=" {{route('chapter.index')}} " class="list-group-item list-group-item-action"><i class="bi bi-book"></i> Chapter List </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>
</ul>

View File

@ -1,5 +1,10 @@
<?php <?php
use App\Http\Controllers\ChapterController;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\MangaController;
use App\Http\Controllers\PageController;
use App\Models\Chapter;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
@ -14,11 +19,17 @@ use Illuminate\Support\Facades\Route;
| |
*/ */
Route::get('/', function () { Route::controller(PageController::class)->group(function() {
return view('index'); Route::get('/','index')->name('page.index');
Route::get('/MangaDex/manga/{slug}', 'manga')->name('page.manga');
Route::get('/manga/{manga:slug}/chapter/{chapter}', 'chapter')->name('page.chapter');
}); });
Auth::routes(); Auth::routes();
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home'); Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::resource('manga', MangaController::class)->middleware('auth');
Route::resource('chapter', ChapterController::class)->middleware('auth');
Route::get('/chapters/manage/{manga:slug}', [ChapterController::class, 'manage'])->name('chapters.manage')->middleware('auth');