more fixes and changes, crash, design …

This commit is contained in:
Thomas Demirdjian
2025-11-14 18:25:28 +01:00
parent cd31d42c0c
commit 705fda0ce3
17 changed files with 1136 additions and 785 deletions
+167 -70
View File
@@ -5,8 +5,8 @@ import React, {
useRef,
useState,
} from "react";
import { ScrollView, StyleSheet, Text, View } from "react-native";
import { Image as ExpoImage } from "expo-image";
import { Pressable, ScrollView, StyleSheet, Text, View } from "react-native";
import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
import { background, cardsImg, icons } from "../../assets";
import Alert from "../../components/Alert";
@@ -16,6 +16,7 @@ import FullscreenIntroVideo from "../../components/FullscreenIntroVideo";
import GradientButton from "../../components/GradientButton";
import MoreMenu from "../../components/MoreMenu";
import ProjectDropDown from "../../components/ProjectDropDown/ProjectDropDown";
import CoinPackModal from "../../components/modal/CoinPackModal";
import { projectsRef, usersRef } from "../../config/firebase";
import { isWeb } from "../../hooks/useLayoutType.js";
import Page from "../../layouts/Page";
@@ -23,12 +24,15 @@ import LandingPage from "../LandingPage";
import { navigate } from "../../navigation/NavigationService";
import { Routes } from "../../navigation/Routes";
import { useUser } from "../../providers/UserDataProvider";
import CreditAmount from "../../components/CreditAmount";
import ShareBtn from "../../components/ShareBtn/ShareBtn";
import { Palette, gutters } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import {
getCreationStageStates,
getStageAction,
} from "../../utils/projectStages";
import { openCoinPackModal } from "../../utils/coinPackModal";
import StageCard from "./components/StageCard";
import ClubCard from "./components/ClubCard";
@@ -424,6 +428,8 @@ const Home = ({ navigation, route }) => {
[stageStatesByKey],
);
const [isCoinModalVisible, setCoinModalVisible] = useState(false);
const handleStagePress = useCallback(
(stageKey, isLocked) => {
if (isLocked) {
@@ -451,6 +457,18 @@ const Home = ({ navigation, route }) => {
navigate(Routes.Payments);
}, []);
const handleOpenCoinModal = useCallback(() => {
if (isWeb) {
openCoinPackModal();
return;
}
setCoinModalVisible(true);
}, []);
const handleCloseCoinModal = useCallback(() => {
setCoinModalVisible(false);
}, []);
const stageCardContainerStyle = isWeb ? styles.cardsGrid : styles.cardsStack;
const stageCardItemStyle = isWeb
? styles.webStageCard
@@ -476,8 +494,45 @@ const Home = ({ navigation, route }) => {
</View>
);
const coinBalance = useMemo(() => {
const value = currentUserData?.coins;
if (typeof value === "number" && Number.isFinite(value)) {
return value;
}
if (typeof value === "string") {
const parsed = Number(value);
if (Number.isFinite(parsed)) {
return parsed;
}
}
return 0;
}, [currentUserData?.coins]);
const mobileInfoRow = !isWeb ? (
<View style={styles.mobileInfoRow}>
<Pressable
onPress={handleOpenCoinModal}
accessibilityRole="button"
style={styles.mobileCoinButton}
>
<CreditAmount
value={coinBalance}
style={styles.mobileCoinAmount}
textStyle={styles.mobileCoinText}
iconSize={20}
iconPosition="left"
/>
</Pressable>
<ShareBtn
style={styles.mobileShareButton}
iconOnly
/>
</View>
) : null;
const topBar = (
<View style={styles.topBar}>
{mobileInfoRow}
<ProjectDropDown
style={styles.projectDropDown}
projects={projects}
@@ -542,72 +597,82 @@ const Home = ({ navigation, route }) => {
</>
);
return adventureStarted ? (
<View style={styles.root}>
<Page
shareBtn
headerType="NONE"
scrollEnabled={false}
containerStyle={styles.page}
contentContainerStyle={styles.pageContent}
maxWidth={1600}
width="100%"
backgroundColor="#303438"
>
<View style={styles.inner}>
<ExpoImage
source={homeBackgroundImage}
contentFit="cover"
style={styles.centerImage}
/>
{isWeb ? (
<View style={styles.contentOverlay}>
{topBar}
{journeyContent}
</View>
) : (
<View style={[styles.contentOverlay, styles.mobileContent]}>
{topBar}
<ScrollView
style={styles.mobileScrollView}
contentContainerStyle={styles.mobileScrollContent}
showsVerticalScrollIndicator={false}
>
{journeyContent}
</ScrollView>
</View>
)}
</View>
</Page>
</View>
) : (
return (
<>
<Page
shareBtn
title="Landing Page"
backgroundImg={landingBackgroundImage}
contentContainerStyle={styles.pageContent}
backgroundColor="#303438"
>
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<GradientButton
url={videoUrl}
title="Commencer l'aventure MusicLand"
onPress={handleStartVisit}
/>
{adventureStarted ? (
<View style={styles.root}>
<Page
shareBtn
headerType="NONE"
scrollEnabled={false}
containerStyle={styles.page}
contentContainerStyle={styles.pageContent}
maxWidth={1600}
width="100%"
backgroundColor="#303438"
>
<View style={styles.inner}>
<ExpoImage
source={homeBackgroundImage}
contentFit="cover"
style={styles.centerImage}
/>
{isWeb ? (
<View style={styles.contentOverlay}>
{topBar}
{journeyContent}
</View>
) : (
<View style={[styles.contentOverlay, styles.mobileContent]}>
{topBar}
<ScrollView
style={styles.mobileScrollView}
contentContainerStyle={styles.mobileScrollContent}
showsVerticalScrollIndicator={false}
>
{journeyContent}
</ScrollView>
</View>
)}
</View>
</Page>
</View>
</Page>
<FullscreenIntroVideo
url={videoUrl}
visible={isIntroVideoVisible}
onClose={handleIntroVideoClose}
/>
) : (
<>
<Page
shareBtn
title="Landing Page"
backgroundImg={landingBackgroundImage}
contentContainerStyle={styles.pageContent}
backgroundColor="#303438"
>
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<GradientButton
url={videoUrl}
title="Commencer l'aventure MusicLand"
onPress={handleStartVisit}
/>
</View>
</Page>
<FullscreenIntroVideo
url={videoUrl}
visible={isIntroVideoVisible}
onClose={handleIntroVideoClose}
/>
</>
)}
{!isWeb ? (
<CoinPackModal
visible={isCoinModalVisible}
onClose={handleCloseCoinModal}
/>
) : null}
</>
);
};
@@ -659,10 +724,10 @@ const styles = StyleSheet.create({
},
topBar: {
width: "100%",
flexDirection: "row",
flexWrap: "wrap",
alignItems: "center",
justifyContent: "center",
flexDirection: isWeb ? "row" : "column",
flexWrap: isWeb ? "wrap" : "nowrap",
alignItems: isWeb ? "center" : "stretch",
justifyContent: isWeb ? "center" : "flex-start",
gap: 12,
marginTop: isWeb ? 24 : 0,
marginBottom: isWeb ? 8 : 16,
@@ -674,6 +739,38 @@ const styles = StyleSheet.create({
maxWidth: 420,
flexGrow: 1,
},
mobileInfoRow: {
width: "100%",
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
gap: 12,
},
mobileCoinButton: {
flexDirection: "row",
alignItems: "center",
gap: 8,
paddingHorizontal: 14,
paddingVertical: 8,
borderRadius: 20,
backgroundColor: "rgba(12, 14, 18, 0.72)",
borderWidth: 1,
borderColor: "rgba(255, 255, 255, 0.1)",
flexShrink: 1,
},
mobileCoinAmount: {
flexDirection: "row",
alignItems: "center",
gap: 6,
},
mobileCoinText: {
fontSize: 18,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
},
mobileShareButton: {
flexShrink: 0,
},
mobileContent: {
flex: 1,
width: "100%",
@@ -684,7 +781,7 @@ const styles = StyleSheet.create({
},
mobileScrollContent: {
paddingHorizontal: gutters,
paddingTop: 24,
paddingTop: 0,
paddingBottom: gutters * 6,
},
subtitleWrapper: {