feat(04-02): thumbnail PostCard e hint Unsplash in OutputReview
- PostCard: thumbnail 80x56px della cover image quando keyword e' URL
- Rilevamento con startsWith('http')
- object-cover, loading=lazy, onError nasconde se URL non valido
- Posizionato dopo cover_title e prima dei metadati secondari
- OutputReview: hint discreto Unsplash sotto il box info edit inline
- Visibile solo se unsplash_api_key_configured === false
- Link a /impostazioni con stile amber discreto
- Scompare automaticamente dopo configurazione Unsplash
- Usa Link da react-router-dom (pattern codebase)
This commit is contained in:
@@ -181,6 +181,19 @@ export function PostCard({
|
|||||||
{post.cover_title}
|
{post.cover_title}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
{/* Thumbnail cover image (solo se keyword e' un URL reale) */}
|
||||||
|
{post.cover_image_keyword.startsWith('http') && (
|
||||||
|
<div className="mt-2 mb-1">
|
||||||
|
<img
|
||||||
|
src={post.cover_image_keyword}
|
||||||
|
alt="Cover preview"
|
||||||
|
loading="lazy"
|
||||||
|
className="w-20 h-14 object-cover rounded-md border border-stone-700"
|
||||||
|
onError={(e) => { (e.target as HTMLImageElement).style.display = 'none' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Metadati secondari */}
|
{/* Metadati secondari */}
|
||||||
{slot && (
|
{slot && (
|
||||||
<div className="flex flex-wrap gap-x-3 gap-y-0.5 mt-2">
|
<div className="flex flex-wrap gap-x-3 gap-y-0.5 mt-2">
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
import { Download, Loader2, RefreshCw } from 'lucide-react'
|
import { Download, Loader2, RefreshCw } from 'lucide-react'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useParams } from 'react-router-dom'
|
import { Link, useParams } from 'react-router-dom'
|
||||||
import { useDownloadEditedCsv, useJobResults } from '../api/hooks'
|
import { useDownloadEditedCsv, useJobResults, useSettingsStatus } from '../api/hooks'
|
||||||
import { PostCard } from '../components/PostCard'
|
import { PostCard } from '../components/PostCard'
|
||||||
import type { PostResult } from '../types'
|
import type { PostResult } from '../types'
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@ export function OutputReview() {
|
|||||||
const { jobId } = useParams<{ jobId: string }>()
|
const { jobId } = useParams<{ jobId: string }>()
|
||||||
const { data: jobData, isLoading, error } = useJobResults(jobId ?? null)
|
const { data: jobData, isLoading, error } = useJobResults(jobId ?? null)
|
||||||
const downloadMutation = useDownloadEditedCsv()
|
const downloadMutation = useDownloadEditedCsv()
|
||||||
|
const { data: settingsStatus } = useSettingsStatus()
|
||||||
|
|
||||||
// Stato locale dei post — viene aggiornato da edit inline e rigenerazione
|
// Stato locale dei post — viene aggiornato da edit inline e rigenerazione
|
||||||
const [localResults, setLocalResults] = useState<PostResult[]>([])
|
const [localResults, setLocalResults] = useState<PostResult[]>([])
|
||||||
@@ -156,6 +157,20 @@ export function OutputReview() {
|
|||||||
Le modifiche saranno incluse nel CSV scaricato.
|
Le modifiche saranno incluse nel CSV scaricato.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Hint Unsplash — visibile solo se non configurato */}
|
||||||
|
{settingsStatus && !settingsStatus.unsplash_api_key_configured && (
|
||||||
|
<div className="px-4 py-2 rounded-lg bg-stone-800/30 border border-stone-700/50 text-xs text-stone-600 flex items-center gap-2 flex-wrap">
|
||||||
|
<span>Le colonne immagine contengono keyword testuali.</span>
|
||||||
|
<Link
|
||||||
|
to="/impostazioni"
|
||||||
|
className="text-amber-500/70 hover:text-amber-400 underline underline-offset-2 transition-colors"
|
||||||
|
>
|
||||||
|
Configura Unsplash
|
||||||
|
</Link>
|
||||||
|
<span>per URL immagini reali nel CSV.</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Griglia post */}
|
{/* Griglia post */}
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{localResults.length === 0 ? (
|
{localResults.length === 0 ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user