diff --git a/app/Http/Controllers/BlogController.php b/app/Http/Controllers/BlogController.php new file mode 100644 index 0000000..687630b --- /dev/null +++ b/app/Http/Controllers/BlogController.php @@ -0,0 +1,145 @@ +get(); + return view('blogs.index', compact('blogs')); + } + + public function create() + { + return view('blogs.create'); + } + + public function store(Request $request) + { + $validated = $request->validate([ + 'title' => 'required', + 'thumbnail' => 'required|image|mimes:jpeg,png,jpg,webp', + 'banner' => 'nullable|image|mimes:jpeg,png,jpg,webp', + 'subtitle1' => 'nullable|string', + 'description1' => 'nullable|string', + 'subtitle2' => 'nullable|string', + 'description2' => 'nullable|string', + 'image' => 'nullable|image|mimes:jpeg,png,jpg,webp', + 'button_text' => 'required|string', + 'button_url' => 'nullable|string', + 'display_order' => 'nullable|integer', + 'is_published' => 'nullable|boolean', + ]); + if ($request->hasFile('thumbnail')) { + $validated['thumbnail'] = $request->file('thumbnail')->store('blogs/thumbnails', 'public'); + } + + if ($request->hasFile('banner')) { + $validated['banner'] = $request->file('banner')->store('blogs/banners', 'public'); + } + + if ($request->hasFile('image')) { + $validated['image'] = $request->file('image')->store('blogs/images', 'public'); + } + + $validated['is_published'] = $request->has('is_published'); // checkbox handling + + Blog::create($validated); + + return redirect()->route('blogs.index')->with('success', 'Blog created successfully'); + } + + + public function show($id) + { + $blog = Blog::findOrFail($id); + return view('blogs.show', compact('blog')); + } + + public function edit($id) + { + $blog = Blog::findOrFail($id); + return view('blogs.edit', compact('blog')); + } + + public function update(Request $request, Blog $blog) + { + $validated = $request->validate([ + 'title' => 'required|string', + 'thumbnail' => 'required|image|mimes:jpeg,png,jpg,webp', + 'banner' => 'nullable|image|mimes:jpeg,png,jpg,webp', + 'subtitle1' => 'nullable|string', + 'description1' => 'nullable|string', + 'subtitle2' => 'nullable|string', + 'description2' => 'nullable|string', + 'image' => 'nullable|image|mimes:jpeg,png,jpg,webp', + 'button_text' => 'required|string', + 'button_url' => 'nullable|string', + 'display_order' => 'nullable|integer', + 'is_published' => 'nullable|boolean', + ]); + + if ($request->hasFile('thumbnail')) { + if ($blog->thumbnail && Storage::disk('public')->exists($blog->thumbnail)) { + Storage::disk('public')->delete($blog->thumbnail); + } + $validated['thumbnail'] = $request->file('thumbnail')->store('blogs/thumbnails', 'public'); + } + + // Handle banner file + if ($request->hasFile('banner')) { + if ($blog->banner && Storage::disk('public')->exists($blog->banner)) { + Storage::disk('public')->delete($blog->banner); + } + $validated['banner'] = $request->file('banner')->store('blogs/banners', 'public'); + } + + // Handle image file + if ($request->hasFile('image')) { + if ($blog->image && Storage::disk('public')->exists($blog->image)) { + Storage::disk('public')->delete($blog->image); + } + $validated['image'] = $request->file('image')->store('blogs/images', 'public'); + } + + $validated['is_published'] = $request->has('is_published'); // checkbox handling + + $blog->update($validated); + + return redirect()->route('blogs.index')->with('success', 'Blog updated successfully'); + } + + public function destroy($id) + { + $blog = Blog::findOrFail($id); + if ($blog->image && Storage::disk('public')->exists($blog->image)) { + Storage::disk('public')->delete($blog->image); + } + $blog->delete(); + return redirect()->route('blogs.index')->with('success', 'Blog deleted successfully'); + } + + public function togglePublish(Request $request, $id) + { + $blog = Blog::findOrFail($id); + $blog->is_published = $request->input('is_published'); // input, not has() + $blog->save(); + + return response()->json(['success' => true, 'message' => 'Publish status updated.']); + } + + public function updateOrder(Request $request) + { + foreach ($request->order as $item) { + Blog::where('id', $item['id'])->update(['display_order' => $item['display_order']]); + } + + return response()->json(['status' => 'success']); + } + +} diff --git a/app/Http/Controllers/FrontendController.php b/app/Http/Controllers/FrontendController.php index a261749..5ed5e17 100644 --- a/app/Http/Controllers/FrontendController.php +++ b/app/Http/Controllers/FrontendController.php @@ -11,6 +11,7 @@ use App\Models\Preparation; use App\Models\Service; use App\Models\About; use App\Models\Testimonial; +use App\Models\Blog; class FrontendController extends Controller { @@ -24,7 +25,10 @@ class FrontendController extends Controller $data['testimonials'] = Testimonial::all(); // $data['partners'] = Partner::all(); // $data['passers'] = Passer::all(); - // $data['blogs'] = Blog::latest()->take(3)->get(); + $data['blogs'] = Blog::where('is_published', true) + ->orderBy('display_order', 'asc') + ->take(3) + ->get(); return view('frontend.home',$data); } @@ -33,6 +37,14 @@ class FrontendController extends Controller $posts = Post::all(); return view('frontend.about', compact('posts')); } + + public function blogDetails($id) + { + $blog = Blog::findOrFail($id); + $otherBlogs = Blog::where('id', '!=', $id)->latest()->take(5)->get(); // Latest 5 except current + return view('frontend.blog-details', compact('blog', 'otherBlogs')); + } + } diff --git a/app/Models/blog.php b/app/Models/blog.php new file mode 100644 index 0000000..9d98570 --- /dev/null +++ b/app/Models/blog.php @@ -0,0 +1,23 @@ +id(); + $table->string('title'); + $table->string('thumbnail'); + $table->string('banner')->nullable(); + $table->string('subtitle1')->nullable(); + $table->text('description1')->nullable(); + $table->string('subtitle2')->nullable(); + $table->text('description2')->nullable(); + $table->string('image')->nullable(); + $table->string('button_text'); + $table->string('button_url')->nullable(); + $table->integer('display_order')->nullable(); + $table->boolean('is_published')->default(false); + $table->timestamps(); + }); + } + + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists(table: 'blog'); + } +}; diff --git a/resources/views/blogs/create.blade.php b/resources/views/blogs/create.blade.php new file mode 100644 index 0000000..4fee41a --- /dev/null +++ b/resources/views/blogs/create.blade.php @@ -0,0 +1,71 @@ +@extends('layouts.app') + +@section('content') +
+

Add Blog

+
+ @csrf + +
+ + +
+
+ + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + + Cancel +
+
+@endsection diff --git a/resources/views/blogs/edit.blade.php b/resources/views/blogs/edit.blade.php new file mode 100644 index 0000000..29fd64b --- /dev/null +++ b/resources/views/blogs/edit.blade.php @@ -0,0 +1,87 @@ +@extends('layouts.app') + +@section('content') +
+

Edit Blog

+
+ @csrf + @method('PUT') + +
+ + +
+ +
+ + + @if ($blog->thumbnail) +

Current thumbnail:

+ + @endif +
+ +
+ + + @if ($blog->banner) +

Current banner:

+ + @endif +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + @if ($blog->image) +

Current image:

+ + @endif +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ is_published) ? 'checked' : '' }}> + +
+ + + Cancel +
+
+@endsection diff --git a/resources/views/blogs/index.blade.php b/resources/views/blogs/index.blade.php new file mode 100644 index 0000000..2049fd3 --- /dev/null +++ b/resources/views/blogs/index.blade.php @@ -0,0 +1,142 @@ +@extends('layouts.app') + +@section('content') +
+

