290 lines
8.2 KiB
JavaScript
290 lines
8.2 KiB
JavaScript
import React, { useMemo, useState } from "react";
|
|
import {
|
|
Platform,
|
|
Pressable,
|
|
ScrollView,
|
|
StyleSheet,
|
|
Text,
|
|
View,
|
|
} from "react-native";
|
|
import { BaseButton } from "../../components/Button";
|
|
import ItemContainer from "../../components/ItemContainer/ItemContainer";
|
|
import ListSelection from "../../components/ListSelection/ListSelection";
|
|
import Overlay from "../../components/Overlay";
|
|
import { strings } from "../../constants/strings";
|
|
import { GOALS, OTHER_OBJECTIVE_OPTION } from "../../data/data";
|
|
import { Palette } from "../../styles";
|
|
import { FONT_FAMILY } from "../../styles/Fonts";
|
|
import CreateLyricsHeader from "./components/CreateLyricsHeader";
|
|
import CustomInput from "./components/CustomInput";
|
|
|
|
const Goals = ({
|
|
selected: selectedProp,
|
|
setSelected: setSelectedProp,
|
|
otherObjective,
|
|
setOtherObjective,
|
|
}) => {
|
|
const normalizedOtherObjective =
|
|
typeof otherObjective === "string" ? otherObjective : "";
|
|
|
|
const [internalSelected, setInternalSelected] = useState(null);
|
|
const [otherObjectiveModalVisible, setOtherObjectiveModalVisible] =
|
|
useState(false);
|
|
const [previousSelection, setPreviousSelection] = useState(null);
|
|
const [previousOtherObjective, setPreviousOtherObjective] = useState(
|
|
normalizedOtherObjective
|
|
);
|
|
|
|
const selected = selectedProp ?? internalSelected;
|
|
const setSelectedBase = setSelectedProp ?? setInternalSelected;
|
|
|
|
const trimmedOtherObjective = normalizedOtherObjective.trim();
|
|
const hasOtherObjectiveValue = trimmedOtherObjective.length > 0;
|
|
|
|
const goalsOptions = useMemo(() => GOALS ?? [], []);
|
|
|
|
const handleOtherObjectiveChange = (value) => {
|
|
setOtherObjective?.(value);
|
|
const trimmed = value?.trim() ?? "";
|
|
if (trimmed.length) {
|
|
if (selected !== OTHER_OBJECTIVE_OPTION) {
|
|
setSelectedBase(OTHER_OBJECTIVE_OPTION);
|
|
}
|
|
} else if (selected === OTHER_OBJECTIVE_OPTION) {
|
|
setSelectedBase(null);
|
|
setPreviousSelection(null);
|
|
}
|
|
};
|
|
|
|
const handleGoalSelect = (value) => {
|
|
if (value === OTHER_OBJECTIVE_OPTION) {
|
|
setPreviousSelection(selected ?? null);
|
|
setPreviousOtherObjective(normalizedOtherObjective);
|
|
setSelectedBase(value);
|
|
setOtherObjectiveModalVisible(true);
|
|
return;
|
|
}
|
|
setSelectedBase(value);
|
|
setOtherObjectiveModalVisible(false);
|
|
setPreviousSelection(null);
|
|
};
|
|
|
|
const handleOpenOtherObjectiveModal = () => {
|
|
setPreviousSelection(selected ?? null);
|
|
setPreviousOtherObjective(normalizedOtherObjective);
|
|
setOtherObjectiveModalVisible(true);
|
|
};
|
|
|
|
const handleCancelOtherObjective = () => {
|
|
setOtherObjectiveModalVisible(false);
|
|
setOtherObjective?.(previousOtherObjective);
|
|
if (selected === OTHER_OBJECTIVE_OPTION) {
|
|
setSelectedBase(previousSelection ?? null);
|
|
}
|
|
setPreviousSelection(null);
|
|
};
|
|
|
|
const handleConfirmOtherObjective = () => {
|
|
if (!hasOtherObjectiveValue) {
|
|
const fallback =
|
|
previousSelection && previousSelection !== OTHER_OBJECTIVE_OPTION
|
|
? previousSelection
|
|
: null;
|
|
setOtherObjective?.(previousOtherObjective);
|
|
setSelectedBase(fallback);
|
|
setOtherObjectiveModalVisible(false);
|
|
setPreviousSelection(null);
|
|
return;
|
|
}
|
|
if (selected !== OTHER_OBJECTIVE_OPTION) {
|
|
setSelectedBase(OTHER_OBJECTIVE_OPTION);
|
|
}
|
|
setOtherObjectiveModalVisible(false);
|
|
setPreviousSelection(OTHER_OBJECTIVE_OPTION);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<ScrollView contentContainerStyle={{ flex: 1, gap: 16, marginTop: 16 }}>
|
|
<View style={{ gap: 10, height: "100%" }}>
|
|
<CreateLyricsHeader title={strings.writing.steps.contextTitle} />
|
|
{/* <View style={styles.examplesContainer}>
|
|
<Text style={styles.examplesText}>
|
|
{strings.writing.steps.contextExamples}
|
|
</Text>
|
|
</View> */}
|
|
<ItemContainer height={"80%"}>
|
|
<ListSelection
|
|
options={goalsOptions}
|
|
variant="simple"
|
|
selected={selected}
|
|
setSelected={handleGoalSelect}
|
|
contentContainerStyle={styles.contentContainer}
|
|
itemContainerStyle={styles.itemContainer}
|
|
itemTextStyle={styles.itemText}
|
|
/>
|
|
</ItemContainer>
|
|
</View>
|
|
{selected === OTHER_OBJECTIVE_OPTION ? (
|
|
<View style={styles.otherObjectiveSummary}>
|
|
<View style={{ flex: 1, gap: 4 }}>
|
|
<Text style={styles.summaryLabel}>
|
|
{strings.writing.labels.otherObjective}
|
|
</Text>
|
|
<Text
|
|
style={[
|
|
styles.summaryValue,
|
|
!hasOtherObjectiveValue && styles.summaryPlaceholder,
|
|
]}
|
|
numberOfLines={3}
|
|
>
|
|
{hasOtherObjectiveValue
|
|
? trimmedOtherObjective
|
|
: strings.writing.labels.otherObjectivePlaceholder}
|
|
</Text>
|
|
</View>
|
|
<Pressable
|
|
style={styles.summaryButton}
|
|
onPress={handleOpenOtherObjectiveModal}
|
|
>
|
|
<Text style={styles.summaryButtonText}>
|
|
{hasOtherObjectiveValue ? "Modifier" : "Ajouter"}
|
|
</Text>
|
|
</Pressable>
|
|
</View>
|
|
) : null}
|
|
</ScrollView>
|
|
<Overlay
|
|
isVisible={otherObjectiveModalVisible}
|
|
setIsVisible={handleCancelOtherObjective}
|
|
>
|
|
<View style={styles.modalContent}>
|
|
<Text style={styles.modalTitle}>
|
|
{strings.writing.labels.otherObjective}
|
|
</Text>
|
|
<CustomInput
|
|
placeholder={strings.writing.labels.otherObjectivePlaceholder}
|
|
value={otherObjective}
|
|
setValue={handleOtherObjectiveChange}
|
|
height={Platform.OS === "web" ? 160 : undefined}
|
|
/>
|
|
<View style={styles.modalActions}>
|
|
<BaseButton
|
|
type="secondary"
|
|
text="Annuler"
|
|
onPress={handleCancelOtherObjective}
|
|
containerStyle={styles.modalActionButton}
|
|
/>
|
|
<BaseButton
|
|
text="Valider"
|
|
onPress={handleConfirmOtherObjective}
|
|
containerStyle={styles.modalActionButton}
|
|
/>
|
|
</View>
|
|
</View>
|
|
</Overlay>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Goals;
|
|
|
|
const styles = StyleSheet.create({
|
|
contentContainer: {
|
|
flexGrow: 1,
|
|
padding: 8,
|
|
gap: 10,
|
|
backgroundColor: "#FFFFFF00",
|
|
paddingBottom: 50,
|
|
width: "100%",
|
|
},
|
|
itemContainer: {
|
|
height: 54,
|
|
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",
|
|
},
|
|
examplesContainer: {
|
|
backgroundColor: Palette.ultraLightWhite,
|
|
borderRadius: 12,
|
|
padding: 12,
|
|
},
|
|
examplesText: {
|
|
fontSize: 14,
|
|
color: Palette.white,
|
|
fontFamily: FONT_FAMILY.InterRegular,
|
|
lineHeight: 20,
|
|
},
|
|
otherObjectiveSummary: {
|
|
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,
|
|
},
|
|
});
|