more fixes
This commit is contained in:
31
resources/views/news/_article_card.blade.php
Normal file
31
resources/views/news/_article_card.blade.php
Normal file
@@ -0,0 +1,31 @@
|
||||
{{-- Reusable article card partial --}}
|
||||
<div class="card h-100 border-0 shadow-sm news-card">
|
||||
@if($article->cover_url)
|
||||
<a href="{{ route('news.show', $article->slug) }}">
|
||||
<img src="{{ $article->cover_url }}" class="card-img-top"
|
||||
alt="{{ $article->title }}"
|
||||
style="height:180px;object-fit:cover;">
|
||||
</a>
|
||||
@endif
|
||||
<div class="card-body d-flex flex-column">
|
||||
@if($article->category)
|
||||
<a href="{{ route('news.category', $article->category->slug) }}"
|
||||
class="badge badge-primary mb-2 align-self-start">{{ $article->category->name }}</a>
|
||||
@endif
|
||||
|
||||
<h6 class="card-title mb-1">
|
||||
<a href="{{ route('news.show', $article->slug) }}" class="text-dark text-decoration-none">
|
||||
{{ $article->title }}
|
||||
</a>
|
||||
</h6>
|
||||
|
||||
@if($article->excerpt)
|
||||
<p class="card-text text-muted small flex-grow-1">{{ Str::limit($article->excerpt, 100) }}</p>
|
||||
@endif
|
||||
|
||||
<div class="text-muted small mt-2 d-flex justify-content-between">
|
||||
<span>{{ $article->published_at?->format('d M Y') }}</span>
|
||||
<span><i class="fas fa-eye mr-1"></i>{{ number_format($article->views) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
59
resources/views/news/_sidebar.blade.php
Normal file
59
resources/views/news/_sidebar.blade.php
Normal file
@@ -0,0 +1,59 @@
|
||||
{{-- Sidebar partial for news frontend --}}
|
||||
|
||||
{{-- Categories widget --}}
|
||||
@if(!empty($categories) && $categories->isNotEmpty())
|
||||
<div class="card mb-4">
|
||||
<div class="card-header"><strong>Categories</strong></div>
|
||||
<div class="list-group list-group-flush">
|
||||
@foreach($categories as $cat)
|
||||
<a href="{{ route('news.category', $cat->slug) }}"
|
||||
class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
|
||||
{{ $cat->name }}
|
||||
<span class="badge badge-secondary badge-pill">{{ $cat->published_articles_count ?? 0 }}</span>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Trending articles --}}
|
||||
@if(!empty($trending) && $trending->isNotEmpty())
|
||||
<div class="card mb-4">
|
||||
<div class="card-header"><strong><i class="fas fa-fire mr-1 text-danger"></i> Trending</strong></div>
|
||||
<div class="list-group list-group-flush">
|
||||
@foreach($trending as $item)
|
||||
<a href="{{ route('news.show', $item->slug) }}"
|
||||
class="list-group-item list-group-item-action py-2">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<span class="font-weight-bold small">{{ Str::limit($item->title, 55) }}</span>
|
||||
<span class="badge badge-info badge-pill ml-2">{{ number_format($item->views) }}</span>
|
||||
</div>
|
||||
<small class="text-muted">{{ $item->published_at?->diffForHumans() }}</small>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Tags cloud --}}
|
||||
@if(!empty($tags) && $tags->isNotEmpty())
|
||||
<div class="card mb-4">
|
||||
<div class="card-header"><strong><i class="fas fa-tags mr-1"></i> Tags</strong></div>
|
||||
<div class="card-body">
|
||||
@foreach($tags as $tag)
|
||||
<a href="{{ route('news.tag', $tag->slug) }}" class="badge badge-secondary mr-1 mb-1">
|
||||
{{ $tag->name }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- RSS link --}}
|
||||
<div class="card mb-4">
|
||||
<div class="card-body text-center">
|
||||
<a href="{{ route('news.rss') }}" class="btn btn-outline-warning btn-sm" target="_blank">
|
||||
<i class="fas fa-rss mr-1"></i> RSS Feed
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
30
resources/views/news/category.blade.php
Normal file
30
resources/views/news/category.blade.php
Normal file
@@ -0,0 +1,30 @@
|
||||
@extends('news.layout', [
|
||||
'metaTitle' => $category->name . ' — News',
|
||||
])
|
||||
|
||||
@section('news_content')
|
||||
<div class="container py-5">
|
||||
<h1 class="mb-1">{{ $category->name }}</h1>
|
||||
@if($category->description)
|
||||
<p class="text-muted mb-4">{{ $category->description }}</p>
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div class="row">
|
||||
@forelse($articles as $article)
|
||||
<div class="col-sm-6 mb-4">
|
||||
@include('news._article_card', ['article' => $article])
|
||||
</div>
|
||||
@empty
|
||||
<div class="col-12 text-center text-muted py-5">No articles in this category.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
<div class="mt-3">{{ $articles->links() }}</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
@include('news._sidebar', ['categories' => $categories])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
69
resources/views/news/index.blade.php
Normal file
69
resources/views/news/index.blade.php
Normal file
@@ -0,0 +1,69 @@
|
||||
@extends('news.layout', [
|
||||
'metaTitle' => config('news.rss_title', 'News'),
|
||||
'metaDescription' => config('news.rss_description', ''),
|
||||
])
|
||||
|
||||
@section('news_content')
|
||||
<div class="news-index">
|
||||
<div class="container py-5">
|
||||
|
||||
{{-- Featured article --}}
|
||||
@if($featured)
|
||||
<section class="mb-5">
|
||||
<a href="{{ route('news.show', $featured->slug) }}" class="text-decoration-none">
|
||||
<div class="card border-0 shadow-sm overflow-hidden news-featured">
|
||||
@if($featured->cover_url)
|
||||
<img src="{{ $featured->cover_url }}" class="card-img" alt="{{ $featured->title }}"
|
||||
style="height:400px;object-fit:cover;">
|
||||
@endif
|
||||
<div class="card-img-overlay d-flex align-items-end p-4"
|
||||
style="background:linear-gradient(transparent,rgba(0,0,0,0.75))">
|
||||
<div class="text-white">
|
||||
@if($featured->category)
|
||||
<span class="badge badge-primary mb-2">{{ $featured->category->name }}</span>
|
||||
@endif
|
||||
<h2 class="font-weight-bold">{{ $featured->title }}</h2>
|
||||
<p class="mb-1">{{ Str::limit(strip_tags((string)$featured->excerpt), 180) }}</p>
|
||||
<small>
|
||||
{{ $featured->author?->name }} ·
|
||||
{{ $featured->published_at?->format('d M Y') }} ·
|
||||
{{ $featured->reading_time }} min read
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</section>
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
{{-- Articles grid --}}
|
||||
<div class="col-lg-8">
|
||||
<div class="row">
|
||||
@forelse($articles as $article)
|
||||
<div class="col-sm-6 mb-4">
|
||||
@include('news._article_card', ['article' => $article])
|
||||
</div>
|
||||
@empty
|
||||
<div class="col-12 text-center text-muted py-5">No news articles published yet.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
{{ $articles->links() }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Sidebar --}}
|
||||
<div class="col-lg-4">
|
||||
@include('news._sidebar', [
|
||||
'categories' => $categories,
|
||||
'trending' => $trending,
|
||||
'tags' => $tags,
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
15
resources/views/news/layout.blade.php
Normal file
15
resources/views/news/layout.blade.php
Normal file
@@ -0,0 +1,15 @@
|
||||
{{--
|
||||
Frontend layout wrapper for the News section.
|
||||
Extends the main app layout.
|
||||
--}}
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', $metaTitle ?? config('news.rss_title', 'News'))
|
||||
|
||||
@if(isset($metaDescription))
|
||||
@section('meta_description', $metaDescription)
|
||||
@endif
|
||||
|
||||
@section('content')
|
||||
@yield('news_content')
|
||||
@endsection
|
||||
113
resources/views/news/show.blade.php
Normal file
113
resources/views/news/show.blade.php
Normal file
@@ -0,0 +1,113 @@
|
||||
@extends('news.layout', [
|
||||
'metaTitle' => $article->meta_title ?: $article->title,
|
||||
'metaDescription' => $article->meta_description ?: Str::limit(strip_tags((string)$article->excerpt), 160),
|
||||
])
|
||||
|
||||
@section('news_content')
|
||||
|
||||
{{-- OpenGraph meta --}}
|
||||
@push('head')
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="og:title" content="{{ $article->effective_og_title }}">
|
||||
<meta property="og:description" content="{{ $article->effective_og_description }}">
|
||||
@if($article->effective_og_image)
|
||||
<meta property="og:image" content="{{ $article->effective_og_image }}">
|
||||
@endif
|
||||
<meta property="article:published_time" content="{{ $article->published_at?->toIso8601String() }}">
|
||||
<meta property="article:author" content="{{ $article->author?->name }}">
|
||||
@if($article->meta_keywords)
|
||||
<meta name="keywords" content="{{ $article->meta_keywords }}">
|
||||
@endif
|
||||
@endpush
|
||||
|
||||
<div class="news-article">
|
||||
<div class="container py-5">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
|
||||
{{-- Cover image --}}
|
||||
@if($article->cover_url)
|
||||
<img src="{{ $article->cover_url }}" class="img-fluid rounded mb-4 w-100"
|
||||
alt="{{ $article->title }}" style="max-height:450px;object-fit:cover;">
|
||||
@endif
|
||||
|
||||
{{-- Meta --}}
|
||||
<div class="d-flex align-items-center mb-3 text-muted small">
|
||||
@if($article->category)
|
||||
<a href="{{ route('news.category', $article->category->slug) }}"
|
||||
class="badge badge-primary mr-2">{{ $article->category->name }}</a>
|
||||
@endif
|
||||
<span>{{ $article->author?->name }}</span>
|
||||
<span class="mx-2">·</span>
|
||||
<span>{{ $article->published_at?->format('d M Y') }}</span>
|
||||
<span class="mx-2">·</span>
|
||||
<span><i class="fas fa-clock mr-1"></i>{{ $article->reading_time }} min read</span>
|
||||
<span class="mx-2">·</span>
|
||||
<span><i class="fas fa-eye mr-1"></i>{{ number_format($article->views) }}</span>
|
||||
</div>
|
||||
|
||||
<h1 class="mb-3">{{ $article->title }}</h1>
|
||||
|
||||
@if($article->excerpt)
|
||||
<p class="lead text-muted mb-4">{{ $article->excerpt }}</p>
|
||||
@endif
|
||||
|
||||
<div class="news-content">
|
||||
{!! $article->content !!}
|
||||
</div>
|
||||
|
||||
{{-- Tags --}}
|
||||
@if($article->tags->isNotEmpty())
|
||||
<div class="mt-4">
|
||||
<strong><i class="fas fa-tags mr-1"></i></strong>
|
||||
@foreach($article->tags as $tag)
|
||||
<a href="{{ route('news.tag', $tag->slug) }}"
|
||||
class="badge badge-secondary mr-1">{{ $tag->name }}</a>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Share buttons --}}
|
||||
<div class="mt-4 pt-4 border-top">
|
||||
<strong>Share:</strong>
|
||||
<a href="https://twitter.com/intent/tweet?url={{ urlencode(url()->current()) }}&text={{ urlencode($article->title) }}"
|
||||
class="btn btn-sm btn-info ml-2" target="_blank" rel="noopener noreferrer">
|
||||
<i class="fab fa-twitter"></i> Twitter
|
||||
</a>
|
||||
<a href="https://www.facebook.com/sharer/sharer.php?u={{ urlencode(url()->current()) }}"
|
||||
class="btn btn-sm btn-primary ml-2" target="_blank" rel="noopener noreferrer">
|
||||
<i class="fab fa-facebook"></i> Facebook
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- Forum discussion link --}}
|
||||
@if($article->forum_thread_id)
|
||||
<div class="mt-4 alert alert-secondary">
|
||||
<i class="fas fa-comments mr-2"></i>
|
||||
<strong>Join the discussion:</strong>
|
||||
<a href="{{ url('/forum/thread/discussion-' . $article->slug) }}" class="ml-1">
|
||||
Discussion: {{ $article->title }}
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Related articles --}}
|
||||
@if($related->isNotEmpty())
|
||||
<div class="mt-5">
|
||||
<h4 class="mb-3">Related Articles</h4>
|
||||
<div class="row">
|
||||
@foreach($related as $rel)
|
||||
<div class="col-sm-6 mb-3">
|
||||
@include('news._article_card', ['article' => $rel])
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>{{-- col-lg-8 --}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
29
resources/views/news/tag.blade.php
Normal file
29
resources/views/news/tag.blade.php
Normal file
@@ -0,0 +1,29 @@
|
||||
@extends('news.layout', [
|
||||
'metaTitle' => '#' . $tag->name . ' — News',
|
||||
])
|
||||
|
||||
@section('news_content')
|
||||
<div class="container py-5">
|
||||
<h1 class="mb-4">
|
||||
<i class="fas fa-tag mr-2"></i>#{{ $tag->name }}
|
||||
</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div class="row">
|
||||
@forelse($articles as $article)
|
||||
<div class="col-sm-6 mb-4">
|
||||
@include('news._article_card', ['article' => $article])
|
||||
</div>
|
||||
@empty
|
||||
<div class="col-12 text-center text-muted py-5">No articles with this tag.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
<div class="mt-3">{{ $articles->links() }}</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
@include('news._sidebar', ['categories' => $categories])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user