feat: fixes
This commit is contained in:
@@ -26,6 +26,7 @@ const CreatePassword = () => {
|
||||
const city = route?.params?.city || "";
|
||||
const country = route?.params?.country || null;
|
||||
const preferredLanguage = route?.params?.preferredLanguage || null;
|
||||
const birthDate = route?.params?.birthDate || null;
|
||||
const [password, setPassword] = useState("");
|
||||
const [passwordError, setPasswordError] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -80,6 +81,7 @@ const CreatePassword = () => {
|
||||
...(trimmedLastName ? { lastName: trimmedLastName } : {}),
|
||||
...(trimmedCity ? { city: trimmedCity } : {}),
|
||||
...(preferredLanguage ? { preferredLanguage } : {}),
|
||||
...(birthDate ? { birthDate } : {}),
|
||||
...(country?.code ? { countryCode: country.code } : {}),
|
||||
...(country?.name ? { countryName: country.name } : {}),
|
||||
createdAt: firebase.firestore.FieldValue.serverTimestamp(),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { View, Text, Image } from "react-native";
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import AppCheckbox from "../../components/AppCheckbox";
|
||||
import Page from "../../layouts/Page";
|
||||
import MusicLandHeader from "../../components/MusicLandHeader";
|
||||
import GradientButton from "../../components/GradientButton";
|
||||
@@ -22,6 +23,7 @@ const StreamSong = () => {
|
||||
const { hasActiveSubscription } = useUser() || {};
|
||||
const userHasActiveSubscription = hasActiveSubscription;
|
||||
const { setTooltip } = useMinuit();
|
||||
const [hasAcceptedPublication, setHasAcceptedPublication] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (action && action !== "playback") {
|
||||
@@ -37,6 +39,13 @@ const StreamSong = () => {
|
||||
? "Publier mon playback"
|
||||
: "Rejoindre le Club MusicLand";
|
||||
const handlePrimaryAction = useCallback(() => {
|
||||
if (!hasAcceptedPublication) {
|
||||
setTooltip({
|
||||
type: "error",
|
||||
text: "Confirme la diffusion sur Musicland et YouTube avant de publier",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (userHasActiveSubscription) {
|
||||
if (action === "playback") {
|
||||
setTooltip({
|
||||
@@ -50,7 +59,7 @@ const StreamSong = () => {
|
||||
return;
|
||||
}
|
||||
navigate(Routes.Payments);
|
||||
}, [action, setTooltip, userHasActiveSubscription]);
|
||||
}, [action, hasAcceptedPublication, setTooltip, userHasActiveSubscription]);
|
||||
|
||||
return (
|
||||
<Page
|
||||
@@ -103,6 +112,25 @@ const StreamSong = () => {
|
||||
</View>
|
||||
</CreateLyricsHeader>
|
||||
<View style={{ marginTop: 24, gap: 12 }}>
|
||||
<View style={{ gap: 6 }}>
|
||||
<AppCheckbox
|
||||
selected={hasAcceptedPublication}
|
||||
onPress={() =>
|
||||
setHasAcceptedPublication((prevState) => !prevState)
|
||||
}
|
||||
label="J'accepte la diffusion de mon contenu sur Musicland et YouTube."
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 13,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
color: Palette.white,
|
||||
opacity: 0.8,
|
||||
}}
|
||||
>
|
||||
Cette confirmation est requise avant toute mise en ligne.
|
||||
</Text>
|
||||
</View>
|
||||
<GradientButton
|
||||
title={ctaLabel}
|
||||
onPress={handlePrimaryAction}
|
||||
|
||||
+90
-9
@@ -1,6 +1,8 @@
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import * as AppleAuthentication from "expo-apple-authentication";
|
||||
import DateTimePicker from "@react-native-community/datetimepicker";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { useGlobal } from "reactn";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
KeyboardAvoidingView,
|
||||
@@ -16,6 +18,7 @@ import { background } from "../assets";
|
||||
import BorderGradientButton from "../components/BorderGradientButton";
|
||||
import { Input } from "../components/Input";
|
||||
import ItemContainer from "../components/ItemContainer/ItemContainer";
|
||||
import WebDateModal from "../components/modal/WebDateModal";
|
||||
import firebase from "../config/firebase";
|
||||
import { isWeb } from "../hooks/useLayoutType";
|
||||
import useSocialAuth from "../hooks/useSocialAuth";
|
||||
@@ -32,6 +35,9 @@ const Register = () => {
|
||||
const [firstName, setFirstName] = useState("");
|
||||
const [lastName, setLastName] = useState("");
|
||||
const [preferredLanguage, setPreferredLanguage] = useState(null);
|
||||
const [birthDate, setBirthDate] = useState(null);
|
||||
const [showDatePicker, setShowDatePicker] = useState(false);
|
||||
const [, setTooltip] = useGlobal("_tooltip");
|
||||
|
||||
const afterSocialAuth = useCallback(async () => {
|
||||
const uid = firebase.auth().currentUser?.uid;
|
||||
@@ -65,7 +71,43 @@ const Register = () => {
|
||||
const isFormValid =
|
||||
email.trim().length > 0 &&
|
||||
firstName.trim().length > 0 &&
|
||||
lastName.trim().length > 0;
|
||||
lastName.trim().length > 0 &&
|
||||
birthDate;
|
||||
|
||||
function isAdult(date) {
|
||||
if (!date) return false;
|
||||
const today = new Date();
|
||||
let age = today.getFullYear() - date.getFullYear();
|
||||
const m = today.getMonth() - date.getMonth();
|
||||
if (m < 0 || (m === 0 && today.getDate() < date.getDate())) {
|
||||
age--;
|
||||
}
|
||||
return age >= 18;
|
||||
}
|
||||
|
||||
const handleNext = () => {
|
||||
if (!isAdult(birthDate)) {
|
||||
setTooltip({
|
||||
text: "Vous devez avoir au moins 18 ans pour créer un compte",
|
||||
type: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
navigate(Routes.CreatePassword, {
|
||||
email: email.trim(),
|
||||
firstName: firstName.trim(),
|
||||
lastName: lastName.trim(),
|
||||
birthDate: birthDate ? birthDate.toISOString() : null,
|
||||
preferredLanguage,
|
||||
});
|
||||
};
|
||||
|
||||
const onDateChange = (event, selectedDate) => {
|
||||
setShowDatePicker(Platform.OS === "ios");
|
||||
if (selectedDate) {
|
||||
setBirthDate(selectedDate);
|
||||
}
|
||||
};
|
||||
|
||||
const renderFormContent = () => (
|
||||
<View style={styles.formContent}>
|
||||
@@ -101,6 +143,52 @@ const Register = () => {
|
||||
value={email}
|
||||
setValue={setEmail}
|
||||
/>
|
||||
{isWeb ? (
|
||||
<>
|
||||
<Pressable onPress={() => setShowDatePicker(true)}>
|
||||
<View pointerEvents="none">
|
||||
<Input
|
||||
placeholder="Date de naissance"
|
||||
label="Date de naissance"
|
||||
isBlur
|
||||
value={birthDate ? birthDate.toLocaleDateString() : ""}
|
||||
editable={false}
|
||||
/>
|
||||
</View>
|
||||
</Pressable>
|
||||
<WebDateModal
|
||||
visible={showDatePicker}
|
||||
onClose={() => setShowDatePicker(false)}
|
||||
onValidate={(date) => setBirthDate(date)}
|
||||
initialDate={birthDate}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Pressable onPress={() => setShowDatePicker(true)}>
|
||||
<View pointerEvents="none">
|
||||
<Input
|
||||
placeholder="Date de naissance"
|
||||
label="Date de naissance"
|
||||
isBlur
|
||||
value={birthDate ? birthDate.toLocaleDateString() : ""}
|
||||
editable={false}
|
||||
/>
|
||||
</View>
|
||||
</Pressable>
|
||||
{showDatePicker && (
|
||||
<DateTimePicker
|
||||
testID="dateTimePicker"
|
||||
value={birthDate || new Date()}
|
||||
mode="date"
|
||||
is24Hour={true}
|
||||
display="default"
|
||||
onChange={onDateChange}
|
||||
maximumDate={new Date()}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
<BorderGradientButton
|
||||
title="Créer mon compte"
|
||||
@@ -108,14 +196,7 @@ const Register = () => {
|
||||
width: "90%",
|
||||
alignSelf: "center",
|
||||
}}
|
||||
onPress={() =>
|
||||
navigate(Routes.CreatePassword, {
|
||||
email: email.trim(),
|
||||
firstName: firstName.trim(),
|
||||
lastName: lastName.trim(),
|
||||
preferredLanguage,
|
||||
})
|
||||
}
|
||||
onPress={handleNext}
|
||||
disabled={!isFormValid || isBusy}
|
||||
/>
|
||||
<View style={styles.socialWrapper}>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { View, StyleSheet } from "react-native";
|
||||
import { View, StyleSheet, Text } from "react-native";
|
||||
import { MaterialIcons } from "@expo/vector-icons";
|
||||
import React, { useState } from "react";
|
||||
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
|
||||
import ItemContainer from "../../components/ItemContainer/ItemContainer";
|
||||
@@ -17,7 +18,33 @@ const ChooseInstruments = ({ selected = [], setSelected }) => {
|
||||
<CreateLyricsHeader
|
||||
title="Choisis des instruments"
|
||||
subTitle="Tu peux choisir jusqu’à 5 instruments différents"
|
||||
/>
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
gap: 6,
|
||||
backgroundColor: Palette.transparentOrange,
|
||||
padding: 8,
|
||||
borderRadius: 8,
|
||||
borderWidth: 1,
|
||||
borderColor: Palette.orange,
|
||||
marginTop: 4,
|
||||
}}
|
||||
>
|
||||
<MaterialIcons name="info-outline" size={20} color={Palette.orange} />
|
||||
<Text
|
||||
style={{
|
||||
flex: 1,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
fontSize: 12,
|
||||
color: Palette.white,
|
||||
}}
|
||||
>
|
||||
Attention : Suno peut ajuster ou supprimer certains paramètres
|
||||
choisis pour maintenir la cohérence de la création musicale.
|
||||
</Text>
|
||||
</View>
|
||||
</CreateLyricsHeader>
|
||||
<View
|
||||
style={{ flex: 1 }}
|
||||
onLayout={(event) => setContainerLayout(event.nativeEvent.layout)}
|
||||
|
||||
@@ -8,9 +8,12 @@ import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
Alert,
|
||||
} from "react-native";
|
||||
import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
|
||||
import * as FileSystem from "expo-file-system";
|
||||
import * as Sharing from "expo-sharing";
|
||||
import AppCheckbox from "../../components/AppCheckbox";
|
||||
import BorderGradientButton from "../../components/BorderGradientButton";
|
||||
import MusicLandHeader from "../../components/MusicLandHeader";
|
||||
import Page from "../../layouts/Page";
|
||||
@@ -38,9 +41,11 @@ const SongDownload = ({ route }) => {
|
||||
} = route?.params || {};
|
||||
const { selectedProject, updateProjectData, hasActiveSubscription } =
|
||||
useUser();
|
||||
const { setTooltip } = useMinuit();
|
||||
const { setLoading } = useGlobalLoading();
|
||||
const [isDownloading, setIsDownloading] = useState(false);
|
||||
const [showConfirmModal, setShowConfirmModal] = useState(false);
|
||||
const [hasAcceptedPublication, setHasAcceptedPublication] = useState(true);
|
||||
|
||||
const projectForStage = useMemo(
|
||||
() => routeProject || selectedProject || null,
|
||||
@@ -130,12 +135,26 @@ const SongDownload = ({ route }) => {
|
||||
]);
|
||||
|
||||
const handleContinue = useCallback(() => {
|
||||
if (!hasAcceptedPublication) {
|
||||
if (setTooltip) {
|
||||
setTooltip({
|
||||
type: "error",
|
||||
text: "Confirme la diffusion sur Musicland et YouTube avant de continuer",
|
||||
});
|
||||
} else {
|
||||
Alert.alert(
|
||||
"Confirmation requise",
|
||||
"Confirme la diffusion sur Musicland et YouTube avant de continuer"
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (hasActiveSubscription) {
|
||||
continueFlow();
|
||||
return;
|
||||
}
|
||||
setShowConfirmModal(true);
|
||||
}, [continueFlow, hasActiveSubscription]);
|
||||
}, [continueFlow, hasAcceptedPublication, hasActiveSubscription, setTooltip]);
|
||||
|
||||
const handleDownload = useCallback(async () => {
|
||||
const downloadUrl =
|
||||
@@ -401,6 +420,17 @@ const SongDownload = ({ route }) => {
|
||||
|
||||
<ClubAdvantagesCard style={styles.clubCardSpacing} />
|
||||
|
||||
<View style={styles.consentContainer}>
|
||||
<AppCheckbox
|
||||
selected={hasAcceptedPublication}
|
||||
onPress={() => setHasAcceptedPublication((prev) => !prev)}
|
||||
label="J'accepte la diffusion de mon contenu sur Musicland et YouTube."
|
||||
/>
|
||||
<Text style={styles.consentDescription}>
|
||||
Cette confirmation est requise pour continuer.
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<BorderGradientButton
|
||||
title={
|
||||
hasActiveSubscription
|
||||
@@ -438,6 +468,16 @@ const styles = StyleSheet.create({
|
||||
scrollContent: {
|
||||
paddingBottom: gutters * 2.6,
|
||||
},
|
||||
consentContainer: {
|
||||
gap: 6,
|
||||
marginTop: 10,
|
||||
},
|
||||
consentDescription: {
|
||||
fontSize: 13,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
color: Palette.white,
|
||||
opacity: 0.8,
|
||||
},
|
||||
coverRow: {
|
||||
flexDirection: isWeb ? "row" : "column",
|
||||
alignItems: "center",
|
||||
|
||||
Reference in New Issue
Block a user