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 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(() => {
@@ -100,7 +105,7 @@ export default ({
const nestedCandidates = nestedSubscription
? ["level", "plan", "pack", "type"].map((key) =>
pickLevel(nestedSubscription?.[key]),
pickLevel(nestedSubscription?.[key])
)
: [];
@@ -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,32 +220,14 @@ export default ({
}}
/>
) : null}
{coinBadgeContainerVisible ? (
<View style={styles.coinBadgeContainer}>
{showCoinBadge ? (
<View
style={{
position: "absolute",
top: gutters,
left: gutters,
flexDirection: "row",
alignItems: "center",
gap: 6,
zIndex: 20,
}}
>
<View style={styles.coinRow}>
<Pressable
onPress={handleCoinPress}
accessibilityRole="button"
style={{
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,
}}
style={styles.coinButton}
>
<CreditAmount
value={coinBalance}
@@ -248,7 +243,7 @@ export default ({
<Pressable
onPress={() => navigate(Routes.ManageSubscription)}
accessibilityRole="button"
style={{ paddingVertical: 4 }}
style={styles.subscriptionBadge}
>
<Image
source={subscriptionBadgeSource}
@@ -258,6 +253,15 @@ export default ({
) : null}
</View>
) : null}
{showReturnHomeButton ? (
<GradientButton
title="retour à l'accueil"
onPress={handleReturnHomePress}
containerStyle={styles.returnHomeButton}
/>
) : null}
</View>
) : null}
<PageContainer
{...(containerType === "SAFE_AREA_VIEW" ? { edges: ["top"] } : {})}
style={{
@@ -328,3 +332,37 @@ export default ({
</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(
() => (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,22 +518,19 @@ const Home = ({ navigation, route }) => {
</View>
) : null;
const returnHomeButton = (
<GradientButton
title="retour à l'accueil"
onPress={handleReturnToLanding}
containerStyle={styles.returnButton}
/>
);
const topBar = (
<View style={styles.topBar}>
<Pressable
onPress={handleNavigateToLanding}
accessibilityRole="button"
style={[
styles.returnLandingButton,
isWeb ? styles.returnLandingButtonWeb : null,
]}
>
<Text style={styles.returnLandingButtonText}>
Retour à l'accueil
</Text>
</Pressable>
<View style={styles.topBarContent}>
{/* {returnHomeButton} */}
{mobileInfoRow}
{!isWeb ? returnHomeButton : null}
<ProjectDropDown
ref={projectDropdownRef}
style={styles.projectDropDown}
@@ -546,7 +543,6 @@ const Home = ({ navigation, route }) => {
formatDate={formatDate}
/>
</View>
</View>
);
const journeyContent = (
@@ -592,9 +588,7 @@ const Home = ({ navigation, route }) => {
{stageCardsList}
<ClubCard
onPress={handleClubPress}
/>
<ClubCard onPress={handleClubPress} />
</>
);
@@ -611,6 +605,8 @@ const Home = ({ navigation, route }) => {
maxWidth={1600}
width="100%"
backgroundColor="#303438"
showReturnHome={isWeb}
onReturnHome={handleReturnToLanding}
>
<View style={styles.inner}>
<ExpoImage
@@ -619,10 +615,15 @@ const Home = ({ navigation, route }) => {
style={styles.centerImage}
/>
{isWeb ? (
<>
{/* <View style={styles.webReturnButtonWrapper}>
{returnHomeButton}
</View> */}
<View style={styles.contentOverlay}>
{topBar}
{journeyContent}
</View>
</>
) : (
<View style={[styles.contentOverlay, styles.mobileContent]}>
{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%",