import { Routes } from "../navigation/Routes"; export const CREATION_STAGE_KEYS = [ "songwriter", "beatmaker", "designer", "director", ]; const getLyricsCount = (project) => { if (!project) return 0; const { lyrics } = project; return Array.isArray(lyrics) ? lyrics.length : 0; }; const getStageMetadata = (project) => { const lyricsCount = getLyricsCount(project); const hasLyrics = !!(project?.hasLyrics || lyricsCount > 0); const hasSongUrl = !!project?.songUrl; const hasCover = !!project?.coverUrl; const hasPlaybackAsset = !!project?.playbackUrl; const hasPlayback = hasPlaybackAsset || hasSongUrl; const musicUrls = Array.isArray(project?.musicUrls) ? project.musicUrls.filter(Boolean) : []; const musicStatus = project?.musicStatus || null; const coverStatus = project?.coverStatus || null; const playbackStatus = project?.playbackStatus || null; const isPlaybackGenerating = project?.playbackGenerating === true || project?.isPlaybackGenerating === true || playbackStatus === "GENERATING"; return { lyricsCount, hasLyrics, hasSongUrl, hasCover, hasPlayback, hasPlaybackAsset, hasMusicDraft: musicUrls.length > 0, musicStatus, coverStatus, playbackStatus, isMusicGenerating: musicStatus === "GENERATING", isCoverGenerating: coverStatus === "GENERATING", isPlaybackGenerating, }; }; const getStageLockState = (key, metadata) => { const { hasSongUrl, hasCover, hasPlayback, lyricsCount } = metadata; switch (key) { case "songwriter": return hasSongUrl; case "beatmaker": return !(lyricsCount > 0 && !hasSongUrl); case "designer": return !(hasSongUrl && hasPlayback); case "director": return !hasCover; default: return true; } }; const getStageDescription = (key, metadata) => { const { hasLyrics, hasSongUrl, hasCover, hasPlaybackAsset, hasMusicDraft, isMusicGenerating, isCoverGenerating, isPlaybackGenerating, } = metadata; switch (key) { case "songwriter": if (!hasLyrics) { return "Commencer à créer des paroles pour votre chanson"; } if (!hasSongUrl) { return "Continuer la création de paroles"; } return "Modifier les paroles créées"; case "beatmaker": if (!hasLyrics) { return "Écrivez vos paroles pour débloquer la musique"; } if (isMusicGenerating) { return "Votre morceau est en cours de création"; } if (hasSongUrl || hasMusicDraft) { return "Modifier la production musicale"; } return "Commencer la création de votre morceau"; case "designer": if (!hasSongUrl) { return "Générez votre morceau avant de créer la cover"; } if (isCoverGenerating) { return "Votre cover est en cours de génération"; } if (hasCover) { return "Modifier la cover générée"; } return "Commencer la création de votre cover"; case "director": if (!hasCover) { return "Générez une cover pour débloquer le playback"; } if (isPlaybackGenerating) { return "Votre playback est en cours de préparation"; } if (hasPlaybackAsset) { return "Modifier le playback généré"; } return "Commencer la création de votre playback"; default: return ""; } }; const getStageLockedDescription = (key, metadata) => { switch (key) { case "songwriter": return metadata.hasSongUrl ? "Impossible de modifier les paroles" : undefined; case "beatmaker": return metadata.hasSongUrl ? "Impossible de modifier la production musicale" : undefined; case "designer": return metadata.hasCover ? "Impossible de modifier la cover" : undefined; case "director": return metadata.hasPlaybackAsset ? "Impossible de modifier le playback" : undefined; default: return undefined; } }; const getStageCompletionState = (key, metadata) => { switch (key) { case "songwriter": return metadata.hasLyrics; case "beatmaker": return metadata.hasSongUrl || metadata.musicStatus === "GENERATED"; case "designer": return metadata.hasCover; case "director": return metadata.hasPlaybackAsset; default: return false; } }; export const getCreationStageStates = (project) => { const metadata = getStageMetadata(project); return CREATION_STAGE_KEYS.map((key, index) => { const isLocked = getStageLockState(key, metadata); const description = getStageDescription(key, metadata); const lockedDescription = getStageLockedDescription(key, metadata); return { key, index, isLocked, isCompleted: getStageCompletionState(key, metadata), description: isLocked && lockedDescription ? lockedDescription : description, lockedDescription, }; }); }; export const getStageAction = (key, project) => { switch (key) { case "songwriter": return { route: getLyricsCount(project) > 0 ? Routes.Lyrics : Routes.WritingLyrics, }; case "beatmaker": if (project?.musicStatus === "GENERATING") { return { route: Routes.GeneratingSong }; } if (project?.musicStatus === "GENERATED") { return { route: Routes.SongReady }; } return { route: Routes.Compose }; case "designer": return { route: project?.coverUrl ? Routes.ValidateCover : Routes.ChooseCoverType, }; case "director": return { route: Routes.Playback, params: project ? { project } : undefined, }; default: return {}; } }; export const findFirstUnlockedStageIndex = (project) => { const stages = getCreationStageStates(project); if (!stages.length) { return 0; } const actionableIndex = stages.findIndex( (stage) => !stage.isCompleted && !stage.isLocked ); if (actionableIndex !== -1) { return actionableIndex; } const firstIncomplete = stages.findIndex((stage) => !stage.isCompleted); if (firstIncomplete !== -1) { return firstIncomplete; } const firstUnlocked = stages.findIndex((stage) => !stage.isLocked); if (firstUnlocked !== -1) { return firstUnlocked; } return stages.length - 1; };