add orders collecrtion for coins and subscriptions page
This commit is contained in:
+212
-35
@@ -1,7 +1,16 @@
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { Platform, ScrollView, StyleSheet, Text, View } from "react-native";
|
||||
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 { GOALS, OTHER_OBJECTIVE_OPTION } from "../../data/data";
|
||||
import { strings } from "../../constants/strings";
|
||||
import { Palette } from "../../styles";
|
||||
@@ -15,10 +24,22 @@ const Goals = ({
|
||||
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 setSelected = setSelectedProp ?? setInternalSelected;
|
||||
const setSelectedBase = setSelectedProp ?? setInternalSelected;
|
||||
|
||||
const trimmedOtherObjective = normalizedOtherObjective.trim();
|
||||
const hasOtherObjectiveValue = trimmedOtherObjective.length > 0;
|
||||
|
||||
const goalsOptions = useMemo(() => GOALS ?? [], []);
|
||||
|
||||
@@ -27,47 +48,145 @@ const Goals = ({
|
||||
const trimmed = value?.trim() ?? "";
|
||||
if (trimmed.length) {
|
||||
if (selected !== OTHER_OBJECTIVE_OPTION) {
|
||||
setSelected(OTHER_OBJECTIVE_OPTION);
|
||||
setSelectedBase(OTHER_OBJECTIVE_OPTION);
|
||||
}
|
||||
} else if (selected === OTHER_OBJECTIVE_OPTION) {
|
||||
setSelected(null);
|
||||
setSelectedBase(null);
|
||||
setPreviousSelection(null);
|
||||
}
|
||||
};
|
||||
|
||||
// Selection handled by ListSelection
|
||||
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 }}>
|
||||
<CreateLyricsHeader
|
||||
title={strings.writing.steps.contextTitle}
|
||||
subTitle={strings.writing.steps.contextSubtitle}
|
||||
/>
|
||||
<View style={styles.examplesContainer}>
|
||||
<Text style={styles.examplesText}>
|
||||
{strings.writing.steps.contextExamples}
|
||||
</Text>
|
||||
</View>
|
||||
<ItemContainer>
|
||||
<ListSelection
|
||||
options={goalsOptions}
|
||||
variant="simple"
|
||||
selected={selected}
|
||||
setSelected={setSelected}
|
||||
contentContainerStyle={styles.contentContainer}
|
||||
itemContainerStyle={styles.itemContainer}
|
||||
itemTextStyle={styles.itemText}
|
||||
<>
|
||||
<ScrollView contentContainerStyle={{ flex: 1, gap: 16, marginTop: 16 }}>
|
||||
<View style={{ gap: 10 }}>
|
||||
<CreateLyricsHeader
|
||||
title={strings.writing.steps.contextTitle}
|
||||
subTitle={strings.writing.steps.contextSubtitle}
|
||||
/>
|
||||
</ItemContainer>
|
||||
</View>
|
||||
<CustomInput
|
||||
label={strings.writing.labels.otherObjective}
|
||||
placeholder={strings.writing.labels.otherObjectivePlaceholder}
|
||||
value={otherObjective}
|
||||
setValue={handleOtherObjectiveChange}
|
||||
height={Platform.OS === "web" ? 160 : undefined}
|
||||
/>
|
||||
</ScrollView>
|
||||
<View style={styles.examplesContainer}>
|
||||
<Text style={styles.examplesText}>
|
||||
{strings.writing.steps.contextExamples}
|
||||
</Text>
|
||||
</View>
|
||||
<ItemContainer>
|
||||
<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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -112,4 +231,62 @@ const styles = StyleSheet.create({
|
||||
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,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user