Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 61 additions & 17 deletions app/src/scenes/goals/settings/GoalConfig.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState, useRef, useEffect, useCallback } from "react";
import { StyleSheet, View, Text } from "react-native";
import { StyleSheet, View, Text, Alert, Linking } from "react-native";
import { getDaysOfWeekLabel, getGoalsData, setGoalTracked } from "../../../utils/localStorage/goals";
import NotificationService from "@/services/notifications";
import { InputGroup, InputGroupItem } from "../../../components/InputGroup";
import { InputToggle } from "../../../components/InputToggle";
import TimePicker from "../../../components/timePicker";
Expand Down Expand Up @@ -52,21 +53,58 @@ export const GoalConfig = ({ navigation, route }) => {
}, [])
);

const showPermissionsAlert = () => {
Alert.alert(
"Vous devez autoriser les notifications.",
"Pour programmer un rappel il faut activer les notifications. Veuillez cliquer sur Réglages puis Notifications pour activer les notifications.",
[
{
text: "Réglages",
onPress: () => {
Linking.openSettings();
},
},
{
text: "Annuler",
style: "cancel",
},
],
{ cancelable: true }
);
};

const onValidate = async () => {
if (loading) return;
setLoading(true);
const reminder = reminderEnabled ? reminderTime : null;
if (!editing) {
await setGoalTracked({ id: goalId, daysOfWeek: goalDaysOfWeek, label: goalLabel, reminder });
logEvents.logAddObjectivePersonalized();
} else {
await setGoalTracked({ id: goalId, daysOfWeek: goalDaysOfWeek, reminder });
if (reminderHasChanged) {
logEvents.logEditObjectiveReminder();

try {
// Vérifier les permissions si un rappel est activé
if (reminderEnabled) {
const isRegistered = await NotificationService.checkAndAskForPermission();
if (!isRegistered) {
showPermissionsAlert();
setLoading(false);
return;
}
}

const reminder = reminderEnabled ? reminderTime : null;
if (!editing) {
await setGoalTracked({ id: goalId, daysOfWeek: goalDaysOfWeek, label: goalLabel, reminder });
logEvents.logAddObjectivePersonalized();
} else {
await setGoalTracked({ id: goalId, daysOfWeek: goalDaysOfWeek, reminder });
if (reminderHasChanged) {
logEvents.logEditObjectiveReminder();
}
}
navigation.navigate("goals-settings");
} catch (error) {
console.error("Erreur lors de la sauvegarde de l'objectif:", error);
alert("Une erreur est survenue lors de la sauvegarde. Veuillez réessayer.");
} finally {
setLoading(false);
}
setLoading(false);
navigation.navigate("goals-settings");
};

const onDeactivate = async () => {
Expand All @@ -75,12 +113,18 @@ export const GoalConfig = ({ navigation, route }) => {
confirm({
title: "Êtes-vous sûr de vouloir désactiver votre objectif ?",
onConfirm: async () => {
await setGoalTracked({
id: goalId,
enabled: false,
});
setDeactivateLoading(false);
navigation.goBack();
try {
await setGoalTracked({
id: goalId,
enabled: false,
});
navigation.goBack();
} catch (error) {
console.error("Erreur lors de la désactivation de l'objectif:", error);
alert("Une erreur est survenue lors de la désactivation. Veuillez réessayer.");
} finally {
setDeactivateLoading(false);
}
},
onCancel: () => {
setDeactivateLoading(false);
Expand Down
97 changes: 80 additions & 17 deletions app/src/scenes/goals/settings/GoalsAddOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import { DAYS_OF_WEEK } from "../../../utils/date/daysOfWeek";
import JMButton from "@/components/JMButton";
import Plus from "../../../../assets/svg/Plus";
import { AnimatedHeaderScrollScreen } from "@/scenes/survey-v2/AnimatedHeaderScrollScreen";
import { View } from "react-native";
import { View, Alert, Linking } from "react-native";
import NavigationButtons from "@/components/onboarding/NavigationButtons";
import logEvents from "@/services/logEvents";
import NotificationService from "@/services/notifications";

const GOALS_EXAMPLE_FLAT = Object.values(GOALS_EXAMPLE).reduce((acc, subGoalCategory) => {
return [...acc, ...subGoalCategory];
Expand Down Expand Up @@ -57,27 +58,89 @@ export const GoalsAddOptions = ({ navigation }) => {
[goalsToChange]
);

const showPermissionsAlert = () => {
Alert.alert(
"Vous devez autoriser les notifications",
"Certain de vos objectifs on un rappel programmé. Il faut activer les notifications pour programmer un rappel. Veuillez cliquer sur Réglages puis Notifications pour activer les notifications.",
[
{
text: "Réglages",
onPress: () => {
Linking.openSettings();
},
},
{
text: "Annuler",
style: "cancel",
},
],
{ cancelable: true }
);
};

const onValidate = async () => {
if (loading) return;
setLoading(true);
for (const goalLabel of Object.keys(goalsToChange)) {
const goalToChange = goalsToChange[goalLabel];
if (goalToChange.type === "disabled") {
await setGoalTracked({ label: goalLabel, enabled: goalToChange.enabled });
} else if (goalToChange.type === "example") {
await setGoalTracked({
label: goalLabel,
enabled: goalToChange.enabled,
daysOfWeek: DAYS_OF_WEEK.reduce((acc, day) => {
acc[day] = true;
return acc;
}, {}),
});
logEvents.logAddObjectiveNative();

try {
// Vérifier les permissions pour les notifications si des objectifs sont activés
const goalLabels = Object.keys(goalsToChange);
const hasEnabledGoals = goalLabels.some((label) => goalsToChange[label].enabled);

if (hasEnabledGoals) {
const isRegistered = await NotificationService.checkAndAskForPermission();
if (!isRegistered) {
showPermissionsAlert();
// Continue quand même avec la sauvegarde, mais les rappels ne seront pas actifs
}
}

let hasApiError = false;

for (const goalLabel of goalLabels) {
const goalToChange = goalsToChange[goalLabel];

try {
if (goalToChange.type === "disabled") {
const result = await setGoalTracked({
label: goalLabel,
enabled: goalToChange.enabled,
});
if (result?.apiError) hasApiError = true;
} else if (goalToChange.type === "example") {
const result = await setGoalTracked({
label: goalLabel,
enabled: goalToChange.enabled,
daysOfWeek: DAYS_OF_WEEK.reduce((acc, day) => {
acc[day] = true;
return acc;
}, {}),
});
if (result?.apiError) hasApiError = true;
logEvents.logAddObjectiveNative();
}
} catch (goalError) {
// Log l'erreur pour ce goal spécifique, mais continue avec les autres
console.error(`Erreur lors de la sauvegarde de l'objectif "${goalLabel}":`, goalError);
hasApiError = true;
}
}

// Feedback utilisateur approprié
if (hasApiError) {
Alert.alert("Objectifs sauvegardés", "Vos objectifs ont été sauvegardés, mais le rappel n'a pas pu être créé.", [
{ text: "OK", onPress: () => navigation.goBack() },
]);
}
navigation.goBack();
} catch (error) {
// Erreur critique (ex: problème de stockage)
console.error("Erreur critique lors de la validation des objectifs:", error);
Alert.alert("Erreur", "Une erreur est survenue lors de la sauvegarde de vos objectifs. Veuillez réessayer.", [{ text: "OK" }]);
} finally {
// Toujours désactiver le loading, même en cas d'erreur
setLoading(false);
}
setLoading(false);
navigation.goBack();
};

return (
Expand Down
Loading
Loading