Blogs

+ + Create New Blog + + @if(session('success')) +
{{ session('success') }}
+ @endif + + + + + + + + + + + + + + + @forelse($blogs as $blog) + + + + + + + + + + + @empty + + @endforelse + +
TitleThumbnailButton TextButton URLDisplay OrderPublishActions
{{ $blog->title }} + @if($blog->thumbnail) + bg-img + @else + N/A + @endif + {{ $blog->button_text }}{{ $blog->button_url }}{{ $blog->display_order }} +
+ is_published ? 'checked' : '' }}> +
+ + +
+ View + Edit +
+ @csrf @method('DELETE') + +
+
No blogs found.
+
+@endsection + + +@section('scripts') + + + + +@endsection diff --git a/resources/views/blogs/show.blade.php b/resources/views/blogs/show.blade.php new file mode 100644 index 0000000..3af7ec5 --- /dev/null +++ b/resources/views/blogs/show.blade.php @@ -0,0 +1,69 @@ +@extends('layouts.app') + +@section('content') +
+

Blog Details

+ + + + Edit + Back to List +
+@endsection diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index 0a64709..62582fa 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -12,6 +12,7 @@ Manage Services Manage Abouts Manage Testimonials + Manage Blogs diff --git a/resources/views/frontend/blog-details.blade.php b/resources/views/frontend/blog-details.blade.php new file mode 100644 index 0000000..f3f947f --- /dev/null +++ b/resources/views/frontend/blog-details.blade.php @@ -0,0 +1,89 @@ +@extends('layouts.app') +@section('content') +@include('frontend.header') + +
+
+
+
+
+
+

