diff --git a/app/components/TextButton/TextButton.styles.ts b/app/components/TextButton/TextButton.styles.ts index 0d4d97a2..d5c51c2b 100644 --- a/app/components/TextButton/TextButton.styles.ts +++ b/app/components/TextButton/TextButton.styles.ts @@ -2,10 +2,14 @@ import { StyleSheet } from "react-native"; export default StyleSheet.create({ container: { + flex: 1, flexDirection: "row", alignItems: "center", alignContent: "center", }, + textContainer: { + flex: 1, + }, text: { marginHorizontal: 8, }, diff --git a/app/components/TextButton/TextButton.tsx b/app/components/TextButton/TextButton.tsx index 8d2d306b..d76b98b4 100644 --- a/app/components/TextButton/TextButton.tsx +++ b/app/components/TextButton/TextButton.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { TouchableOpacity } from "react-native"; +import { TouchableOpacity, View } from "react-native"; import { Ionicons } from "@expo/vector-icons"; import { Colors } from "style"; @@ -18,11 +18,17 @@ const iconSize = 20; const TextButton: React.FC = ({ onPress, iconLeft, text }) => { return ( - - - {text} - - + + + + + + {text} + + + + + ); }; diff --git a/app/components/TextButton/__tests__/__snapshots__/TextButton.test.tsx.snap b/app/components/TextButton/__tests__/__snapshots__/TextButton.test.tsx.snap index 2e3b132e..d745a1cc 100644 --- a/app/components/TextButton/__tests__/__snapshots__/TextButton.test.tsx.snap +++ b/app/components/TextButton/__tests__/__snapshots__/TextButton.test.tsx.snap @@ -7,30 +7,55 @@ exports[`TextButton renders correctly with camera icon 1`] = ` Object { "alignContent": "center", "alignItems": "center", + "flex": 1, "flexDirection": "row", } } > - - - some text - - + + + + + some text + + + + + `; @@ -41,29 +66,54 @@ exports[`TextButton renders correctly with repeat icon 1`] = ` Object { "alignContent": "center", "alignItems": "center", + "flex": 1, "flexDirection": "row", } } > - - + + + + + some text + + + - some text - - + + `; diff --git a/app/screens/AddEmission/AddEmissionScreen.tsx b/app/screens/AddEmission/AddEmissionScreen.tsx index 9611e51c..0405c6da 100644 --- a/app/screens/AddEmission/AddEmissionScreen.tsx +++ b/app/screens/AddEmission/AddEmissionScreen.tsx @@ -7,12 +7,12 @@ import DateTimePickerModal from "react-native-modal-datetime-picker"; import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view"; import { useRoute } from "@react-navigation/core"; import { useNavigation } from "@react-navigation/native"; -import { pathOr } from "ramda"; +import { pathOr, join } from "ramda"; import { navigate } from "navigation"; import { Text, TextInput, TextButton, OpenFoodFacts } from "components"; import { userPreferences } from "ducks"; -import { EmissionType, EmissionPayload, EmissionModelType } from "interfaces"; +import { EmissionType, EmissionPayload, EmissionModelType, PeriodicityType } from "interfaces"; import { calculation, t, @@ -37,6 +37,7 @@ import { Meal, ProductScanned, } from "./components"; +import { WEEK_DAYS_LIST } from "../Periodicity/PeriodicityModalScreen"; /* multiply or divide by 1000 to have kilograms or meters */ const DEFAULT_SLIDER_VALUE_FOOD = 200 / 1000; @@ -54,6 +55,9 @@ const getName = pathOr("", ["params", "name"]); const getNutriscoreGrade = pathOr("", ["params", "nutriscoreGrade"]); const getNovaGroup = pathOr(-1, ["params", "novaGroup"]); const getEcoScore = pathOr("", ["params", "ecoScore"]); +const getPeriodType = pathOr(PeriodicityType.monthly, ["params", "periodType"]); +const getPeriodWeekDays = pathOr([], ["params", "periodWeekDays"]); +const getPeriodTimes = pathOr(0, ["params", "periodTimes"]); const AddEmissionScreen = ({ locale = "", language = "" }: LocalizationContextProps) => { const route = useRoute(); @@ -95,6 +99,35 @@ const AddEmissionScreen = ({ locale = "", language = "" }: LocalizationContextPr const novaGroup: number = getNovaGroup(route); const ecoScore: string = getEcoScore(route); + const periodType: PeriodicityType = getPeriodType(route); + const periodWeekDays: Array = getPeriodWeekDays(route); + const periodTimes: number = getPeriodTimes(route); + + let periodicityText = t("ADD_EMISSION_SCREEN_NON_RECURRING"); + if (periodTimes) { + if (periodTimes > 1) { + periodicityText = periodTimes + " " + t("ADD_EMISSION_SCREEN_TIMES"); + } else { + periodicityText = periodTimes + " " + t("ADD_EMISSION_SCREEN_TIME"); + } + + periodicityText = periodicityText + " - "; + + if (periodType == PeriodicityType.monthly) { + periodicityText = periodicityText + t("ADD_EMISSION_SCREEN_MONTHLY"); + } else { + periodicityText = periodicityText + t("ADD_EMISSION_SCREEN_WEEKLY"); + } + + if (periodWeekDays.length) { + periodicityText = periodicityText + " - "; + const daysToDisplay = WEEK_DAYS_LIST.filter((item) => + periodWeekDays.includes(item.dayIndex) + ).map((item) => t(item.nameKey)); + periodicityText = periodicityText + join(", ", daysToDisplay); + } + } + const handleConfirm = useCallback( (date: Date) => { hideDatePicker(); @@ -335,25 +368,33 @@ const AddEmissionScreen = ({ locale = "", language = "" }: LocalizationContextPr onCancel={hideDatePicker} /> - - {t("ADD_EMISSION_SCREEN_DATE")} - - + {!periodTimes ? ( + + {t("ADD_EMISSION_SCREEN_DATE")} + + + - + ) : null} {__DEV__ && ( {t("ADD_EMISSION_SCREEN_PERIODICITY")} navigator.openPeriodicityModal()} + onPress={() => + navigator.openPeriodicityModal({ + periodType, + periodWeekDays, + periodTimes, + }) + } iconLeft={"repeat"} - text={t("ADD_EMISSION_SCREEN_NON_RECURRING")} + text={periodicityText} /> diff --git a/app/screens/AddEmission/translations/en.json b/app/screens/AddEmission/translations/en.json index eadfcf84..391b97ec 100644 --- a/app/screens/AddEmission/translations/en.json +++ b/app/screens/AddEmission/translations/en.json @@ -18,5 +18,9 @@ "ADD_EMISSION_SCREEN_MEALS": "meal(s)", "ADD_EMISSION_SCREEN_PERIODICITY": "Periodicity", "ADD_EMISSION_SCREEN_NON_RECURRING": "Non-recurring", - "ADD_EMISSION_SCREEN_NAME": "Name" + "ADD_EMISSION_SCREEN_NAME": "Name", + "ADD_EMISSION_SCREEN_TIMES": "times", + "ADD_EMISSION_SCREEN_TIME": "time", + "ADD_EMISSION_SCREEN_WEEKLY": "weekly", + "ADD_EMISSION_SCREEN_MONTHLY": "monthly" } diff --git a/app/screens/AddEmission/translations/index.ts b/app/screens/AddEmission/translations/index.ts index 3528dbce..56686517 100644 --- a/app/screens/AddEmission/translations/index.ts +++ b/app/screens/AddEmission/translations/index.ts @@ -31,6 +31,10 @@ interface TranslationKeys { ADD_EMISSION_SCREEN_PERIODICITY: string; ADD_EMISSION_SCREEN_NON_RECURRING: string; ADD_EMISSION_SCREEN_NAME: string; + ADD_EMISSION_SCREEN_TIMES: string; + ADD_EMISSION_SCREEN_TIME: string; + ADD_EMISSION_SCREEN_WEEKLY: string; + ADD_EMISSION_SCREEN_MONTHLY: string; } export { en, fr, de, sv, es, pt, da, ru, pl, zh, ms, TranslationKeys }; diff --git a/app/screens/Periodicity/PeriodicityModalScreen.tsx b/app/screens/Periodicity/PeriodicityModalScreen.tsx index 80eb957b..a7fb611f 100644 --- a/app/screens/Periodicity/PeriodicityModalScreen.tsx +++ b/app/screens/Periodicity/PeriodicityModalScreen.tsx @@ -1,6 +1,8 @@ import React, { useState } from "react"; import { ScrollView, View } from "react-native"; import { useNavigation } from "@react-navigation/native"; +import { pathOr } from "ramda"; +import { useRoute } from "@react-navigation/core"; import { NavStatelessComponent, PeriodicityType } from "interfaces"; import { Button, Text } from "components"; @@ -9,13 +11,24 @@ import { TranslationKeys } from "utils/translations/resources"; import { t } from "utils"; import styles from "./PeriodicityModalScreen.styles"; -import navigationOptions from "./PeriodicityModal.navigationOptions"; -const PeriodicityModalScreen: NavStatelessComponent = () => { +const DEFAULT_VALUES = { + periodType: PeriodicityType.monthly, + weekDays: [], + periodTimes: 0, +}; + +const getPeriodType = pathOr(DEFAULT_VALUES.periodType, ["params", "periodType"]); +const getWeekDays = pathOr(DEFAULT_VALUES.weekDays, ["params", "periodWeekDays"]); +const getTimes = pathOr(DEFAULT_VALUES.periodTimes, ["params", "periodTimes"]); + +export const PeriodicityModalScreen: NavStatelessComponent = () => { + const route = useRoute(); const navigation = useNavigation(); - const [periodType, setPeriodType] = useState(null); - const [weekDays, setWeekdays] = useState([]); - const [times, setTimes] = useState(); + + const [periodType, setPeriodType] = useState(getPeriodType(route)); + const [weekDays, setWeekdays] = useState(getWeekDays(route)); + const [periodTimes, setTimes] = useState(getTimes(route)); function onWeekdaySelected(dayIndex: number) { setWeekdays( @@ -24,18 +37,23 @@ const PeriodicityModalScreen: NavStatelessComponent = () => { } function onConfirm() { - const periodicity = { + navigation.navigate("AddEmission", { periodType, periodWeekDays: periodType === PeriodicityType.weekly ? weekDays : null, - times, - }; + periodTimes, + }); + } + + function onCancel() { navigation.navigate("AddEmission", { - periodicity, + periodType: DEFAULT_VALUES.periodType, + periodWeekDays: DEFAULT_VALUES.weekDays, + periodTimes: DEFAULT_VALUES.periodTimes, }); } const hideConfirm = - !periodType || !times || (periodType === PeriodicityType.weekly && weekDays.length === 0); + !periodType || !periodTimes || (periodType === PeriodicityType.weekly && weekDays.length === 0); return ( @@ -84,7 +102,7 @@ const PeriodicityModalScreen: NavStatelessComponent = () => { {TIMES_LIST.map((_, index) => ( { setTimes(index + 1); }} @@ -101,7 +119,13 @@ const PeriodicityModalScreen: NavStatelessComponent = () => { + + )} @@ -111,21 +135,15 @@ const PeriodicityModalScreen: NavStatelessComponent = () => { const TIMES_LIST = new Array(3).fill(null); -const WEEK_DAYS_LIST: { +export const WEEK_DAYS_LIST: { dayIndex: number; nameKey: keyof TranslationKeys; }[] = [ + { dayIndex: 1, nameKey: "UI_SUNDAY" }, { dayIndex: 2, nameKey: "UI_MONDAY" }, { dayIndex: 3, nameKey: "UI_TUESDAY" }, { dayIndex: 4, nameKey: "UI_WEDNESDAY" }, { dayIndex: 5, nameKey: "UI_THURSDAY" }, { dayIndex: 6, nameKey: "UI_FRIDAY" }, - { dayIndex: 0, nameKey: "UI_SATURDAY" }, - { dayIndex: 1, nameKey: "UI_SUNDAY" }, + { dayIndex: 7, nameKey: "UI_SATURDAY" }, ]; - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -PeriodicityModalScreen.navigationOptions = navigationOptions; - -export default PeriodicityModalScreen; diff --git a/app/screens/Periodicity/__test__/PriodicityModalScreen.test.tsx b/app/screens/Periodicity/__test__/PriodicityModalScreen.test.tsx index 69143de1..014be89d 100644 --- a/app/screens/Periodicity/__test__/PriodicityModalScreen.test.tsx +++ b/app/screens/Periodicity/__test__/PriodicityModalScreen.test.tsx @@ -1,7 +1,7 @@ import React from "react"; import { create } from "react-test-renderer"; -import PeriodicityModalScreen from "../PeriodicityModalScreen"; +import { PeriodicityModalScreen } from "../PeriodicityModalScreen"; it("InfoModalScreen renders correctly", () => { const tree = create().toJSON(); diff --git a/app/screens/Periodicity/__test__/__snapshots__/PriodicityModalScreen.test.tsx.snap b/app/screens/Periodicity/__test__/__snapshots__/PriodicityModalScreen.test.tsx.snap index d92456eb..c3f9aef9 100644 --- a/app/screens/Periodicity/__test__/__snapshots__/PriodicityModalScreen.test.tsx.snap +++ b/app/screens/Periodicity/__test__/__snapshots__/PriodicityModalScreen.test.tsx.snap @@ -43,8 +43,8 @@ exports[`InfoModalScreen renders correctly 1`] = ` "paddingVertical": 4, }, Object { - "backgroundColor": "#F0F0F0", - "borderColor": "#9CA6A0", + "backgroundColor": "#DCF0E5", + "borderColor": "#4BB377", }, undefined, ] @@ -52,8 +52,8 @@ exports[`InfoModalScreen renders correctly 1`] = ` > Monthly diff --git a/app/screens/Periodicity/index.ts b/app/screens/Periodicity/index.ts index 57e17142..7fda75f2 100644 --- a/app/screens/Periodicity/index.ts +++ b/app/screens/Periodicity/index.ts @@ -1 +1,8 @@ -export { default } from "./PeriodicityModalScreen"; +import { PeriodicityModalScreen } from "./PeriodicityModalScreen"; +import navigationOptions from "./PeriodicityModal.navigationOptions"; + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +//@ts-ignore +PeriodicityModalScreen.navigationOptions = navigationOptions; + +export default PeriodicityModalScreen; diff --git a/app/screens/Periodicity/translations/en.json b/app/screens/Periodicity/translations/en.json index bf67ed60..f45daf7d 100644 --- a/app/screens/Periodicity/translations/en.json +++ b/app/screens/Periodicity/translations/en.json @@ -6,5 +6,7 @@ "PERIODICITY_MODAL_SCREEN_DAYS": "Which days is this emission repeat?", "PERIODICITY_MODAL_SCREEN_OCCURRENCES": "Occurences?", "PERIODICITY_MODAL_SCREEN_TIME": "time", - "PERIODICITY_MODAL_SCREEN_TIMES": "times" + "PERIODICITY_MODAL_SCREEN_TIMES": "times", + "PERIODICITY_MODAL_SCREEN_COMFIRM": "Confirm", + "PERIODICITY_MODAL_SCREEN_CANCEL_NO_PERIODICITY": "Cancel - No periodicity" } diff --git a/app/screens/Periodicity/translations/index.ts b/app/screens/Periodicity/translations/index.ts index b71bb25f..fcf30c78 100644 --- a/app/screens/Periodicity/translations/index.ts +++ b/app/screens/Periodicity/translations/index.ts @@ -19,13 +19,8 @@ interface TranslationKeys { PERIODICITY_MODAL_SCREEN_OCCURRENCES: string; PERIODICITY_MODAL_SCREEN_TIMES: string; PERIODICITY_MODAL_SCREEN_TIME: string; - MONDAY: string; - TUESDAY: string; - WEDNESDAY: string; - THURSDAY: string; - FRIDAY: string; - SATURDAY: string; - SUNDAY: string; + PERIODICITY_MODAL_SCREEN_COMFIRM: string; + PERIODICITY_MODAL_SCREEN_CANCEL_NO_PERIODICITY: string; } export { en, fr, de, sv, es, pt, da, ru, pl, zh, ms, TranslationKeys };