blogs
This commit is contained in:
145
app/Http/Controllers/BlogController.php
Normal file
145
app/Http/Controllers/BlogController.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Blog;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class BlogController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$blogs = Blog::orderBy('display_order')->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']);
|
||||
}
|
||||
|
||||
}
|
@ -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'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
23
app/Models/blog.php
Normal file
23
app/Models/blog.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class blog extends Model
|
||||
{
|
||||
protected $fillable =[
|
||||
'title',
|
||||
'thumbnail',
|
||||
'banner',
|
||||
'subtitle1',
|
||||
'description1',
|
||||
'subtitle2',
|
||||
'description2',
|
||||
'image',
|
||||
'button_url',
|
||||
'button_text',
|
||||
'display_order',
|
||||
'is_published'
|
||||
];
|
||||
}
|
40
database/migrations/2025_06_06_113520_create_blogs_table.php
Normal file
40
database/migrations/2025_06_06_113520_create_blogs_table.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?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('blogs', function (Blueprint $table) {
|
||||
$table->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');
|
||||
}
|
||||
};
|
71
resources/views/blogs/create.blade.php
Normal file
71
resources/views/blogs/create.blade.php
Normal file
@ -0,0 +1,71 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<h1>Add Blog</h1>
|
||||
<form action="{{ route('blogs.store') }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="title">Title</label>
|
||||
<input type="text" name="title" class="form-control">
|
||||
</div>
|
||||
<div class="form-group mb-3">
|
||||
<label for="thumbnail">thumbnail</label>
|
||||
<input type="file" name="thumbnail" class="form-control">
|
||||
</div>
|
||||
<div class="form-group mb-3">
|
||||
<label for="banner">Banner</label>
|
||||
<input type="file" name="banner" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="subtitle1">Subtitle 1</label>
|
||||
<input type="text" name="subtitle1" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="description1">Description 1</label>
|
||||
<textarea name="description1" rows="4" class="form-control"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="subtitle2">Subtitle 2</label>
|
||||
<input type="text" name="subtitle2" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="description2">Description 2</label>
|
||||
<textarea name="description2" rows="4" class="form-control"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="image">Image</label>
|
||||
<input type="file" name="image" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="button_text">Button Text</label>
|
||||
<input type="text" name="button_text" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="button_url">Button URL</label>
|
||||
<input type="text" name="button_url" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="display_order">Display Order</label>
|
||||
<input type="number" name="display_order" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-check mb-3">
|
||||
<input type="checkbox" name="is_published" id="is_published" class="form-check-input" value="1" {{ old('is_published') ? 'checked' : '' }}>
|
||||
<label class="form-check-label" for="is_published">Publish</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-success">Save</button>
|
||||
<a href="{{ route('blogs.index') }}" class="btn btn-secondary">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
87
resources/views/blogs/edit.blade.php
Normal file
87
resources/views/blogs/edit.blade.php
Normal file
@ -0,0 +1,87 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<h1>Edit Blog</h1>
|
||||
<form method="POST" action="{{ route('blogs.update', $blog->id) }}" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="title" class="form-label">Title</label>
|
||||
<input type="text" name="title" class="form-control" value="{{ old('title', $blog->title) }}">
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="thumbnail" class="form-label">Thumbnail</label>
|
||||
<input type="file" name="thumbnail" class="form-control">
|
||||
@if ($blog->thumbnail)
|
||||
<p>Current thumbnail:</p>
|
||||
<img src="{{ asset('storage/' . $blog->thumbnail) }}" width="150">
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="banner" class="form-label">Banner</label>
|
||||
<input type="file" name="banner" class="form-control">
|
||||
@if ($blog->banner)
|
||||
<p>Current banner:</p>
|
||||
<img src="{{ asset('storage/' . $blog->banner) }}" width="150">
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="subtitle1" class="form-label">Subtitle 1</label>
|
||||
<input type="text" name="subtitle1" class="form-control" value="{{ old('subtitle1', $blog->subtitle1) }}">
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="description1" class="form-label">Description 1</label>
|
||||
<textarea name="description1" class="form-control" rows="4">{{ old('description1', $blog->description1) }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="subtitle2" class="form-label">Subtitle 2</label>
|
||||
<input type="text" name="subtitle2" class="form-control" value="{{ old('subtitle2', $blog->subtitle2) }}">
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="description2" class="form-label">Description 2</label>
|
||||
<textarea name="description2" class="form-control" rows="4">{{ old('description2', $blog->description2) }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="image" class="form-label">Image</label>
|
||||
<input type="file" name="image" class="form-control">
|
||||
@if ($blog->image)
|
||||
<p>Current image:</p>
|
||||
<img src="{{ asset('storage/' . $blog->image) }}" width="150">
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="button_text" class="form-label">Button Text</label>
|
||||
<input type="text" name="button_text" class="form-control" value="{{ old('button_text', $blog->button_text) }}">
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="button_url" class="form-label">Button URL</label>
|
||||
<input type="text" name="button_url" class="form-control" value="{{ old('button_url', $blog->button_url) }}">
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-3">
|
||||
<label for="display_order" class="form-label">Display Order</label>
|
||||
<input type="number" name="display_order" class="form-control" value="{{ old('display_order', $blog->display_order) }}">
|
||||
</div>
|
||||
|
||||
<div class="form-check mb-3">
|
||||
<input type="checkbox" name="is_published" id="is_published" class="form-check-input" value="1"
|
||||
{{ old('is_published', $blog->is_published) ? 'checked' : '' }}>
|
||||
<label class="form-check-label" for="is_published">Publish</label>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-success">Update</button>
|
||||
<a href="{{ route('blogs.index') }}" class="btn btn-danger">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
142
resources/views/blogs/index.blade.php
Normal file
142
resources/views/blogs/index.blade.php
Normal file
@ -0,0 +1,142 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<h1>Blogs</h1>
|
||||
|
||||
<a href="{{ route('blogs.create') }}" class="btn btn-primary mb-3">Create New Blog</a>
|
||||
|
||||
@if(session('success'))
|
||||
<div class="alert alert-success">{{ session('success') }}</div>
|
||||
@endif
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Thumbnail</th>
|
||||
<th>Button Text</th>
|
||||
<th>Button URL</th>
|
||||
<th>Display Order</th>
|
||||
<th>Publish</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($blogs as $blog)
|
||||
<tr data-id="{{ $blog->id }}">
|
||||
<td>{{ $blog->title }}</td>
|
||||
<td>
|
||||
@if($blog->thumbnail)
|
||||
<img src="{{ asset('storage/' . $blog->thumbnail) }}" alt="bg-img" width="100">
|
||||
@else
|
||||
N/A
|
||||
@endif
|
||||
</td>
|
||||
<td>{{ $blog->button_text }}</td>
|
||||
<td>{{ $blog->button_url }}</td>
|
||||
<td>{{ $blog->display_order }}</td>
|
||||
<td>
|
||||
<div class="form-check form-switch">
|
||||
<input type="checkbox"
|
||||
class="form-check-input publish-toggle"
|
||||
data-id="{{ $blog->id }}"
|
||||
{{ $blog->is_published ? 'checked' : '' }}>
|
||||
</div>
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="{{ route('blogs.show', $blog->id) }}" class="btn btn-sm btn-info">View</a>
|
||||
<a href="{{ route('blogs.edit', $blog->id) }}" class="btn btn-sm btn-warning">Edit</a>
|
||||
<form action="{{ route('blogs.destroy', $blog->id) }}" method="POST" style="display:inline-block">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-danger" onclick="return confirm('Delete this blog?')">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="7">No blogs found.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
|
||||
@section('scripts')
|
||||
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const tableBody = document.querySelector("tbody");
|
||||
|
||||
if (tableBody) {
|
||||
new Sortable(tableBody, {
|
||||
animation: 150,
|
||||
onEnd: function () {
|
||||
const order = [];
|
||||
document.querySelectorAll("tbody tr").forEach((row, index) => {
|
||||
order.push({
|
||||
id: row.dataset.id,
|
||||
display_order: index + 1
|
||||
});
|
||||
});
|
||||
|
||||
fetch("{{ route('blogs.updateOrder') }}", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": "{{ csrf_token() }}",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({ order: order })
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
})
|
||||
.catch(err => console.error('Update failed', err));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Existing sortable code...
|
||||
|
||||
// New AJAX publish toggle
|
||||
document.querySelectorAll('.publish-toggle').forEach((checkbox) => {
|
||||
checkbox.addEventListener('change', function () {
|
||||
const blogId = this.dataset.id;
|
||||
const isPublished = this.checked ? 1 : 0;
|
||||
|
||||
fetch(`/blogs/${blogId}/toggle-publish`, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
is_published: isPublished,
|
||||
})
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) throw new Error("Failed to update");
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log("Publish status updated:", data);
|
||||
})
|
||||
.catch(async err => {
|
||||
const errorText = await err?.response?.text?.();
|
||||
console.error("Server error:", errorText);
|
||||
alert("Error updating publish status.");
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@endsection
|
69
resources/views/blogs/show.blade.php
Normal file
69
resources/views/blogs/show.blade.php
Normal file
@ -0,0 +1,69 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<h1>Blog Details</h1>
|
||||
|
||||
<ul class="list-group mb-4">
|
||||
<li class="list-group-item"><strong>Title:</strong> {{ $blog->title }}</li>
|
||||
|
||||
<li class="list-group-item">
|
||||
<strong>Thumbnail:</strong>
|
||||
@if($blog->thumbnail)
|
||||
<div class="mt-2">
|
||||
<img src="{{ Storage::url($blog->thumbnail) }}" alt="Thumbnail" width="200">
|
||||
</div>
|
||||
@else
|
||||
N/A
|
||||
@endif
|
||||
</li>
|
||||
|
||||
<li class="list-group-item">
|
||||
<strong>Banner:</strong>
|
||||
@if($blog->banner)
|
||||
<div class="mt-2">
|
||||
<img src="{{ Storage::url($blog->banner) }}" alt="Banner" width="200">
|
||||
</div>
|
||||
@else
|
||||
N/A
|
||||
@endif
|
||||
</li>
|
||||
|
||||
<li class="list-group-item"><strong>Subtitle 1:</strong> {{ $blog->subtitle1 ?? 'N/A' }}</li>
|
||||
|
||||
<li class="list-group-item">
|
||||
<strong>Description 1:</strong><br>
|
||||
<div class="mt-2">{{ $blog->description1 ?? 'N/A' }}</div>
|
||||
</li>
|
||||
|
||||
<li class="list-group-item"><strong>Subtitle 2:</strong> {{ $blog->subtitle2 ?? 'N/A' }}</li>
|
||||
|
||||
<li class="list-group-item">
|
||||
<strong>Description 2:</strong><br>
|
||||
<div class="mt-2">{{ $blog->description2 ?? 'N/A' }}</div>
|
||||
</li>
|
||||
|
||||
<li class="list-group-item">
|
||||
<strong>Image:</strong>
|
||||
@if($blog->image)
|
||||
<div class="mt-2">
|
||||
<img src="{{ Storage::url($blog->image) }}" alt="Image" width="200">
|
||||
</div>
|
||||
@else
|
||||
N/A
|
||||
@endif
|
||||
</li>
|
||||
|
||||
<li class="list-group-item"><strong>Button Text:</strong> {{ $blog->button_text }}</li>
|
||||
<li class="list-group-item"><strong>Button URL:</strong> {{ $blog->button_url ?? 'N/A' }}</li>
|
||||
<li class="list-group-item"><strong>Display Order:</strong> {{ $blog->display_order ?? 'N/A' }}</li>
|
||||
<li class="list-group-item"><strong>Published:</strong> {{ $blog->is_published ? 'Yes' : 'No' }}</li>
|
||||
|
||||
<li class="list-group-item"><strong>Created At:</strong> {{ $blog->created_at->format('Y-m-d H:i') }}</li>
|
||||
<li class="list-group-item"><strong>Updated At:</strong> {{ $blog->updated_at->format('Y-m-d H:i') }}</li>
|
||||
</ul>
|
||||
|
||||
<a href="{{ route('blogs.edit', $blog->id) }}" class="btn btn-warning">Edit</a>
|
||||
<a href="{{ route('blogs.index') }}" class="btn btn-secondary mt-3">Back to List</a>
|
||||
</div>
|
||||
@endsection
|
@ -12,6 +12,7 @@
|
||||
<a href="{{ route('services.index') }}" class="btn btn-secondary">Manage Services</a>
|
||||
<a href="{{ route('abouts.index') }}" class="btn btn-secondary">Manage Abouts</a>
|
||||
<a href="{{ route('testimonials.index') }}" class="btn btn-secondary">Manage Testimonials</a>
|
||||
<a href="{{ route('blogs.index') }}" class="btn btn-secondary">Manage Blogs</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
89
resources/views/frontend/blog-details.blade.php
Normal file
89
resources/views/frontend/blog-details.blade.php
Normal file
@ -0,0 +1,89 @@
|
||||
@extends('layouts.app')
|
||||
@section('content')
|
||||
@include('frontend.header')
|
||||
<!-- page-title -->
|
||||
<div class="ttm-page-title-row">
|
||||
<div class="ttm-page-title-row-inner">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-12">
|
||||
<div class="page-title-heading">
|
||||
<h2 class="title">{{ $blog->title }}</h2>
|
||||
</div>
|
||||
<div class="breadcrumb-wrapper">
|
||||
<div class="container">
|
||||
<div class="breadcrumb-wrapper-inner">
|
||||
<span><a href="{{ route('home')}}">Home</a></span>
|
||||
<span class="ttm-bread-sep"> / </span>
|
||||
<span>Blog</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- page-title-end -->
|
||||
|
||||
<!--site-main start-->
|
||||
<div class="site-main">
|
||||
|
||||
<section class="ttm-row blog-single-section">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 content-area m-auto">
|
||||
<div class="post ttm-blog-single">
|
||||
<div class="ttm-blog-single-content">
|
||||
<div class="entry-content">
|
||||
<div class="ttm-box-desc-text">
|
||||
<div class="entry-header">
|
||||
<h3 class="entry-title">{{ $blog->subtitle1 }}</h3>
|
||||
</div>
|
||||
<p>{{ $blog->description1 }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ttm-post-featured-wrapper ttm-featured-wrapper w-100">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="ttm_single_image-wrapper">
|
||||
<img class="img-fluid" src="{{ asset('storage/' . $blog->image )}}" width="773" height="317" alt="blog-01">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ttm-blog-single-content mt-20 res-991-mt-20">
|
||||
<div class="entry-header">
|
||||
<h3 class="entry-title">{{ $blog->subtitle2 }}</h3>
|
||||
</div>
|
||||
<div class="entry-content">
|
||||
<p>{{ $blog->description2 }}</p>
|
||||
<div class="ttm-horizontal_sep style2 mt-40 res-991-mt-30"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="widget widget-recent-post clearfix">
|
||||
<h3 class="widget-title">Popular Posts</h3>
|
||||
<ul class="widget-post ttm-recent-post-list">
|
||||
@foreach($otherBlogs as $other)
|
||||
<li>
|
||||
<img class="img-fluid" src="{{ asset('storage/' . $other->image) }}" width="72" height="80" alt="post-img">
|
||||
<div class="post-detail">
|
||||
<a href="{{ route('frontend.blog-details', $other->id) }}">
|
||||
{{ Str::limit($other->title, 40) }}
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<!--site-main end-->
|
||||
@include('frontend.footer')
|
||||
@endsection
|
@ -122,7 +122,6 @@
|
||||
</div><!-- page end -->
|
||||
|
||||
<!-- Javascript -->
|
||||
|
||||
<script src="{{asset('assets/js/jquery.min.js')}}"></script>
|
||||
<script src="{{asset('assets/js/jquery-migrate-1.4.1.min.js')}}"></script>
|
||||
<script src="{{asset('assets/js/tether.min.js')}}"></script>
|
||||
|
@ -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
|
||||
|
51
resources/views/frontend/partials/blog.blade.php
Normal file
51
resources/views/frontend/partials/blog.blade.php
Normal file
@ -0,0 +1,51 @@
|
||||
<!-- about-section-->
|
||||
<section class="ttm-row about-section ttm-bgcolor-grey clearfix">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-6 m-auto">
|
||||
<!-- section title -->
|
||||
<div class="section-title title-style-center_text">
|
||||
<div class="title-header">
|
||||
<h3>READ OUR BLOG</h3>
|
||||
<h2 class="title mb-0">We Provide Special Service For Patients</h2>
|
||||
</div>
|
||||
</div><!-- section title end -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row slick_slider" data-slick='{"slidesToShow": 3, "slidesToScroll": 1, "arrows":false, "dots":false, "autoplay":false, "infinite":true, "responsive": [{"breakpoint":1100,"settings":{"slidesToShow": 3}} , {"breakpoint":991,"settings":{"slidesToShow": 2}}, {"breakpoint":767,"settings":{"slidesToShow": 2}},{"breakpoint":575,"settings":{"slidesToShow": 1}}]}'>
|
||||
|
||||
@foreach($blogs as $blog)
|
||||
<div class="col-lg-4 col-md-6 col-sm-6">
|
||||
<div class="featured-imagebox featured-imagebox-blog style2 m-15">
|
||||
<div class="featured-thumbnail">
|
||||
@if($blog->thumbnail)
|
||||
<img class="img-fluid" src="{{ Storage::url($blog->thumbnail) }}" alt="{{ $blog->title }}" width="740" height="568">
|
||||
@else
|
||||
<img class="img-fluid" src="/images/placeholder.jpg" alt="placeholder" width="740" height="568">
|
||||
@endif
|
||||
</div>
|
||||
<div class="featured-content featured-content-blog align-self-center">
|
||||
<div class="featured-title">
|
||||
<h3>
|
||||
<a href="{{ route('frontend.blog-details', $blog->id) }}">
|
||||
{{ Str::limit($blog->title, 80) }}
|
||||
</a>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="post-footer">
|
||||
<div class="post-footer-link">
|
||||
<a class="ttm-btn btn-inline d-block ttm-btn-size-md ttm-icon-btn-right" href="{{ route('blogs.show', $blog->id) }}">
|
||||
{{ $blog->button_text ?? 'Read More' }}<i class="icon-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- about-section-end-->
|
@ -14,6 +14,7 @@
|
||||
<link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
|
||||
|
||||
<!-- Scripts -->
|
||||
@yield('scripts')
|
||||
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
|
||||
</head>
|
||||
<body>
|
||||
|
@ -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');
|
||||
|
Reference in New Issue
Block a user