diff --git a/src/components/FeatureCarousel/FeatureCarousel.js b/src/components/FeatureCarousel/FeatureCarousel.js index 1cce3be..fa9b2c6 100644 --- a/src/components/FeatureCarousel/FeatureCarousel.js +++ b/src/components/FeatureCarousel/FeatureCarousel.js @@ -62,13 +62,29 @@ const FeatureCarousel = ({ return getCreationStageStates(selectedProject); }, [stageStatesProp, selectedProject]); + const stageStatesByKey = useMemo(() => { + if (!Array.isArray(stageStates)) { + return {}; + } + return stageStates.reduce((acc, stage) => { + if (stage?.key) { + acc[stage.key] = stage; + } + return acc; + }, {}); + }, [stageStates]); + const carouselItems = useMemo( () => - STAGE_CARD_CONTENT.map((item, index) => ({ - ...item, - isLocked: stageStates[index]?.isLocked ?? true, - })), - [stageStates], + STAGE_CARD_CONTENT.map((item) => { + const state = stageStatesByKey[item.key]; + return { + ...item, + isLocked: state?.isLocked ?? true, + description: state?.description ?? item.description, + }; + }), + [stageStatesByKey], ); const { height: windowHeight } = useWindowDimensions(); diff --git a/src/utils/projectStages.js b/src/utils/projectStages.js index be8d917..eb0692f 100644 --- a/src/utils/projectStages.js +++ b/src/utils/projectStages.js @@ -13,19 +13,51 @@ const getLyricsCount = (project) => { return Array.isArray(lyrics) ? lyrics.length : 0; }; -const getStageLockState = (key, project) => { - const hasSong = !!project?.songUrl; - const hasCover = !!project?.coverUrl; - const hasPlayback = !!(project?.playbackUrl || project?.songUrl); +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 hasSong; + return hasSongUrl; case "beatmaker": - return !(lyricsCount > 0 && !hasSong); + return !(lyricsCount > 0 && !hasSongUrl); case "designer": - return !(hasSong && hasPlayback); + return !(hasSongUrl && hasPlayback); case "director": return !hasCover; default: @@ -33,12 +65,105 @@ const getStageLockState = (key, project) => { } }; -export const getCreationStageStates = (project) => - CREATION_STAGE_KEYS.map((key, index) => ({ - key, - index, - isLocked: getStageLockState(key, project), - })); +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; + } +}; + +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, + description: + isLocked && lockedDescription ? lockedDescription : description, + lockedDescription, + }; + }); +}; export const getStageAction = (key, project) => { switch (key) {