// Prodz — Production import (brief §1.4 + Roberto): "Crea → Produzione" opens a
// dedicated screen. Three entry methods converge on one metadata form:
// · Link Instagram — incolla il link, anteprima media, campi compilati da un
// modello AI (titolo, brand, categoria, prodotto da, credits).
// · Chrome extension — installi il plugin, apri un post IG, clicchi "Importa".
// · Caricamento manuale — gli stessi campi, compilati a mano.
// Poi una revisione di crew e credits → la produzione è importata.
const PROD_CATEGORIES = [
{ it: 'Editoriale moda', en: 'Fashion editorial' },
{ it: 'Commercial', en: 'Commercial' },
{ it: 'Video musicale', en: 'Music video' },
{ it: 'Documentario', en: 'Documentary' },
{ it: 'Cortometraggio', en: 'Short film' },
{ it: 'Architettura', en: 'Architecture' },
];
function ImportProduction() {
const { L } = useL();
const nav = useNav();
const { Button, Avatar } = window.ProdzDesignSystem_d0b87b;
const [step, setStep] = useStateS('method'); // method | instagram | extension | analyzing | form | review
const [method, setMethod] = useStateS(null);
const [link, setLink] = useStateS('');
// metadata
const [media, setMedia] = useStateS([]);
const [title, setTitle] = useStateS('');
const [brand, setBrand] = useStateS('');
const [category, setCategory] = useStateS('');
const [producedBy, setProducedBy] = useStateS('');
const [credits, setCredits] = useStateS([]);
const [ai, setAi] = useStateS(false);
const [picking, setPicking] = useStateS(false);
// Simulate an AI pass over the Instagram post → auto-fill everything.
const runAI = () => {
setStep('analyzing');
setTimeout(() => {
setMedia([IMG.fashion, IMG.av1, IMG.interior]);
setTitle('Collezione Aurora');
setBrand('Maison Vela');
setCategory(tr(L, PROD_CATEGORIES[0]));
setProducedBy('Studio Lumen');
setCredits([
{ id: 'sofia', role: tr(L, PEOPLE.sofia.role) },
{ id: 'elena', role: tr(L, PEOPLE.elena.role) },
{ id: 'nina', role: tr(L, PEOPLE.nina.role) },
]);
setAi(true);
setStep('form');
}, 1600);
};
const startManual = () => {
setMethod('manual'); setMedia([]); setAi(false);
setCredits([{ id: 'me', role: tr(L, PEOPLE.me.role) }]);
setStep('form');
};
const back = () => {
if (step === 'method') return nav.pop();
if (step === 'instagram' || step === 'extension') return setStep('method');
if (step === 'form') return setStep(method === 'manual' ? 'method' : method);
if (step === 'review') return setStep('form');
return nav.pop();
};
const setRole = (id, role) => setCredits((cs) => cs.map((c) => c.id === id ? { ...c, role } : c));
const removeCredit = (id) => setCredits((cs) => cs.filter((c) => c.id !== id));
const addCredit = (id) => { setCredits((cs) => [...cs, { id, role: tr(L, PEOPLE[id].role) }]); setPicking(false); };
const available = Object.keys(PEOPLE).filter((id) => !credits.some((c) => c.id === id));
const finishImport = () => {
nav.pop();
nav.toast(L('Produzione importata · ora è nel tuo profilo', 'Production imported · now on your profile'), null);
};
const headerTitle = L('Importa produzione', 'Import production');
return (
{/* progress dots — once you're past the method chooser */}
{step !== 'method' && (
{['source', 'form', 'review'].map((s, i) => {
const reached = (step === 'review' ? 2 : step === 'form' ? 1 : 0) >= i;
return ;
})}
)}
{/* ───────── METHOD CHOOSER ───────── */}
{step === 'method' && (
{L('Come vuoi importare?', 'How do you want to import?')}
{L('Porta un progetto su Prodz: genereremo Moments e Thread collegati.', 'Bring a project onto Prodz — we’ll create linked Moments & Threads.')}
{ setMethod('instagram'); setStep('instagram'); }} />
{ setMethod('extension'); setStep('extension'); }} />
)}
{/* ───────── INSTAGRAM LINK ───────── */}
{step === 'instagram' && (
)}
{/* ───────── CHROME EXTENSION ───────── */}
{step === 'extension' && (
setStep('method')} L={L} />
} onClick={() => nav.toast(L('Apertura Chrome Web Store…', 'Opening Chrome Web Store…'), null)}>{L('Installa', 'Install')}
} onClick={runAI}>{L('Simula importazione', 'Simulate import')}
)}
{/* ───────── ANALYZING ───────── */}
{step === 'analyzing' && (
{L('Analisi del post con l’AI…', 'Analyzing the post with AI…')}
{L('Leggo media, titolo, brand e i credits.', 'Reading media, title, brand and credits.')}
)}
{/* ───────── FORM ───────── */}
{step === 'form' && (
{ai && (
{L('Campi precompilati dall’AI. Controlla e modifica quello che serve.', 'Fields pre-filled by AI. Review and edit anything you need.')}
)}
{/* media preview / upload */}
0} L={L}>
{media.length > 0 ? (
{media.map((src, i) => (
))}
nav.toast(L('Aggiungi media', 'Add media'), null)} style={uploadSlot} aria-label={L('Aggiungi', 'Add')}>
) : (
nav.toast(L('Apertura caricamento…', 'Opening upload…'), null)} style={{ ...uploadSlot, width: '100%', height: 150, flexDirection: 'column', gap: 8 }}>
{L('Carica foto e video del progetto', 'Upload project photos & videos')}
)}
setTitle(e.target.value)} placeholder={L('Nome della produzione…', 'Production name…')} style={impInput} />
setBrand(e.target.value)} placeholder={L('es. Maison Vela', 'e.g. Maison Vela')} style={impInput} />
{PROD_CATEGORIES.map((c) => {
const v = tr(L, c); const on = category === v;
return setCategory(v)} style={chipStyle(on)}>{v} ;
})}
setProducedBy(e.target.value)} placeholder={L('Casa di produzione o persona…', 'Production house or person…')} style={impInput} />
{/* credits */}
0} L={L}>
{credits.map((c) => {
const p = PEOPLE[c.id]; if (!p) return null;
const roleOpts = ROLES.map((r) => tr(L, r));
if (!roleOpts.includes(c.role)) roleOpts.unshift(c.role);
return (
{p.name}{c.id === 'me' && L(' · Tu', ' · You')}
setRole(c.id, e.target.value)} style={impSelect}>
{roleOpts.map((r) => {r} )}
removeCredit(c.id)} aria-label={L('Rimuovi', 'Remove')} style={iconGhostBtn}>
);
})}
{picking ? (
{available.length === 0 &&
{L('Tutti aggiunti.', 'Everyone added.')} }
{available.map((id) => {
const p = PEOPLE[id];
return (
addCredit(id)} style={{ display: 'flex', alignItems: 'center', gap: 7, padding: '5px 11px 5px 5px', border: 'none', cursor: 'pointer', borderRadius: 'var(--radius-pill)', background: 'var(--surface-raised)', boxShadow: 'var(--ring-inset-hairline)' }}>
{p.name.split(' ')[0]}
);
})}
) : (
setPicking(true)} style={addCreditBtn}>
{L('Aggiungi credit', 'Add credit')}
)}
} onClick={() => setStep('review')}>{L('Rivedi crew e credits', 'Review crew & credits')}
)}
{/* ───────── REVIEW ───────── */}
{step === 'review' && (
{L('Revisione crew & credits', 'Review crew & credits')}
{L('Conferma chi ha collaborato e i ruoli, poi importa.', 'Confirm who collaborated and their roles, then import.')}
{/* summary card */}
{!media[0] && }
{title || L('Senza titolo', 'Untitled')}
{[brand, category].filter(Boolean).join(' · ') || '—'}
{producedBy &&
{L('Prodotto da', 'Produced by')} {producedBy}
}
{credits.length} {L('credits', 'credits')}
{credits.map((c) => {
const p = PEOPLE[c.id]; if (!p) return null;
return (
{p.name}{c.id === 'me' && L(' · Tu', ' · You')}
{c.role}
);
})}
} onClick={() => setStep('form')}>{L('Indietro', 'Back')}
} onClick={finishImport}>{L('Importa produzione', 'Import production')}
)}
);
}
function ExtStep({ n, icon, text, L }) {
return (
{n}
{text}
);
}
function IField({ label, ai, L, children, style }) {
return (
{label}
{ai && (
AI
)}
{children}
);
}
const chipStyle = (on) => ({
height: 36, padding: '0 14px', borderRadius: 'var(--radius-pill)', border: 'none', cursor: 'pointer',
fontSize: 12.5, fontWeight: 700, whiteSpace: 'nowrap',
background: on ? 'var(--teal-surface)' : 'var(--surface-raised)',
color: on ? 'var(--prodz-teal)' : 'var(--text-muted)',
boxShadow: on ? 'var(--ring-teal)' : 'var(--ring-inset-hairline)',
});
const impInput = { width: '100%', height: 46, padding: '0 14px', borderRadius: 'var(--radius-md)', border: 'none', outline: 'none', background: 'var(--surface-raised)', boxShadow: 'var(--ring-inset-hairline)', color: 'var(--text-body)', fontSize: 15, fontFamily: 'var(--font-ui)' };
const impSelect = { marginTop: 3, height: 30, padding: '0 8px', borderRadius: 8, border: 'none', outline: 'none', background: 'var(--surface-canvas)', boxShadow: 'var(--ring-inset-hairline)', color: 'var(--text-muted)', fontSize: 12.5, fontWeight: 600, fontFamily: 'var(--font-ui)', maxWidth: '100%' };
const impNote = { display: 'flex', alignItems: 'flex-start', gap: 9, padding: '12px 14px', borderRadius: 'var(--radius-md)', background: 'var(--surface-card)', boxShadow: 'var(--ring-inset-hairline)', fontSize: 12.5, lineHeight: 1.45, color: 'var(--text-muted)' };
const creditRow = { display: 'flex', alignItems: 'center', gap: 11, padding: 10, background: 'var(--surface-card)', borderRadius: 'var(--radius-md)', boxShadow: 'var(--ring-inset-hairline)' };
const iconGhostBtn = { width: 30, height: 30, flexShrink: 0, borderRadius: '50%', border: 'none', cursor: 'pointer', background: 'var(--surface-raised)', display: 'flex', alignItems: 'center', justifyContent: 'center' };
const uploadSlot = { width: 96, height: 168, flexShrink: 0, borderRadius: 14, border: '1.5px dashed var(--hairline-strong)', background: 'var(--surface-raised)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', scrollSnapAlign: 'start' };
const addCreditBtn = { display: 'inline-flex', alignItems: 'center', gap: 8, alignSelf: 'flex-start', height: 40, padding: '0 16px', borderRadius: 'var(--radius-pill)', border: '1.5px dashed var(--hairline-strong)', background: 'none', cursor: 'pointer', fontSize: 13, fontWeight: 700, color: 'var(--prodz-teal)', marginTop: 2 };
Object.assign(window, { ImportProduction, PROD_CATEGORIES });