--- phase: 04-enrichment plan: 02 subsystem: ui tags: [react, typescript, unsplash, thumbnail, settings, tanstack-query] # Dependency graph requires: - phase: 04-01 provides: UnsplashService backend + unsplash_api_key in Settings schema + image_url_map nel job JSON provides: - Campo API Key Unsplash in pagina Settings con sezione dedicata "Immagini" - Thumbnail cover image in PostCard (80x56px) quando cover_image_keyword e' un URL reale - Hint discreto in OutputReview che suggerisce di configurare Unsplash se non presente - Types aggiornati: Settings con unsplash_api_key, SettingsStatus con unsplash_api_key_configured affects: - deploy (frontend pronto per deploy completo fase 4) # Tech tracking tech-stack: added: [] patterns: - "Logica di submit difensiva: campi API key non inviati se vuoti (evita sovrascrittura)" - "Hint contestuali condizionali via useSettingsStatus (scompaiono quando risolto)" - "Thumbnail lazy con onError fallback (nasconde immagine se URL non valido)" - "Rilevamento URL reale via startsWith('http') — pattern semplice e affidabile" key-files: created: [] modified: - frontend/src/types.ts - frontend/src/pages/Settings.tsx - frontend/src/components/PostCard.tsx - frontend/src/pages/OutputReview.tsx key-decisions: - "Pattern Link da react-router-dom (non useNavigate) per navigazione a /impostazioni — coerente col codebase" - "showUnsplashKey state separato da showApiKey — toggle indipendenti per le due API key" - "Thumbnail 80x56px (w-20 h-14) — anteprima sufficiente senza appesantire la pagina con 13 immagini" - "Hint OutputReview volutamente discreto (text-stone-600) — non aggressivo, scompare silenziosamente" patterns-established: - "Tutti i campi API key: non pre-popolati nel form, non inviati se vuoti, reset dopo salvataggio" - "useSettingsStatus() come fonte di verita' per feature-gating UI (configured vs not)" # Metrics duration: 3min completed: 2026-03-09 --- # Phase 4 Plan 02: Frontend Unsplash — Settings, Thumbnail, Hint Summary **Campo Unsplash API key in Settings, thumbnail cover image 80x56px in PostCard, e hint contestuale in OutputReview con Link a /impostazioni** ## Performance - **Duration:** ~3 min - **Started:** 2026-03-09T07:14:26Z - **Completed:** 2026-03-09T07:17:09Z - **Tasks:** 2 - **Files modified:** 4 ## Accomplishments - Types TypeScript aggiornati: `unsplash_api_key` in `Settings`, `unsplash_api_key_configured` in `SettingsStatus` - Pagina Settings: nuova sezione "Immagini" con input API Key Unsplash, toggle visibilita' indipendente, helper text condizionale (diverso se key configurata o no), logica submit identica a API Key Claude (non invia se vuota) - PostCard: thumbnail 80x56px della cover image visibile solo quando `cover_image_keyword` e' un URL reale (`startsWith('http')`), con `loading="lazy"` e `onError` per fallback silenzioso - OutputReview: hint discreto con Link a `/impostazioni` visibile solo quando `unsplash_api_key_configured === false`, scompare automaticamente dopo configurazione ## Task Commits Ogni task e' stato committato atomicamente: 1. **Task 1: Types + Settings page + hooks per Unsplash** - `d537c03` (feat) 2. **Task 2: Thumbnail PostCard + hint OutputReview** - `f154f1b` (feat) **Plan metadata:** (doc commit segue) ## Files Created/Modified - `frontend/src/types.ts` - Aggiunto `unsplash_api_key` a Settings, `unsplash_api_key_configured` a SettingsStatus - `frontend/src/pages/Settings.tsx` - Sezione "Immagini" con campo Unsplash API key, state showUnsplashKey, logica submit, reset post-salvataggio - `frontend/src/components/PostCard.tsx` - Thumbnail condizionale dopo cover_title nella sezione SUCCESS - `frontend/src/pages/OutputReview.tsx` - Import Link e useSettingsStatus, hint discreto Unsplash con Link a /impostazioni ## Decisions Made - **Link vs navigate():** Usato `Link` da `react-router-dom` con `to="/impostazioni"` (pattern usato in tutto il codebase, es. Dashboard, GenerateCalendar, GenerateSingle) — non introdotto `useNavigate` che non era necessario - **showUnsplashKey separato:** State `showUnsplashKey` indipendente da `showApiKey` — ogni campo API key ha il proprio toggle, coerente con comportamento atteso - **Thumbnail size 80x56px:** `w-20 h-14` — abbastanza grande per dare un'anteprima visiva significativa, abbastanza piccolo da non dominare la card con 13 post in pagina - **Hint discreto stone-600:** Testo volutamente sottotono, non un warning aggressivo. Colore amber solo sul link di azione ## Deviations from Plan Nessuna — piano eseguito esattamente come scritto. ## Issues Encountered Nessuno. ## User Setup Required None — l'API key Unsplash si configura ora direttamente dalla UI in Settings. ## Next Phase Readiness - Frontend completo per tutte le 4 fasi (core generation, prompt control, organization, enrichment) - Pronto per `vps-lab-deploy` per testing end-to-end completo - Per testare Unsplash: configurare API key in Settings, avviare generazione bulk, verificare thumbnail in OutputReview e URL immagini nel CSV scaricato --- *Phase: 04-enrichment* *Completed: 2026-03-09*