# Story 14.5: Latest Posts Section ## Story **As a** website visitor **I want to** see recent legal articles and updates on the home page **So that** I can access valuable legal content and see that the firm is active ## Acceptance Criteria ### AC1: Section Container **Given** a visitor scrolls to the latest posts section **When** viewing the section **Then** display with: - Warm Cream (`#F4F1EA`) background - Section ID `id="posts"` for anchor linking - Adequate padding (64px vertical on desktop) ### AC2: Section Heading **Given** the latest posts section **When** displayed **Then** show a section heading: - English: "Latest Articles" or "Legal Insights" - Arabic: "أحدث المقالات" or "رؤى قانونية" - Typography: H2, SemiBold, Forest Green (`#2D322A`) - Centered alignment ### AC3: Display 3 Latest Posts **Given** the posts section **When** posts exist in the database **Then** display the 3 most recent published posts showing: - Post title - Publication date - Brief excerpt (first 100-150 characters of body) - "Read More" link ### AC4: Post Card Design **Given** each post card **When** displayed **Then** include: - Card background: White (`#FFFFFF`) - Title: Bold, Forest Green (`#2D322A`), clickable link - Date: Small text, muted color - Excerpt: Body text, truncated with ellipsis - "Read More" link: Warm Gold (`#A68966`) - Subtle shadow and border-radius - Hover effect on card or title ### AC5: Empty State **Given** the posts section **When** no published posts exist **Then** either: - Hide the entire section, OR - Show a message: "Articles coming soon" / "المقالات قريباً" ### AC6: View All Link **Given** the posts section **When** posts are displayed **Then** show a "View All Articles" / "عرض جميع المقالات" link: - Links to `/posts` - Styled as secondary button or text link with arrow - Positioned below the post cards, centered ### AC7: Grid Layout **Given** different screen sizes **When** viewing the posts section: - **Desktop (≥992px):** 3 columns (1 row of 3 cards) - **Tablet (576-991px):** 2 columns + 1 below, or 3 columns - **Mobile (<576px):** 1 column (3 rows, stacked) ### AC8: RTL Support **Given** Arabic language is selected **When** viewing the posts section **Then** cards and text align right-to-left correctly ### AC9: Dynamic Data **Given** the posts section **When** rendered **Then** query posts from database: ```php Post::where('status', 'published') ->latest() ->take(3) ->get() ``` ## Technical Notes ### Files to Modify - `resources/views/pages/home.blade.php` - Add posts section with data query - `lang/en/home.php` - Add translations - `lang/ar/home.php` - Add translations ### Controller/Page Component The home page needs to pass posts data. Options: 1. Use a Livewire/Volt component to fetch posts 2. Pass posts via route closure or controller **Option 1: Volt Component (Recommended)** Convert `home.blade.php` to a Volt component: ```php Post::where('status', 'published') ->latest() ->take(3) ->get(), ]; } }; ?> ``` **Option 2: Route with data** ```php // routes/web.php Route::get('/', function () { return view('pages.home', [ 'latestPosts' => Post::where('status', 'published') ->latest() ->take(3) ->get(), ]); })->name('home'); ``` ### HTML Structure ```blade @if($latestPosts->count() > 0)

{{ __('home.posts_title') }}

@foreach($latestPosts as $post) @endforeach
{{ __('home.view_all_posts') }}
@endif ``` ### Translation Keys ```php // lang/en/home.php (additions) 'posts_title' => 'Latest Articles', 'read_more' => 'Read More', 'view_all_posts' => 'View All Articles', 'posts_empty' => 'Articles coming soon', // lang/ar/home.php (additions) 'posts_title' => 'أحدث المقالات', 'read_more' => 'اقرأ المزيد', 'view_all_posts' => 'عرض جميع المقالات', 'posts_empty' => 'المقالات قريباً', ``` ### Post Model Reference Existing Post model fields: - `title` - Post title (bilingual stored via JSON or separate fields) - `body` - Post content - `status` - 'draft' or 'published' - `created_at` - Timestamp ### Date Formatting Use Laravel's `translatedFormat()` for bilingual dates: ```php $post->created_at->translatedFormat('j F Y') // English: "15 January 2026" // Arabic: "15 يناير 2026" ``` ## Dev Checklist - [x] Determine data passing method (Volt component or route) - [x] Create posts section HTML structure - [x] Add section heading with translations - [x] Implement post card design - [x] Query and display 3 latest published posts - [x] Add date formatting with translation support - [x] Implement excerpt truncation - [x] Add "Read More" links to individual posts - [x] Add "View All" link to posts index - [x] Handle empty state (hide section or show message) - [x] Implement responsive grid layout - [x] Test RTL layout - [x] Verify links work correctly ## Estimation **Complexity:** Medium (requires data fetching) **Risk:** Low - Uses existing Post model and routes ## Dependencies - Previous stories for page structure - Existing Post model - Posts routes (`posts.index`, `posts.show`) --- ## Dev Agent Record ### Status Ready for Review ### Agent Model Used Claude Opus 4.5 (claude-opus-4-5-20251101) ### File List | File | Action | |------|--------| | `resources/views/livewire/pages/home.blade.php` | Created (new Volt component) | | `resources/views/pages/home.blade.php` | Deleted (replaced by Volt component) | | `routes/web.php` | Modified (changed to Volt::route) | | `lang/en/home.php` | Modified (added posts translations) | | `lang/ar/home.php` | Modified (added posts translations) | | `tests/Feature/Public/HomePageTest.php` | Modified (added 17 new tests) | ### Change Log - Converted home page from plain Blade view to Volt component with `with()` method for data fetching - Added latest posts section that displays 3 most recent published posts - Implemented responsive grid layout (1 col mobile, 2 col tablet, 3 col desktop) - Added post cards with title, date, excerpt, and "Read More" links - Added "View All Articles" button linking to posts index - Section hidden when no published posts exist (empty state) - Used Post model's `getTitle()` and `getExcerpt()` methods for bilingual support - Uses `published_at` for ordering and display, with fallback to `created_at` - Added wire:navigate for SPA-like navigation - Added hover effects on cards and title links ### Debug Log References None - implementation completed without issues ### Completion Notes - All acceptance criteria met - 17 new tests added covering posts section functionality - All 91 home page and posts tests pass - RTL support inherited from existing layout structure - Uses existing Post model scope `published()` for filtering