# 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
<?php
use App\Models\Post;
use Livewire\Volt\Component;

new class extends Component {
    public function with(): array
    {
        return [
            'latestPosts' => 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)
<section id="posts" class="py-16 lg:py-20 bg-background">
    <div class="container mx-auto px-4">
        <div class="text-center mb-12">
            <h2 class="text-2xl lg:text-3xl font-semibold text-text mb-4">
                {{ __('home.posts_title') }}
            </h2>
        </div>

        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
            @foreach($latestPosts as $post)
                <article class="bg-card p-6 rounded-lg shadow-card">
                    <time class="text-xs text-body/70 mb-2 block">
                        {{ $post->created_at->translatedFormat('j F Y') }}
                    </time>
                    <h3 class="text-lg font-bold text-text mb-3">
                        <a href="{{ route('posts.show', $post) }}" class="hover:text-cta transition-colors">
                            {{ $post->title }}
                        </a>
                    </h3>
                    <p class="text-body text-sm mb-4 line-clamp-3">
                        {{ Str::limit(strip_tags($post->body), 150) }}
                    </p>
                    <a href="{{ route('posts.show', $post) }}" class="text-cta font-medium text-sm hover:text-cta-hover">
                        {{ __('home.read_more') }} →
                    </a>
                </article>
            @endforeach
        </div>

        <div class="text-center">
            <flux:button variant="ghost" href="{{ route('posts.index') }}">
                {{ __('home.view_all_posts') }}
            </flux:button>
        </div>
    </div>
</section>
@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