{{ $blog->title }}

+
+ +
+
+
+
+
+ + +
+ +
+
+
+
+
+
+
+
+
+

{{ $blog->subtitle1 }}

+
+

{{ $blog->description1 }}

+
+
+
+
+
+
+
+ blog-01 +
+
+
+
+
+
+

{{ $blog->subtitle2 }}

+
+
+

{{ $blog->description2 }}

+
+
+
+
+
+
+
+

Popular Posts

+ +
+
+
+
+
+
+ +@include('frontend.footer') +@endsection diff --git a/resources/views/frontend/footer.blade.php b/resources/views/frontend/footer.blade.php index 9e8785c..bf14e3e 100644 --- a/resources/views/frontend/footer.blade.php +++ b/resources/views/frontend/footer.blade.php @@ -122,7 +122,6 @@ - diff --git a/resources/views/frontend/home.blade.php b/resources/views/frontend/home.blade.php index 924d755..fa3bc4d 100644 --- a/resources/views/frontend/home.blade.php +++ b/resources/views/frontend/home.blade.php @@ -10,6 +10,6 @@ @include('frontend.partials.testimonial', ['testimonials' => $testimonials]) {{-- @include('frontend.partials.partners', ['partners' => $partners]) --}} {{-- @include('frontend.partials.passers', ['passers' => $passers]) --}} - {{-- @include('frontend.partials.blog', ['blogs' => $blogs]) --}} + @include('frontend.partials.blog', ['blogs' => $blogs]) @include('frontend.footer') @endsection diff --git a/resources/views/frontend/partials/blog.blade.php b/resources/views/frontend/partials/blog.blade.php new file mode 100644 index 0000000..c4cfddd --- /dev/null +++ b/resources/views/frontend/partials/blog.blade.php @@ -0,0 +1,51 @@ + +
+
+
+
+ +
+
+

READ OUR BLOG

+

We Provide Special Service For Patients

+
+
+
+
+ +
+ + @foreach($blogs as $blog) +
+ +
+ @endforeach + +
+
+
+ diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 0d9dd43..0097cb9 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -14,6 +14,7 @@ + @yield('scripts') @vite(['resources/sass/app.scss', 'resources/js/app.js']) diff --git a/routes/web.php b/routes/web.php index d9ffe65..6f6d890 100644 --- a/routes/web.php +++ b/routes/web.php @@ -10,9 +10,11 @@ use App\Http\Controllers\PreparationController; use App\Http\Controllers\ServiceController; use App\Http\Controllers\AboutController; use App\Http\Controllers\TestimonialController; +use App\Http\Controllers\BlogController; Route::get('/', [FrontendController::class, 'homePage'])->name('home'); Route::get('/aboutpage', [FrontendController::class, 'aboutPage'])->name('aboutpage'); +Route::get('/blog-details/{id}', [FrontendController::class, 'blogDetails'])->name('frontend.blog-details'); Route::get('/dashboard', function () { @@ -28,6 +30,10 @@ Route::middleware('auth')->group(function () { Route::resource('services',ServiceController::class); Route::resource('abouts', AboutController::class); Route::resource('testimonials', TestimonialController::class); + Route::resource('blogs', BlogController::class); + Route::patch('/blogs/{id}/toggle-publish', [BlogController::class, 'togglePublish'])->name('blogs.togglePublish'); + Route::post('/blogs/update-order', [BlogController::class, 'updateOrder'])->name('blogs.updateOrder'); + }); Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])->name('logout');