feat: new home

This commit is contained in:
2025-12-04 10:33:00 +01:00
parent 48fd1d8816
commit 6f81419fb8
2 changed files with 158 additions and 139 deletions
+65 -27
View File
@@ -8,6 +8,7 @@ import { subBadges } from "../assets";
import BaseHeader from "../components/BaseHeader"; import BaseHeader from "../components/BaseHeader";
import CreditAmount from "../components/CreditAmount"; import CreditAmount from "../components/CreditAmount";
import ConnectBtn from "../components/ConnectBtn.js"; import ConnectBtn from "../components/ConnectBtn.js";
import GradientButton from "../components/GradientButton";
import CoinPackModal from "../components/modal/CoinPackModal"; import CoinPackModal from "../components/modal/CoinPackModal";
import NavigateHeader from "../components/NavigateHeader"; import NavigateHeader from "../components/NavigateHeader";
import ShareBtn from "../components/ShareBtn/ShareBtn"; import ShareBtn from "../components/ShareBtn/ShareBtn";
@@ -48,6 +49,8 @@ export default ({
blurIntensity = 0, blurIntensity = 0,
backgroundColor = "#000", backgroundColor = "#000",
showCoin = true, showCoin = true,
showReturnHome = false,
onReturnHome = null,
}) => { }) => {
const { currentUID = null, currentUserData = null } = useUserData?.() || {}; const { currentUID = null, currentUserData = null } = useUserData?.() || {};
@@ -66,6 +69,8 @@ export default ({
}, [currentUserData?.coins]); }, [currentUserData?.coins]);
const showCoinBadge = isWeb && !!currentUID && showCoin; const showCoinBadge = isWeb && !!currentUID && showCoin;
const showReturnHomeButton = isWeb && showReturnHome;
const coinBadgeContainerVisible = showCoinBadge || showReturnHomeButton;
const [isCoinModalVisible, setCoinModalVisible] = React.useState(false); const [isCoinModalVisible, setCoinModalVisible] = React.useState(false);
const subscriptionBadgeSource = React.useMemo(() => { const subscriptionBadgeSource = React.useMemo(() => {
@@ -100,7 +105,7 @@ export default ({
const nestedCandidates = nestedSubscription const nestedCandidates = nestedSubscription
? ["level", "plan", "pack", "type"].map((key) => ? ["level", "plan", "pack", "type"].map((key) =>
pickLevel(nestedSubscription?.[key]), pickLevel(nestedSubscription?.[key])
) )
: []; : [];
@@ -132,6 +137,14 @@ export default ({
setCoinModalVisible(false); setCoinModalVisible(false);
}, []); }, []);
const handleReturnHomePress = React.useCallback(() => {
if (typeof onReturnHome === "function") {
onReturnHome();
return;
}
navigate(Routes.LandingPage);
}, [onReturnHome]);
React.useEffect(() => { React.useEffect(() => {
if (!showCoinBadge && isCoinModalVisible) { if (!showCoinBadge && isCoinModalVisible) {
setCoinModalVisible(false); setCoinModalVisible(false);
@@ -170,15 +183,15 @@ export default ({
const resolvedContainerStyle = React.useMemo( const resolvedContainerStyle = React.useMemo(
() => StyleSheet.flatten(containerStyle) || {}, () => StyleSheet.flatten(containerStyle) || {},
[containerStyle], [containerStyle]
); );
const resolvedHeaderStyle = React.useMemo( const resolvedHeaderStyle = React.useMemo(
() => StyleSheet.flatten(headerStyle) || {}, () => StyleSheet.flatten(headerStyle) || {},
[headerStyle], [headerStyle]
); );
const resolvedContentContainerStyle = React.useMemo( const resolvedContentContainerStyle = React.useMemo(
() => StyleSheet.flatten(contentContainerStyle) || {}, () => StyleSheet.flatten(contentContainerStyle) || {},
[contentContainerStyle], [contentContainerStyle]
); );
return ( return (
@@ -207,32 +220,14 @@ export default ({
}} }}
/> />
) : null} ) : null}
{coinBadgeContainerVisible ? (
<View style={styles.coinBadgeContainer}>
{showCoinBadge ? ( {showCoinBadge ? (
<View <View style={styles.coinRow}>
style={{
position: "absolute",
top: gutters,
left: gutters,
flexDirection: "row",
alignItems: "center",
gap: 6,
zIndex: 20,
}}
>
<Pressable <Pressable
onPress={handleCoinPress} onPress={handleCoinPress}
accessibilityRole="button" accessibilityRole="button"
style={{ style={styles.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,
}}
> >
<CreditAmount <CreditAmount
value={coinBalance} value={coinBalance}
@@ -248,7 +243,7 @@ export default ({
<Pressable <Pressable
onPress={() => navigate(Routes.ManageSubscription)} onPress={() => navigate(Routes.ManageSubscription)}
accessibilityRole="button" accessibilityRole="button"
style={{ paddingVertical: 4 }} style={styles.subscriptionBadge}
> >
<Image <Image
source={subscriptionBadgeSource} source={subscriptionBadgeSource}
@@ -258,6 +253,15 @@ export default ({
) : null} ) : null}
</View> </View>
) : null} ) : null}
{showReturnHomeButton ? (
<GradientButton
title="retour à l'accueil"
onPress={handleReturnHomePress}
containerStyle={styles.returnHomeButton}
/>
) : null}
</View>
) : null}
<PageContainer <PageContainer
{...(containerType === "SAFE_AREA_VIEW" ? { edges: ["top"] } : {})} {...(containerType === "SAFE_AREA_VIEW" ? { edges: ["top"] } : {})}
style={{ style={{
@@ -328,3 +332,37 @@ export default ({
</View> </View>
); );
}; };
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",
},
});
+38 -57
View File
@@ -124,7 +124,7 @@ const Home = ({ navigation, route }) => {
const projects = useMemo( const projects = useMemo(
() => (Array.isArray(userProjects) ? userProjects : []), () => (Array.isArray(userProjects) ? userProjects : []),
[userProjects], [userProjects]
); );
const currentProject = useMemo(() => { const currentProject = useMemo(() => {
@@ -157,7 +157,7 @@ const Home = ({ navigation, route }) => {
const stageStates = useMemo( const stageStates = useMemo(
() => getCreationStageStates(currentProject), () => getCreationStageStates(currentProject),
[currentProject], [currentProject]
); );
const stageStatesByKey = useMemo(() => { const stageStatesByKey = useMemo(() => {
@@ -184,7 +184,7 @@ const Home = ({ navigation, route }) => {
if (!project?.id) return; if (!project?.id) return;
selectProject(project.id); selectProject(project.id);
}, },
[selectProject], [selectProject]
); );
const handleCloseMenu = useCallback(() => { 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); navigate(targetRoute, beatmakerStage?.params);
}, },
}, },
], ]
); );
navigation?.setParams?.({ showLyricsCongrats: false }); navigation?.setParams?.({ showLyricsCongrats: false });
}, [ }, [
@@ -330,7 +330,7 @@ const Home = ({ navigation, route }) => {
const songwriterAction = useMemo( const songwriterAction = useMemo(
() => getStageAction("songwriter", null), () => getStageAction("songwriter", null),
[], []
); );
const handleStartNew = useCallback(async () => { const handleStartNew = useCallback(async () => {
@@ -395,6 +395,10 @@ const Home = ({ navigation, route }) => {
setVideoUrl(isWeb ? videos?.landingWeb : videos?.landing); setVideoUrl(isWeb ? videos?.landingWeb : videos?.landing);
}, []); }, []);
const handleReturnToLanding = useCallback(() => {
navigate(Routes.LandingPage);
}, []);
const handleIntroVideoClose = useCallback(() => { const handleIntroVideoClose = useCallback(() => {
setVideoUrl(null); setVideoUrl(null);
markAdventureStarted(); markAdventureStarted();
@@ -412,7 +416,7 @@ const Home = ({ navigation, route }) => {
...card, ...card,
isLocked: stageStatesByKey[card.key]?.isLocked ?? true, isLocked: stageStatesByKey[card.key]?.isLocked ?? true,
})), })),
[stageStatesByKey], [stageStatesByKey]
); );
const [isCoinModalVisible, setCoinModalVisible] = useState(false); const [isCoinModalVisible, setCoinModalVisible] = useState(false);
@@ -437,7 +441,7 @@ const Home = ({ navigation, route }) => {
} }
navigate(action.route, action.params); navigate(action.route, action.params);
}, },
[currentProject, ensureProjectSelected, hasActiveProject, handleStartNew], [currentProject, ensureProjectSelected, hasActiveProject, handleStartNew]
); );
const handleClubPress = useCallback(() => { const handleClubPress = useCallback(() => {
@@ -456,10 +460,6 @@ const Home = ({ navigation, route }) => {
setCoinModalVisible(false); setCoinModalVisible(false);
}, []); }, []);
const handleNavigateToLanding = useCallback(() => {
navigate(Routes.LandingPage);
}, []);
const stageCardContainerStyle = isWeb ? styles.cardsGrid : styles.cardsStack; const stageCardContainerStyle = isWeb ? styles.cardsGrid : styles.cardsStack;
const stageCardItemStyle = isWeb const stageCardItemStyle = isWeb
? styles.webStageCard ? styles.webStageCard
@@ -518,22 +518,19 @@ const Home = ({ navigation, route }) => {
</View> </View>
) : null; ) : null;
const returnHomeButton = (
<GradientButton
title="retour à l'accueil"
onPress={handleReturnToLanding}
containerStyle={styles.returnButton}
/>
);
const topBar = ( const topBar = (
<View style={styles.topBar}> <View style={styles.topBar}>
<Pressable {/* {returnHomeButton} */}
onPress={handleNavigateToLanding}
accessibilityRole="button"
style={[
styles.returnLandingButton,
isWeb ? styles.returnLandingButtonWeb : null,
]}
>
<Text style={styles.returnLandingButtonText}>
Retour à l'accueil
</Text>
</Pressable>
<View style={styles.topBarContent}>
{mobileInfoRow} {mobileInfoRow}
{!isWeb ? returnHomeButton : null}
<ProjectDropDown <ProjectDropDown
ref={projectDropdownRef} ref={projectDropdownRef}
style={styles.projectDropDown} style={styles.projectDropDown}
@@ -546,7 +543,6 @@ const Home = ({ navigation, route }) => {
formatDate={formatDate} formatDate={formatDate}
/> />
</View> </View>
</View>
); );
const journeyContent = ( const journeyContent = (
@@ -592,9 +588,7 @@ const Home = ({ navigation, route }) => {
{stageCardsList} {stageCardsList}
<ClubCard <ClubCard onPress={handleClubPress} />
onPress={handleClubPress}
/>
</> </>
); );
@@ -611,6 +605,8 @@ const Home = ({ navigation, route }) => {
maxWidth={1600} maxWidth={1600}
width="100%" width="100%"
backgroundColor="#303438" backgroundColor="#303438"
showReturnHome={isWeb}
onReturnHome={handleReturnToLanding}
> >
<View style={styles.inner}> <View style={styles.inner}>
<ExpoImage <ExpoImage
@@ -619,10 +615,15 @@ const Home = ({ navigation, route }) => {
style={styles.centerImage} style={styles.centerImage}
/> />
{isWeb ? ( {isWeb ? (
<>
{/* <View style={styles.webReturnButtonWrapper}>
{returnHomeButton}
</View> */}
<View style={styles.contentOverlay}> <View style={styles.contentOverlay}>
{topBar} {topBar}
{journeyContent} {journeyContent}
</View> </View>
</>
) : ( ) : (
<View style={[styles.contentOverlay, styles.mobileContent]}> <View style={[styles.contentOverlay, styles.mobileContent]}>
{topBar} {topBar}
@@ -728,40 +729,20 @@ const styles = StyleSheet.create({
flexWrap: isWeb ? "wrap" : "nowrap", flexWrap: isWeb ? "wrap" : "nowrap",
alignItems: isWeb ? "center" : "stretch", alignItems: isWeb ? "center" : "stretch",
justifyContent: isWeb ? "center" : "flex-start", justifyContent: isWeb ? "center" : "flex-start",
gap: isWeb ? 0 : 12, gap: 12,
marginTop: isWeb ? 12 : 0, marginTop: isWeb ? 12 : 0,
marginBottom: isWeb ? 4 : 16, marginBottom: isWeb ? 4 : 16,
paddingHorizontal: isWeb ? 0 : gutters, paddingHorizontal: isWeb ? 0 : gutters,
zIndex: 10, zIndex: 10,
position: "relative",
}, },
returnLandingButton: { returnButton: {
paddingHorizontal: 14, width: isWeb ? 220 : "100%",
paddingVertical: 10, alignSelf: isWeb ? "flex-start" : "stretch",
borderRadius: 18, },
backgroundColor: "rgba(12, 14, 18, 0.72)", webReturnButtonWrapper: {
borderWidth: 1,
borderColor: "rgba(255, 255, 255, 0.1)",
alignSelf: "flex-start", alignSelf: "flex-start",
}, marginTop: gutters * 2.5,
returnLandingButtonWeb: { marginBottom: 8,
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,
}, },
projectDropDown: { projectDropDown: {
width: isWeb ? 420 : "100%", width: isWeb ? 420 : "100%",