diff --git a/frontend/src/components/ContentArchive.jsx b/frontend/src/components/ContentArchive.jsx index a503cbc..b89eb79 100644 --- a/frontend/src/components/ContentArchive.jsx +++ b/frontend/src/components/ContentArchive.jsx @@ -1,25 +1,13 @@ import { useState, useEffect } from 'react' +import { Link } from 'react-router-dom' import { api } from '../api' -const statusLabels = { - draft: 'Bozza', - approved: 'Approvato', - scheduled: 'Schedulato', - published: 'Pubblicato', -} - +const statusLabels = { draft: 'Bozza', approved: 'Approvato', scheduled: 'Schedulato', published: 'Pubblicato' } const statusColors = { - draft: 'bg-amber-50 text-amber-600', - approved: 'bg-emerald-50 text-emerald-600', - scheduled: 'bg-blue-50 text-blue-600', - published: 'bg-violet-50 text-violet-600', -} - -const platformLabels = { - instagram: 'Instagram', - facebook: 'Facebook', - youtube: 'YouTube', - tiktok: 'TikTok', + draft: { bg: '#FFFBEB', color: '#B45309' }, + approved: { bg: 'var(--success-light)', color: 'var(--success)' }, + scheduled: { bg: '#EFF6FF', color: '#1D4ED8' }, + published: { bg: '#F5F3FF', color: '#6D28D9' }, } export default function ContentArchive() { @@ -27,12 +15,12 @@ export default function ContentArchive() { const [characters, setCharacters] = useState([]) const [loading, setLoading] = useState(true) const [expandedId, setExpandedId] = useState(null) + const [editingId, setEditingId] = useState(null) + const [editText, setEditText] = useState('') const [filterCharacter, setFilterCharacter] = useState('') const [filterStatus, setFilterStatus] = useState('') - useEffect(() => { - loadData() - }, []) + useEffect(() => { loadData() }, []) const loadData = async () => { setLoading(true) @@ -43,185 +31,177 @@ export default function ContentArchive() { ]) setPosts(postsData) setCharacters(charsData) - } catch { - // silent - } finally { - setLoading(false) - } + } catch { /* silent */ } finally { setLoading(false) } } - const getCharacterName = (id) => { - const c = characters.find((ch) => ch.id === id) - return c ? c.name : '—' - } + const getCharacterName = (id) => characters.find(c => c.id === id)?.name || '—' const handleApprove = async (postId) => { - try { - await api.post(`/content/posts/${postId}/approve`) - loadData() - } catch { - // silent - } + try { await api.post(`/content/posts/${postId}/approve`); loadData() } catch {} } - const handleDelete = async (postId) => { if (!confirm('Eliminare questo contenuto?')) return + try { await api.delete(`/content/posts/${postId}`); loadData() } catch {} + } + const handleSaveEdit = async (postId) => { try { - await api.delete(`/content/posts/${postId}`) + await api.put(`/content/posts/${postId}`, { text_content: editText }) + setEditingId(null) loadData() - } catch { - // silent - } + } catch {} } - const filtered = posts.filter((p) => { + const filtered = posts.filter(p => { if (filterCharacter && String(p.character_id) !== filterCharacter) return false if (filterStatus && p.status !== filterStatus) return false return true }) - const formatDate = (dateStr) => { - if (!dateStr) return '—' - const d = new Date(dateStr) - return d.toLocaleDateString('it-IT', { day: '2-digit', month: 'short', year: 'numeric' }) - } + const formatDate = (d) => d ? new Date(d).toLocaleDateString('it-IT', { day: '2-digit', month: 'short', year: 'numeric' }) : '—' return ( -
-
+
+
-

Archivio Contenuti

-

- Tutti i contenuti generati -

+ Archivio +
+

+ Archivio Contenuti +

+

Tutti i contenuti generati

+ + ← Genera nuovo +
{/* Filters */} -
- setFilterCharacter(e.target.value)} style={selectStyle}> - {characters.map((c) => ( - - ))} + {characters.map(c => )} - - setFilterStatus(e.target.value)} style={selectStyle}> - {Object.entries(statusLabels).map(([val, label]) => ( - - ))} + {Object.entries(statusLabels).map(([val, label]) => )} - - + {filtered.length} contenut{filtered.length === 1 ? 'o' : 'i'}
{loading ? ( -
-
+
+
) : filtered.length === 0 ? ( -
-

-

Nessun contenuto trovato

-

- {posts.length === 0 - ? 'Genera il tuo primo contenuto dalla pagina Contenuti' - : 'Prova a cambiare i filtri'} +

+
+

Nessun contenuto trovato

+

+ {posts.length === 0 ? 'Genera il tuo primo contenuto dalla pagina Contenuti' : 'Prova a cambiare i filtri'}

) : ( -
- {filtered.map((post) => ( -
setExpandedId(expandedId === post.id ? null : post.id)} - > -
- {/* Header */} -
- - {statusLabels[post.status] || post.status} - - - {platformLabels[post.platform] || post.platform} - -
- - {/* Character name */} -

- {getCharacterName(post.character_id)} -

- - {/* Text preview */} -

- {post.text} -

- - {/* Expanded details */} - {expandedId === post.id && ( -
- {post.hashtags && post.hashtags.length > 0 && ( -
- {post.hashtags.map((tag, i) => ( - - #{tag} - - ))} -
- )} -
- )} - - {/* Footer */} -
- - {formatDate(post.created_at)} - -
- {post.hashtags && ( - - {post.hashtags.length} hashtag +
+ {filtered.map(post => { + const sc = statusColors[post.status] || statusColors.draft + const isExpanded = expandedId === post.id + const isEditing = editingId === post.id + return ( +
{ if (!isEditing) setExpandedId(isExpanded ? null : post.id) }}> +
+ {/* Header */} +
+ + {statusLabels[post.status] || post.status} + + {post.platform_hint && ( + + {post.platform_hint} )}
-
- {/* Actions */} -
e.stopPropagation()} - > - {post.status === 'draft' && ( - +

+ {getCharacterName(post.character_id)} +

+ + {/* Text content */} + {isEditing ? ( +
e.stopPropagation()}> +