263 lines
7.4 KiB
JavaScript
263 lines
7.4 KiB
JavaScript
import { Platform, Pressable, StyleSheet, Text, View } from "react-native";
|
|
import React, { useMemo, useState } from "react";
|
|
import CreateLyricsHeader from "./components/CreateLyricsHeader";
|
|
import { OTHER_STYLE_OPTION, SONG_STYLE } from "../../data/data";
|
|
import { Palette } from "../../styles";
|
|
import CustomInput from "./components/CustomInput";
|
|
import { FONT_FAMILY } from "../../styles/Fonts";
|
|
import ItemContainer from "../../components/ItemContainer/ItemContainer";
|
|
import ListSelection from "../../components/ListSelection/ListSelection";
|
|
import { BaseButton } from "../../components/Button";
|
|
import Overlay from "../../components/Overlay";
|
|
|
|
const SongStyle = ({
|
|
selected: selectedProp,
|
|
setSelected: setSelectedProp,
|
|
otherStyle,
|
|
setOtherStyle,
|
|
}) => {
|
|
const normalizedOtherStyle =
|
|
typeof otherStyle === "string" ? otherStyle : "";
|
|
|
|
const [internalSelected, setInternalSelected] = useState(null);
|
|
const [otherStyleModalVisible, setOtherStyleModalVisible] = useState(false);
|
|
const [previousSelection, setPreviousSelection] = useState(null);
|
|
const [previousOtherStyle, setPreviousOtherStyle] = useState(
|
|
normalizedOtherStyle
|
|
);
|
|
|
|
const selected = selectedProp ?? internalSelected;
|
|
const setSelectedBase = setSelectedProp ?? setInternalSelected;
|
|
|
|
const trimmedOtherStyle = normalizedOtherStyle.trim();
|
|
const hasOtherStyleValue = trimmedOtherStyle.length > 0;
|
|
|
|
const songStyleOptions = useMemo(() => SONG_STYLE ?? [], []);
|
|
|
|
const handleOtherStyleChange = (value) => {
|
|
setOtherStyle?.(value);
|
|
const trimmed = value?.trim() ?? "";
|
|
if (trimmed.length) {
|
|
if (selected !== OTHER_STYLE_OPTION) {
|
|
setSelectedBase(OTHER_STYLE_OPTION);
|
|
}
|
|
} else if (selected === OTHER_STYLE_OPTION) {
|
|
setSelectedBase(null);
|
|
setPreviousSelection(null);
|
|
}
|
|
};
|
|
|
|
const handleStyleSelect = (value) => {
|
|
if (value === OTHER_STYLE_OPTION) {
|
|
setPreviousSelection(selected ?? null);
|
|
setPreviousOtherStyle(normalizedOtherStyle);
|
|
setSelectedBase(value);
|
|
setOtherStyleModalVisible(true);
|
|
return;
|
|
}
|
|
setSelectedBase(value);
|
|
setOtherStyleModalVisible(false);
|
|
setPreviousSelection(null);
|
|
};
|
|
|
|
const handleOpenOtherStyleModal = () => {
|
|
setPreviousSelection(selected ?? null);
|
|
setPreviousOtherStyle(normalizedOtherStyle);
|
|
setOtherStyleModalVisible(true);
|
|
};
|
|
|
|
const handleCancelOtherStyle = () => {
|
|
setOtherStyleModalVisible(false);
|
|
setOtherStyle?.(previousOtherStyle);
|
|
if (selected === OTHER_STYLE_OPTION) {
|
|
setSelectedBase(previousSelection ?? null);
|
|
}
|
|
setPreviousSelection(null);
|
|
};
|
|
|
|
const handleConfirmOtherStyle = () => {
|
|
if (!hasOtherStyleValue) {
|
|
const fallback =
|
|
previousSelection && previousSelection !== OTHER_STYLE_OPTION
|
|
? previousSelection
|
|
: null;
|
|
setOtherStyle?.(previousOtherStyle);
|
|
setSelectedBase(fallback);
|
|
setOtherStyleModalVisible(false);
|
|
setPreviousSelection(null);
|
|
return;
|
|
}
|
|
if (selected !== OTHER_STYLE_OPTION) {
|
|
setSelectedBase(OTHER_STYLE_OPTION);
|
|
}
|
|
setOtherStyleModalVisible(false);
|
|
setPreviousSelection(OTHER_STYLE_OPTION);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<View style={{ flex: 1, gap: 16, marginTop: 16 }}>
|
|
<View style={{ gap: 10 }}>
|
|
<CreateLyricsHeader
|
|
title={`Quel est le style de ta chanson ?`}
|
|
subTitle="Choisis l'ambiance émotions que tu veux faire passer."
|
|
/>
|
|
<ItemContainer>
|
|
<ListSelection
|
|
options={songStyleOptions}
|
|
variant="titleDescription"
|
|
selected={selected}
|
|
setSelected={handleStyleSelect}
|
|
contentContainerStyle={styles.contentContainer}
|
|
itemContainerStyle={styles.itemContainer}
|
|
/>
|
|
</ItemContainer>
|
|
</View>
|
|
{selected === OTHER_STYLE_OPTION ? (
|
|
<View style={styles.otherStyleSummary}>
|
|
<View style={{ flex: 1, gap: 4 }}>
|
|
<Text style={styles.summaryLabel}>
|
|
Tu as un autre style de chanson ?
|
|
</Text>
|
|
<Text
|
|
style={[
|
|
styles.summaryValue,
|
|
!hasOtherStyleValue && styles.summaryPlaceholder,
|
|
]}
|
|
numberOfLines={3}
|
|
>
|
|
{hasOtherStyleValue ? trimmedOtherStyle : "Décrire le style"}
|
|
</Text>
|
|
</View>
|
|
<Pressable
|
|
style={styles.summaryButton}
|
|
onPress={handleOpenOtherStyleModal}
|
|
>
|
|
<Text style={styles.summaryButtonText}>
|
|
{hasOtherStyleValue ? "Modifier" : "Ajouter"}
|
|
</Text>
|
|
</Pressable>
|
|
</View>
|
|
) : null}
|
|
</View>
|
|
<Overlay
|
|
isVisible={otherStyleModalVisible}
|
|
setIsVisible={handleCancelOtherStyle}
|
|
>
|
|
<View style={styles.modalContent}>
|
|
<Text style={styles.modalTitle}>
|
|
Tu as un autre style de chanson ?
|
|
</Text>
|
|
<CustomInput
|
|
placeholder="Décrire le style"
|
|
value={otherStyle}
|
|
setValue={handleOtherStyleChange}
|
|
height={Platform.OS === "web" ? 160 : undefined}
|
|
/>
|
|
<View style={styles.modalActions}>
|
|
<BaseButton
|
|
type="secondary"
|
|
text="Annuler"
|
|
onPress={handleCancelOtherStyle}
|
|
containerStyle={styles.modalActionButton}
|
|
/>
|
|
<BaseButton
|
|
text="Valider"
|
|
onPress={handleConfirmOtherStyle}
|
|
containerStyle={styles.modalActionButton}
|
|
/>
|
|
</View>
|
|
</View>
|
|
</Overlay>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default SongStyle;
|
|
|
|
const styles = StyleSheet.create({
|
|
contentContainer: {
|
|
flexGrow: 1,
|
|
padding: 8,
|
|
gap: 10,
|
|
backgroundColor: "#FFFFFF00",
|
|
paddingBottom: 50,
|
|
},
|
|
itemContainer: {
|
|
borderRadius: 14,
|
|
shadowColor: "#00000040",
|
|
shadowOffset: {
|
|
width: 0,
|
|
height: 2,
|
|
},
|
|
shadowOpacity: 0.25,
|
|
shadowRadius: 3.84,
|
|
|
|
elevation: 5,
|
|
},
|
|
itemText: {
|
|
fontSize: 16,
|
|
color: Palette.white,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
textAlign: "center",
|
|
},
|
|
otherStyleSummary: {
|
|
backgroundColor: Palette.ultraLightWhite,
|
|
borderRadius: 12,
|
|
padding: 12,
|
|
flexDirection: "row",
|
|
alignItems: "flex-start",
|
|
gap: 12,
|
|
},
|
|
summaryLabel: {
|
|
fontSize: 14,
|
|
color: Palette.white,
|
|
fontFamily: FONT_FAMILY.InterMedium,
|
|
},
|
|
summaryValue: {
|
|
fontSize: 14,
|
|
color: Palette.white,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
},
|
|
summaryPlaceholder: {
|
|
color: Palette.grayMid,
|
|
fontStyle: "italic",
|
|
},
|
|
summaryButton: {
|
|
alignSelf: "flex-start",
|
|
paddingVertical: 6,
|
|
paddingHorizontal: 12,
|
|
borderRadius: 999,
|
|
borderWidth: 1,
|
|
borderColor: Palette.white,
|
|
backgroundColor: "#FFFFFF10",
|
|
},
|
|
summaryButtonText: {
|
|
fontSize: 12,
|
|
color: Palette.white,
|
|
fontFamily: FONT_FAMILY.InterMedium,
|
|
},
|
|
modalContent: {
|
|
width: "90%",
|
|
maxWidth: 420,
|
|
padding: 20,
|
|
borderRadius: 16,
|
|
backgroundColor: Palette.darkPurple,
|
|
gap: 16,
|
|
},
|
|
modalTitle: {
|
|
fontSize: 18,
|
|
color: Palette.white,
|
|
fontFamily: FONT_FAMILY.InterSemiBold,
|
|
textAlign: "center",
|
|
},
|
|
modalActions: {
|
|
flexDirection: "row",
|
|
gap: 12,
|
|
},
|
|
modalActionButton: {
|
|
flex: 1,
|
|
},
|
|
});
|