diff --git a/front/src/components/index.ts b/front/src/components/index.ts index 27c5f8f12..5d3db5440 100644 --- a/front/src/components/index.ts +++ b/front/src/components/index.ts @@ -42,6 +42,7 @@ import NotificationHandler, { setNotificationHandler, } from "./notification/notificationHandler.component"; import NotificationPermissionInSettingsModal from "./notification/notificationPermissionInSettingsModal.component"; +import NotificationsEssentialEvents from "./notification/notificationsEssentialEvents.component"; import NotificationsFrequency from "./notification/notificationsFrequency.component"; import NotificationToggle from "./notification/notificationToggle.component"; import CustomPagination from "./onboardingAndProfile/customOnboardingPagination.component"; @@ -87,6 +88,7 @@ export { MoodsCalendar, NotificationHandler, NotificationPermissionInSettingsModal, + NotificationsEssentialEvents, NotificationsFrequency, NotificationToggle, ParenthequeItem, diff --git a/front/src/components/menu/menu.component.tsx b/front/src/components/menu/menu.component.tsx index 9baf09a31..3797ef4f1 100644 --- a/front/src/components/menu/menu.component.tsx +++ b/front/src/components/menu/menu.component.tsx @@ -80,14 +80,13 @@ const Menu: React.FC = ({ showMenu, setShowMenu }) => { }, title: Labels.timeline.library.nom, }, - // TODO: feature-flipping => centre de notifications - // { - // icon: IcomoonIcons.notification, - // onPress: () => { - // void RootNavigation.navigate("notificationsCenter"); - // }, - // title: Labels.menu.notificationsCenter, - // }, + { + icon: IcomoonIcons.notification, + onPress: () => { + void RootNavigation.navigate("notificationsCenter"); + }, + title: Labels.menu.notificationsCenter, + }, { icon: IcomoonIcons.email, onPress: () => { diff --git a/front/src/components/notification/notificationToggle.component.tsx b/front/src/components/notification/notificationToggle.component.tsx index 56487728a..937d0492e 100644 --- a/front/src/components/notification/notificationToggle.component.tsx +++ b/front/src/components/notification/notificationToggle.component.tsx @@ -15,6 +15,7 @@ import { } from "../../utils"; import { NotificationType } from "../../utils/notifications/notification.util"; import * as NotificationUtils from "../../utils/notifications/notification.util"; +import { NotificationsEssentialEvents } from ".."; import TrackerHandler from "../tracker/trackerHandler.component"; import NotificationsFrequency from "./notificationsFrequency.component"; @@ -65,6 +66,8 @@ const NotificationToggle: FC = ({ const showOptionByType = (_type: NotificationType): ReactElement => { if (_type == NotificationType.moodboard) return ; + if (_type == NotificationType.event && events) + return ; return ; }; diff --git a/front/src/components/notification/notificationsEssentialEvents.component.tsx b/front/src/components/notification/notificationsEssentialEvents.component.tsx new file mode 100644 index 000000000..660081b10 --- /dev/null +++ b/front/src/components/notification/notificationsEssentialEvents.component.tsx @@ -0,0 +1,106 @@ +import type { FC } from "react"; +import * as React from "react"; +import { useCallback, useEffect, useState } from "react"; +import { StyleSheet } from "react-native"; +import { CheckBox } from "react-native-elements"; + +import { Labels, StorageKeysConstants } from "../../constants"; +import { Colors, Sizes } from "../../styles"; +import type { TrackerEvent } from "../../type"; +import type { Event } from "../../types"; +import { + EventUtils, + NotificationUtils, + StorageUtils, + TrackerUtils, +} from "../../utils"; +import { NotificationType } from "../../utils/notifications/notification.util"; +import { BaseAssets } from "../assets"; +import TrackerHandler from "../tracker/trackerHandler.component"; + +interface Props { + events: Event[]; +} + +const NotificationsEssentialEvents: FC = ({ events }) => { + const [trackerEventObject, setTrackerEventObject] = useState(); + const [isCheckboxChecked, setIsCheckboxChecked] = useState(false); + + const initCheckboxState = useCallback(async () => { + const areEssentialEventsChecked = (await StorageUtils.getObjectValue( + StorageKeysConstants.notifToggleEssentialEvents + )) as boolean; + setIsCheckboxChecked(areEssentialEventsChecked); + }, []); + + const scheduleEssentialEvents = useCallback( + async (shouldScheduleEssentialEvents: boolean) => { + const essentialEvents: Event[] = EventUtils.essentialEvents(events); + + await StorageUtils.storeObjectValue( + StorageKeysConstants.notifToggleEssentialEvents, + shouldScheduleEssentialEvents + ); + if (shouldScheduleEssentialEvents) { + void NotificationUtils.cancelScheduleEventsNotification(); + void NotificationUtils.scheduleEventsNotification(essentialEvents); + } + }, + [events] + ); + + const onCheckboxPressed = useCallback(() => { + const shouldScheduleEssentialEvents = !isCheckboxChecked; + setIsCheckboxChecked(shouldScheduleEssentialEvents); + + void scheduleEssentialEvents(shouldScheduleEssentialEvents); + setTrackerEventObject({ + action: TrackerUtils.TrackingEvent.NOTIFICATIONS_CENTER, + name: `${TrackerUtils.TrackingEvent.NOTIFICATIONS_CENTER} : ${NotificationType.event} essentiels`, + }); + }, [isCheckboxChecked, scheduleEssentialEvents]); + + useEffect(() => { + void initCheckboxState(); + }, [initCheckboxState]); + + return ( + <> + + + } + checkedIcon={ + + } + title={Labels.notification.essentialEvents} + accessibilityLabel={Labels.notification.essentialEvents} + checked={isCheckboxChecked} + onPress={onCheckboxPressed} + /> + + ); +}; + +const styles = StyleSheet.create({ + checkboxItem: { + backgroundColor: "transparent", + borderColor: "transparent", + marginStart: 0, + minHeight: Sizes.accessibilityMinButton, + paddingStart: 0, + }, +}); + +export default NotificationsEssentialEvents; diff --git a/front/src/components/notification/notificationsFrequency.component.tsx b/front/src/components/notification/notificationsFrequency.component.tsx index 78fe4c5e2..6ca5b35d8 100644 --- a/front/src/components/notification/notificationsFrequency.component.tsx +++ b/front/src/components/notification/notificationsFrequency.component.tsx @@ -32,7 +32,7 @@ const NotificationsFrequency: FC = ({ type }) => { setRadioValue(frequency); }, []); - const saveFraquency = useCallback( + const saveFrequency = useCallback( async (frequency: NotificationUtils.Frequencies) => { await StorageUtils.storeStringValue( StorageKeys.notifToggleMoodboardFrequency, @@ -52,13 +52,13 @@ const NotificationsFrequency: FC = ({ type }) => { const newValue = value as NotificationUtils.Frequencies; setRadioValue(newValue); - void saveFraquency(newValue); + void saveFrequency(newValue); setTrackerEventObject({ action: TrackerUtils.TrackingEvent.NOTIFICATIONS_CENTER, name: `${TrackerUtils.TrackingEvent.NOTIFICATIONS_CENTER} : ${type} & ${newValue}`, }); }, - [saveFraquency, type] + [saveFrequency, type] ); const radioButtonFrequency = ( diff --git a/front/src/constants/Labels.ts b/front/src/constants/Labels.ts index f901c215d..5dae7e271 100644 --- a/front/src/constants/Labels.ts +++ b/front/src/constants/Labels.ts @@ -594,6 +594,7 @@ export default { }, noData: "Aucunes données", notification: { + essentialEvents: "Que les événements essentiels", frequency: { onceADay: "1 fois par jour", question: "À quelle fréquence ?", diff --git a/front/src/constants/storageKeys.constants.ts b/front/src/constants/storageKeys.constants.ts index a1cfd59b4..008717924 100644 --- a/front/src/constants/storageKeys.constants.ts +++ b/front/src/constants/storageKeys.constants.ts @@ -22,6 +22,7 @@ export const notifToggleArticles = "@notifToggleArticles"; export const notifToggleMoodboard = "@notifToggleMoodboard"; export const notifToggleMoodboardFrequency = "@notifToggleMoodboardFrequency"; export const notifToggleEvents = "@notifToggleEvents"; +export const notifToggleEssentialEvents = "@notifToggleEssentialEvents"; export const eventsCalcFromBirthday = "@eventsCalcFromBirthday"; export const forceToScheduleEventsNotif = "@forceToScheduleEventsNotif"; export const osCalendarId = "@osCalendarId"; @@ -61,6 +62,7 @@ export const allStorageKeys = [ notifToggleMoodboard, notifToggleMoodboardFrequency, notifToggleEvents, + notifToggleEssentialEvents, eventsCalcFromBirthday, forceToScheduleEventsNotif, osCalendarId, diff --git a/front/src/utils/events/event.util.ts b/front/src/utils/events/event.util.ts index de43d7731..4907b3ad0 100644 --- a/front/src/utils/events/event.util.ts +++ b/front/src/utils/events/event.util.ts @@ -17,3 +17,8 @@ export const formattedEvents = ( })); else return []; }; + +export const essentialEvents = (events: Event[]): Event[] => + events.filter((event) => { + return event.important; + }); diff --git a/front/src/utils/events/events.util.test.ts b/front/src/utils/events/events.util.test.ts index db947ef1a..543dbac4a 100644 --- a/front/src/utils/events/events.util.test.ts +++ b/front/src/utils/events/events.util.test.ts @@ -1,41 +1,92 @@ import type { Event } from "../../types"; -import { formattedEvents } from "./event.util"; +import { EventUtils } from ".."; describe("Event utils", () => { - describe("formattedEvents function", () => { - const childBirthday = "2022-12-08"; - const event1: Event = { + const events: Event[] = [ + { debut: 0, fin: 8, id: 1, - nom: "événement", - }; + important: true, + nom: "événement1", + }, + { + debut: 0, + fin: 8, + id: 2, + important: false, + nom: "événement2", + }, + ]; + + describe("formattedEvents function", () => { + const childBirthday = "2022-12-08"; it("should get events formatted with no events", () => { - const result = formattedEvents([], childBirthday); + const result = EventUtils.formattedEvents([], childBirthday); const expected: Event[] = []; expect(result).toEqual(expected); }); it("should get events formatted witout childBirthday", () => { - // TODO: je renvoie an array vide, mais pas spur que ce soit la meilleure des solutions - const result = formattedEvents([event1], ""); + // TODO: je renvoie an array vide, mais pas sûr que ce soit la meilleure des solutions + const result = EventUtils.formattedEvents(events, ""); const expected: Event[] = []; expect(result).toEqual(expected); }); it("should get events formatted with childBirthday", () => { - const result = formattedEvents([event1], childBirthday); + const result = EventUtils.formattedEvents(events, childBirthday); const expected: Event[] = [ { date: childBirthday, debut: 0, fin: 8, id: 1, - nom: "événement", + important: true, + nom: "événement1", + }, + { + date: childBirthday, + debut: 0, + fin: 8, + id: 2, + important: false, + nom: "événement2", }, ]; expect(result).toEqual(expected); }); }); + + describe("essentialEvents", () => { + it("should return empty array when there are no events", () => { + expect(EventUtils.essentialEvents([])).toEqual([]); + }); + + it("should return empty array when there are no essential events", () => { + const noEssentialEvents: Event[] = [ + { + debut: 0, + fin: 8, + id: 2, + important: false, + nom: "événement2", + }, + ]; + expect(EventUtils.essentialEvents(noEssentialEvents)).toEqual([]); + }); + + it("should return essential events", () => { + expect(EventUtils.essentialEvents(events)).toEqual([ + { + debut: 0, + fin: 8, + id: 1, + important: true, + nom: "événement1", + }, + ]); + }); + }); });