From 6f81419fb8556dc21378802821bfb33690b8ebc6 Mon Sep 17 00:00:00 2001 From: leon-morival Date: Thu, 4 Dec 2025 10:33:00 +0100 Subject: [PATCH] feat: new home --- src/layouts/Page.js | 170 ++++++++++++++++++++++++--------------- src/screens/Home/Home.js | 127 +++++++++++++---------------- 2 files changed, 158 insertions(+), 139 deletions(-) diff --git a/src/layouts/Page.js b/src/layouts/Page.js index a844602..a45898c 100644 --- a/src/layouts/Page.js +++ b/src/layouts/Page.js @@ -8,6 +8,7 @@ import { subBadges } from "../assets"; import BaseHeader from "../components/BaseHeader"; import CreditAmount from "../components/CreditAmount"; import ConnectBtn from "../components/ConnectBtn.js"; +import GradientButton from "../components/GradientButton"; import CoinPackModal from "../components/modal/CoinPackModal"; import NavigateHeader from "../components/NavigateHeader"; import ShareBtn from "../components/ShareBtn/ShareBtn"; @@ -48,6 +49,8 @@ export default ({ blurIntensity = 0, backgroundColor = "#000", showCoin = true, + showReturnHome = false, + onReturnHome = null, }) => { const { currentUID = null, currentUserData = null } = useUserData?.() || {}; @@ -66,6 +69,8 @@ export default ({ }, [currentUserData?.coins]); const showCoinBadge = isWeb && !!currentUID && showCoin; + const showReturnHomeButton = isWeb && showReturnHome; + const coinBadgeContainerVisible = showCoinBadge || showReturnHomeButton; const [isCoinModalVisible, setCoinModalVisible] = React.useState(false); const subscriptionBadgeSource = React.useMemo(() => { @@ -80,14 +85,14 @@ export default ({ const nestedSubscription = currentUserData?.subscription && - typeof currentUserData.subscription === "object" + typeof currentUserData.subscription === "object" ? currentUserData.subscription : null; const stripeMetadata = currentUserData?.stripeSubscription && - typeof currentUserData.stripeSubscription === "object" && - typeof currentUserData.stripeSubscription.metadata === "object" + typeof currentUserData.stripeSubscription === "object" && + typeof currentUserData.stripeSubscription.metadata === "object" ? currentUserData.stripeSubscription.metadata : null; @@ -100,18 +105,18 @@ export default ({ const nestedCandidates = nestedSubscription ? ["level", "plan", "pack", "type"].map((key) => - pickLevel(nestedSubscription?.[key]), - ) + pickLevel(nestedSubscription?.[key]) + ) : []; const metadataCandidates = stripeMetadata ? [ - "level", - "subscriptionLevel", - "subscription_level", - "pack", - "Pack", - ].map((key) => pickLevel(stripeMetadata?.[key])) + "level", + "subscriptionLevel", + "subscription_level", + "pack", + "Pack", + ].map((key) => pickLevel(stripeMetadata?.[key])) : []; const resolvedLevel = [ @@ -132,6 +137,14 @@ export default ({ setCoinModalVisible(false); }, []); + const handleReturnHomePress = React.useCallback(() => { + if (typeof onReturnHome === "function") { + onReturnHome(); + return; + } + navigate(Routes.LandingPage); + }, [onReturnHome]); + React.useEffect(() => { if (!showCoinBadge && isCoinModalVisible) { setCoinModalVisible(false); @@ -170,15 +183,15 @@ export default ({ const resolvedContainerStyle = React.useMemo( () => StyleSheet.flatten(containerStyle) || {}, - [containerStyle], + [containerStyle] ); const resolvedHeaderStyle = React.useMemo( () => StyleSheet.flatten(headerStyle) || {}, - [headerStyle], + [headerStyle] ); const resolvedContentContainerStyle = React.useMemo( () => StyleSheet.flatten(contentContainerStyle) || {}, - [contentContainerStyle], + [contentContainerStyle] ); return ( @@ -207,54 +220,45 @@ export default ({ }} /> ) : null} - {showCoinBadge ? ( - - - + {showCoinBadge ? ( + + + + + {subscriptionBadgeSource ? ( + navigate(Routes.ManageSubscription)} + accessibilityRole="button" + style={styles.subscriptionBadge} + > + + + ) : null} + + ) : null} + {showReturnHomeButton ? ( + - - {subscriptionBadgeSource ? ( - navigate(Routes.ManageSubscription)} - accessibilityRole="button" - style={{ paddingVertical: 4 }} - > - - ) : null} ) : null} @@ -293,11 +297,11 @@ export default ({ style={{ flex: 1, ...resolvedContentContainerStyle }} {...(scrollEnabled ? { - scrollEventThrottle: 80, - showsVerticalScrollIndicator: false, - contentContainerStyle: { paddingBottom: responsiveHeight(55) }, - keyboardDismissMode: "on-drag", - } + scrollEventThrottle: 80, + showsVerticalScrollIndicator: false, + contentContainerStyle: { paddingBottom: responsiveHeight(55) }, + keyboardDismissMode: "on-drag", + } : {})} > {children} @@ -328,3 +332,37 @@ export default ({ ); }; + +const styles = StyleSheet.create({ + coinBadgeContainer: { + position: "absolute", + top: gutters, + left: gutters, + alignItems: "flex-start", + gap: 10, + zIndex: 20, + }, + coinRow: { + flexDirection: "row", + alignItems: "center", + gap: 6, + }, + coinButton: { + paddingHorizontal: 14, + paddingVertical: 8, + borderRadius: 20, + backgroundColor: "rgba(12, 14, 18, 0.72)", + borderWidth: 1, + borderColor: "rgba(255, 255, 255, 0.1)", + flexDirection: "row", + alignItems: "center", + gap: 8, + }, + subscriptionBadge: { + paddingVertical: 4, + }, + returnHomeButton: { + width: 220, + alignSelf: "flex-start", + }, +}); diff --git a/src/screens/Home/Home.js b/src/screens/Home/Home.js index a0d61a1..77d7073 100644 --- a/src/screens/Home/Home.js +++ b/src/screens/Home/Home.js @@ -124,7 +124,7 @@ const Home = ({ navigation, route }) => { const projects = useMemo( () => (Array.isArray(userProjects) ? userProjects : []), - [userProjects], + [userProjects] ); const currentProject = useMemo(() => { @@ -157,7 +157,7 @@ const Home = ({ navigation, route }) => { const stageStates = useMemo( () => getCreationStageStates(currentProject), - [currentProject], + [currentProject] ); const stageStatesByKey = useMemo(() => { @@ -184,7 +184,7 @@ const Home = ({ navigation, route }) => { if (!project?.id) return; selectProject(project.id); }, - [selectProject], + [selectProject] ); const handleCloseMenu = useCallback(() => { @@ -271,7 +271,7 @@ const Home = ({ navigation, route }) => { }, }, ], - { cancelable: true }, + { cancelable: true } ), }); @@ -306,7 +306,7 @@ const Home = ({ navigation, route }) => { navigate(targetRoute, beatmakerStage?.params); }, }, - ], + ] ); navigation?.setParams?.({ showLyricsCongrats: false }); }, [ @@ -330,7 +330,7 @@ const Home = ({ navigation, route }) => { const songwriterAction = useMemo( () => getStageAction("songwriter", null), - [], + [] ); const handleStartNew = useCallback(async () => { @@ -395,6 +395,10 @@ const Home = ({ navigation, route }) => { setVideoUrl(isWeb ? videos?.landingWeb : videos?.landing); }, []); + const handleReturnToLanding = useCallback(() => { + navigate(Routes.LandingPage); + }, []); + const handleIntroVideoClose = useCallback(() => { setVideoUrl(null); markAdventureStarted(); @@ -412,7 +416,7 @@ const Home = ({ navigation, route }) => { ...card, isLocked: stageStatesByKey[card.key]?.isLocked ?? true, })), - [stageStatesByKey], + [stageStatesByKey] ); const [isCoinModalVisible, setCoinModalVisible] = useState(false); @@ -437,7 +441,7 @@ const Home = ({ navigation, route }) => { } navigate(action.route, action.params); }, - [currentProject, ensureProjectSelected, hasActiveProject, handleStartNew], + [currentProject, ensureProjectSelected, hasActiveProject, handleStartNew] ); const handleClubPress = useCallback(() => { @@ -456,10 +460,6 @@ const Home = ({ navigation, route }) => { setCoinModalVisible(false); }, []); - const handleNavigateToLanding = useCallback(() => { - navigate(Routes.LandingPage); - }, []); - const stageCardContainerStyle = isWeb ? styles.cardsGrid : styles.cardsStack; const stageCardItemStyle = isWeb ? styles.webStageCard @@ -518,34 +518,30 @@ const Home = ({ navigation, route }) => { ) : null; + const returnHomeButton = ( + + ); + const topBar = ( - - - Retour à l'accueil - - - - {mobileInfoRow} - - + {/* {returnHomeButton} */} + {mobileInfoRow} + {!isWeb ? returnHomeButton : null} + ); @@ -592,9 +588,7 @@ const Home = ({ navigation, route }) => { {stageCardsList} - + ); @@ -611,6 +605,8 @@ const Home = ({ navigation, route }) => { maxWidth={1600} width="100%" backgroundColor="#303438" + showReturnHome={isWeb} + onReturnHome={handleReturnToLanding} > { style={styles.centerImage} /> {isWeb ? ( - - {topBar} - {journeyContent} - + <> + {/* + {returnHomeButton} + */} + + {topBar} + {journeyContent} + + ) : ( {topBar} @@ -728,40 +729,20 @@ const styles = StyleSheet.create({ flexWrap: isWeb ? "wrap" : "nowrap", alignItems: isWeb ? "center" : "stretch", justifyContent: isWeb ? "center" : "flex-start", - gap: isWeb ? 0 : 12, + gap: 12, marginTop: isWeb ? 12 : 0, marginBottom: isWeb ? 4 : 16, paddingHorizontal: isWeb ? 0 : gutters, zIndex: 10, - position: "relative", }, - returnLandingButton: { - paddingHorizontal: 14, - paddingVertical: 10, - borderRadius: 18, - backgroundColor: "rgba(12, 14, 18, 0.72)", - borderWidth: 1, - borderColor: "rgba(255, 255, 255, 0.1)", + returnButton: { + width: isWeb ? 220 : "100%", + alignSelf: isWeb ? "flex-start" : "stretch", + }, + webReturnButtonWrapper: { alignSelf: "flex-start", - }, - returnLandingButtonWeb: { - position: "absolute", - left: 0, - top: 0, - transform: [{ translateY: -2 }], - }, - returnLandingButtonText: { - fontSize: 14, - color: Palette.white, - fontFamily: FONT_FAMILY.InterSemiBold, - }, - topBarContent: { - flex: 1, - width: "100%", - flexDirection: isWeb ? "row" : "column", - alignItems: isWeb ? "center" : "stretch", - justifyContent: isWeb ? "center" : "flex-start", - gap: 12, + marginTop: gutters * 2.5, + marginBottom: 8, }, projectDropDown: { width: isWeb ? 420 : "100%",