# SPRINT 10.5 — INBOX UI (Email List Component)

## METADATA
- Execution: Hodina 5
- Prerekvizity: Sprint 10.4 COMPLETE (Login funguje)
- Deliverables: Inbox.tsx, EmailListItem.tsx, loading/empty states
- Estimated time: 45-55 min
- Output folder: Modifikace v existujícím React projektu z Sprint 10.3

## OBJECTIVES
Vytvořit kompletní Inbox/Email List stránku:
1. Email list s preview (from, subject, date, read/unread)
2. Funkční pro INBOX i SENT folder
3. Infinite scroll / load more pagination
4. Empty state pro prázdný inbox
5. Loading skeleton
6. Batch actions (select, delete, move)
7. Pull-to-refresh

## STEP-BY-STEP INSTRUCTIONS

### Krok 1: Email List Item component
**Soubor:** `src/components/EmailListItem.tsx`

Každý email v seznamu zobrazuje:
- Checkbox (pro batch select)
- Unread indicator (modrá tečka vlevo pokud is_read=false)
- From (bold pokud unread): zobrazit jméno nebo email
- Subject (truncated na 1 řádek)
- Preview body (truncated na 1 řádek, šedý text)
- Date (relative: "5m ago", "2h ago", "Yesterday", "Mar 28")
- Star toggle (optional)

**Styling:**
- Container: `flex items-center gap-3 px-4 py-3 border-b border-sky-border hover:bg-sky-card cursor-pointer transition-colors`
- Unread row: zvýraznit background `bg-sky-bg2`
- Selected row: `bg-amber-500/10 border-l-2 border-sky-accent`

onClick → navigate to `/email/${email_id}`

### Krok 2: Nahradit placeholder Inbox.tsx
**Soubor:** `src/pages/Inbox.tsx`

Kompletní inbox stránka:

**Toolbar (nahoře):**
- Checkbox "Select all"
- Akce: Delete, Move to (dropdown), Mark read/unread
- Refresh button
- Email count: "1-50 of 234"

**Email list:**
- Map přes `emails` z emailStore
- Každý email = `<EmailListItem />`
- Infinite scroll: když user scrollne dolů → loadMore s cursor

**Empty state:**
- Ikona mailboxu
- "Your inbox is empty"
- "Emails sent to your @skymailbox.net address will appear here"

**Loading state:**
- 5-8 skeleton rows (pulsující šedé boxy)

**Funkce:**
- `useEffect` → loadInbox() nebo loadSent() based na route (/inbox vs /sent)
- useLocation() pro detekci folder
- Batch select: checkbox toggle, select all
- Delete selected: volat deleteEmail pro každý selected
- Search bar nahoře (placeholder pro Sprint 10.8)

### Krok 3: Relative date utility
**Soubor:** `src/lib/dateUtils.ts`
```ts
export function relativeDate(isoDate: string): string {
  const date = new Date(isoDate);
  const now = new Date();
  const diffMs = now.getTime() - date.getTime();
  const diffMin = Math.floor(diffMs / 60000);
  const diffHour = Math.floor(diffMs / 3600000);
  const diffDay = Math.floor(diffMs / 86400000);

  if (diffMin < 1) return 'now';
  if (diffMin < 60) return `${diffMin}m`;
  if (diffHour < 24) return `${diffHour}h`;
  if (diffDay === 1) return 'Yesterday';
  if (diffDay < 7) return date.toLocaleDateString('en', { weekday: 'short' });
  return date.toLocaleDateString('en', { month: 'short', day: 'numeric' });
}
```

### Krok 4: Testovat
1. `npm run dev`
2. Login → ověřit redirect na inbox
3. Ověřit loading skeleton se zobrazí
4. Ověřit empty state pokud žádné emaily
5. Pokud API funguje — ověřit reálné emaily se zobrazí
6. Click na email → naviguje na /email/:id

## COMPLETION CHECKLIST
- [ ] EmailListItem renderuje správně
- [ ] Inbox stránka načítá emaily z API
- [ ] Loading skeleton funguje
- [ ] Empty state zobrazuje se správně
- [ ] Click na email naviguje na detail
- [ ] Batch select (checkbox) funguje
- [ ] Toolbar akce (delete, refresh)
- [ ] /sent route zobrazuje sent emaily
- [ ] Relative dates formátují správně
- [ ] Build prochází

## DELIVERABLES LIST
1. `src/components/EmailListItem.tsx`
2. `src/pages/Inbox.tsx` (updated)
3. `src/lib/dateUtils.ts`
4. `SPRINT_10.5_COMPLETE.md`

## COMPLETION REPORT TEMPLATE
```markdown
# ✅ SPRINT 10.5 — INBOX UI — COMPLETE

## Timestamp
[ISO datetime]

## Status
COMPLETE / FAILED

## Components
- EmailListItem.tsx: OK
- Inbox.tsx: OK
- dateUtils.ts: OK

## Visual Check
- Email list: OK/ISSUE
- Loading skeleton: OK/ISSUE
- Empty state: OK/ISSUE
- Batch select: OK/ISSUE

## Next Sprint
SPRINT_10.6_READER_UI
```
