diff --git a/frontend/src/pages/OutputReview.tsx b/frontend/src/pages/OutputReview.tsx index ac5a548..5e8b656 100644 --- a/frontend/src/pages/OutputReview.tsx +++ b/frontend/src/pages/OutputReview.tsx @@ -10,7 +10,7 @@ * e inviato al backend via POST al momento del download CSV. */ -import { Download, Loader2 } from 'lucide-react' +import { Download, Loader2, RefreshCw } from 'lucide-react' import { useEffect, useState } from 'react' import { useParams } from 'react-router-dom' import { useDownloadEditedCsv, useJobResults } from '../api/hooks' @@ -24,6 +24,8 @@ export function OutputReview() { // Stato locale dei post — viene aggiornato da edit inline e rigenerazione const [localResults, setLocalResults] = useState([]) + // Set di indici dei post che sono stati rigenerati + const [regeneratedSlots, setRegeneratedSlots] = useState>(new Set()) // Inizializza i risultati e merge con CalendarSlot dal calendario useEffect(() => { @@ -47,6 +49,7 @@ export function OutputReview() { setLocalResults((prev) => prev.map((r) => (r.slot_index === updated.slot_index ? updated : r)) ) + setRegeneratedSlots((prev) => new Set(prev).add(updated.slot_index)) } async function handleDownloadCsv() { @@ -82,6 +85,15 @@ export function OutputReview() { const successCount = localResults.filter((r) => r.status === 'success').length const failedCount = localResults.filter((r) => r.status === 'failed').length + const regeneratedCount = regeneratedSlots.size + // Conteggio post modificati manualmente (diversi dall'originale, esclusi i rigenerati) + const editedCount = localResults.filter((r) => { + if (r.status !== 'success' || !r.post) return false + const original = jobData?.results?.find((o) => o.slot_index === r.slot_index) + if (!original?.post) return false + return JSON.stringify(r.post) !== JSON.stringify(original.post) + }).length + const manuallyEditedCount = Math.max(0, editedCount - regeneratedCount) // --------------------------------------------------------------------------- // UI principale @@ -94,11 +106,23 @@ export function OutputReview() {

Output Review

{jobData.campagna}

-
+
+ {localResults.length} post {successCount} generati {failedCount > 0 && ( {failedCount} falliti )} + {regeneratedCount > 0 && ( + + + {regeneratedCount} rigenerati + + )} + {manuallyEditedCount > 0 && ( + + {manuallyEditedCount} modificati + + )} job: {jobId}
@@ -127,7 +151,9 @@ export function OutputReview() { {/* Info edit inline */}
- Clicca su una card per espandere le slide. I campi di testo sono editabili inline — le modifiche saranno incluse nel CSV scaricato. + Clicca su una card per espandere le slide. I campi di testo sono editabili inline. + Usa il pulsante per rigenerare singoli post con topic diversi. + Le modifiche saranno incluse nel CSV scaricato.
{/* Griglia post */} @@ -146,6 +172,7 @@ export function OutputReview() { tono={null} onRegenerated={handleRegenerated} onEdit={handleEdit} + isRegenerated={regeneratedSlots.has(result.slot_index)} /> )) )}