diff --git a/api/src/controllers/test.js b/api/src/controllers/test.js index 338200f59..87bff5b5f 100644 --- a/api/src/controllers/test.js +++ b/api/src/controllers/test.js @@ -75,7 +75,7 @@ router.post( const userId = user.id; - const notif = await prisma.notification.create({ + await prisma.notification.create({ data: { user: { connect: { id: userId } }, type: type ? type : "DEFI1_DAY1", diff --git a/api/src/cronjobs.js b/api/src/cronjobs.js index 86822ef0d..39546dbc6 100644 --- a/api/src/cronjobs.js +++ b/api/src/cronjobs.js @@ -9,6 +9,7 @@ const { scheduleNotificationsNotFilledWeekCronJob, scheduleNotificationsInactivity10DaysCronJob, scheduleNotificationPlan, + scheduleNotificationsNotActivated3DaysCronJob, } = require("./utils/notifications"); const { reminderCronJob } = require("./controllers/reminder"); @@ -39,6 +40,11 @@ cron.schedule("0 0 4 * * 1 *", async () => { launchCronJob("schedule notifications not filled week", scheduleNotificationsNotFilledWeekCronJob); }); +cron.schedule("0 0 4 * * * *", async () => { + // every thursday at 4 am, find users with no lastConsoAdded and createdAt = 3 days ago and create a notification for tomorrow (4th day) + launchCronJob("schedule notifications not activated 3 days", scheduleNotificationsNotActivated3DaysCronJob); +}); + //every day at 19H59 launch the notification plan cron.schedule("59 19 * * *", async () => { launchCronJob("schedule notification plan", scheduleNotificationPlan); diff --git a/api/src/services/push-notifications.js b/api/src/services/push-notifications.js index 9bb3f1fea..162c8a5a1 100644 --- a/api/src/services/push-notifications.js +++ b/api/src/services/push-notifications.js @@ -65,6 +65,7 @@ const sendPushNotification = async ({ userId, matomoId, pushNotifToken, title, b await matomo.logEvent({ category: "PUSH_NOTIFICATION_SEND", action: "SENDING", + name: type || "", userId: matomoId, }); @@ -75,6 +76,7 @@ const sendPushNotification = async ({ userId, matomoId, pushNotifToken, title, b await matomo.logEvent({ category: "PUSH_NOTIFICATION_SEND", action: "SUCCESS", + name: type || "", userId: matomoId, }); } else if (results[0]?.failure) { @@ -116,6 +118,7 @@ const sendPushNotification = async ({ userId, matomoId, pushNotifToken, title, b await matomo.logEvent({ category: "PUSH_NOTIFICATION_SEND", action: "ERROR", + name: type || "", userId: matomoId, }); return { ok: false, error }; diff --git a/api/src/utils/notifications-catalog.js b/api/src/utils/notifications-catalog.js index a82dcfe4d..28ad93bcd 100644 --- a/api/src/utils/notifications-catalog.js +++ b/api/src/utils/notifications-catalog.js @@ -11,6 +11,12 @@ const NOTIFICATIONS_TYPES = { body: "Mettez toutes les chances de votre côté en remplissant vos consommations régulièrement 😊", link: "oz://APP/ADD_DRINK", }, + NOT_ACTIVATED_3_DAYS: { + type: "NOT_ACTIVATED_3_DAYS", + title: "Vous n'êtes pas resté longtemps", + body: "Nous aimerions savoir ce qui vous ferait rester sur Oz", + link: "oz://NOT_ACTIVATED_NPS_SCREEN", + }, INACTIVITY_10_DAYS: { type: "INACTIVITY_10_DAYS", title: "5 sec pour un dernier retour ?", diff --git a/api/src/utils/notifications.js b/api/src/utils/notifications.js index b2910fcbe..d3347368a 100644 --- a/api/src/utils/notifications.js +++ b/api/src/utils/notifications.js @@ -73,6 +73,58 @@ const saveInactivity5Days = async (userId) => { }, }); }; +const saveNotActivated3Days = async (userId) => { + const type = "NOT_ACTIVATED_3_DAYS"; + const notif = await prisma.notification.findFirst({ + where: { + userId, + type, + status: "NotSent", + }, + }); + if (notif) return; + + const reminder = await prisma.reminder.findUnique({ + where: { + userId, + }, + }); + if (reminder) return; + + await prisma.notification.create({ + data: { + user: { connect: { id: userId } }, + type, + date: dayjs().utc().add(14, "hour").startOf("minute").toDate(), + }, + }); +}; + +const scheduleNotificationsNotActivated3DaysCronJob = async () => { + try { + const users = await prisma.user.findMany({ + where: { + lastConsoAdded: { + //last conso added is null + equals: null, + }, + appVersion: { + gte: "313", + }, + createdAt: { + gte: dayjs().utc().subtract(3, "day").startOf("day").toDate(), + lte: dayjs().utc().subtract(3, "day").endOf("day").toDate(), + }, + }, + }); + + for (const { id } of users) { + await saveNotActivated3Days(id); + } + } catch (e) { + capture(e, { level: "error" }); + } +}; const scheduleNotificationsInactivity5DaysCronJob = async () => { try { @@ -111,12 +163,6 @@ const saveNotFilledWeek = async (userId) => { }); if (reminder?.type === "Daily") return; - const utcHour = dayjs().utc().hour(); - const hourInParis = dayjs().tz("Europe/Paris").hour(); - const timeDifference = hourInParis - utcHour; - const utcTimeHours = (!reminder?.disabled && reminder?.date?.utcTimeHours) || 18 - timeDifference; - const utcTimeMinutes = (!reminder?.disabled && reminder?.date?.utcTimeMinutes) || 0; - await prisma.notification.create({ data: { user: { connect: { id: userId } }, @@ -468,4 +514,5 @@ module.exports = { scheduleUserSurvey, scheduleNotificationsNotFilledWeekCronJob, scheduleNotificationPlan, + scheduleNotificationsNotActivated3DaysCronJob, }; diff --git a/expo/app.versions.json b/expo/app.versions.json index a7d27a680..ad87e52a0 100644 --- a/expo/app.versions.json +++ b/expo/app.versions.json @@ -1,4 +1,4 @@ { - "buildNumber": 312, - "buildName": "1.26.4" + "buildNumber": 313, + "buildName": "1.26.5" } diff --git a/expo/package.json b/expo/package.json index 40666ab8b..a402802e2 100644 --- a/expo/package.json +++ b/expo/package.json @@ -1,6 +1,6 @@ { "name": "oz-ensemble", - "version": "1.26.4", + "version": "1.26.5", "scripts": { "get-ip": "./get-ip.sh && echo \"this script updates the API IP to your own IP, because that's what Android Emulator needs to work. It's based on your wifi IP, if you need ethernet it won't work (needs en1 instead of en0)\"", "start": "expo start --dev-client", diff --git a/expo/src/Router.js b/expo/src/Router.js index 12296d55d..3fab5339f 100644 --- a/expo/src/Router.js +++ b/expo/src/Router.js @@ -49,6 +49,7 @@ import { isInCravingKeyState } from "./recoil/craving"; import { dayjsInstance } from "./services/dates"; import SuccessStrategyModal from "./scenes/Craving/SuccessStrategyModal"; import ExportedDataDone from "./scenes/Craving/ExportedDataDone"; +import Not_Activated_NPSScreen from "./scenes/NPS/not_activated_NPSScreen"; const Label = ({ children, focused, color }) => ( @@ -384,6 +385,14 @@ const Router = () => { headerShown: false, }} /> + { matomoId: storage.getString("@UserIdv2"), }, }).then((response) => { - if (response.ok) - Alert.alert( - "Suis-je bien localisé ?", - response.isWellLocated ? "Oui" : "Non" - ); + if (response.ok) Alert.alert("Suis-je bien localisé ?", response.isWellLocated ? "Oui" : "Non"); }); }} /> Effacer des données - storage.delete("@NPSDone")} - /> - deleteStorageValues(fakeOnboardingQuizz.good)} - /> + storage.delete("@NPSDone")} /> + deleteStorageValues(fakeOnboardingQuizz.good)} /> { @@ -93,41 +73,21 @@ const FakeData = () => { deleteStorageValues(fakeDefi5); }} /> - deleteStorageValues(fakeDefi1)} - /> - deleteStorageValues(fakeDefi2)} - /> - deleteStorageValues(fakeDefi3)} - /> - deleteStorageValues(fakeDefi4)} - /> - deleteStorageValues(fakeDefi5)} - /> + deleteStorageValues(fakeDefi1)} /> + deleteStorageValues(fakeDefi2)} /> + deleteStorageValues(fakeDefi3)} /> + deleteStorageValues(fakeDefi4)} /> + deleteStorageValues(fakeDefi5)} /> { - deleteStorageValues([ - "@NewFeaturesPopupIdsShown", - "NewFeaturesLastShownId", - ]); + deleteStorageValues(["@NewFeaturesPopupIdsShown", "NewFeaturesLastShownId"]); }} /> { - setGlobalDrinksState( - sortConsosByTimestamp(fakeConsoData.empty.drinks) - ); + setGlobalDrinksState(sortConsosByTimestamp(fakeConsoData.empty.drinks)); storage.delete("nps-asked-after-more-than-3-consos"); }} /> @@ -141,9 +101,7 @@ const FakeData = () => { { - setGlobalDrinksState( - sortConsosByTimestamp(fakeConsoData.empty.drinks) - ); + setGlobalDrinksState(sortConsosByTimestamp(fakeConsoData.empty.drinks)); storage.delete("nps-asked-after-more-than-3-consos"); deleteStorageValues(fakeDefi1); }} @@ -158,17 +116,12 @@ const FakeData = () => { replaceStorageValues(fakeDefi5); replaceStorageValues(fakeOnboardingQuizz.risk); replaceStorageValues(fakeGain); - setGlobalDrinksState( - sortConsosByTimestamp(fakeConsoData.full.drinks) - ); + setGlobalDrinksState(sortConsosByTimestamp(fakeConsoData.full.drinks)); }} /> Simuler un badge {badgesCatalog - .reduce( - (allBadges, category) => [...allBadges, ...category.badges], - [] - ) + .reduce((allBadges, category) => [...allBadges, ...category.badges], []) .map(({ title, category, stars }) => { return ( @@ -187,12 +140,8 @@ const FakeData = () => { - API.get({ path: "/badge/test", query: { category, stars } }) - } + caption={category.includes("locked") ? `LOCKED ${title}` : title} + onPress={() => API.get({ path: "/badge/test", query: { category, stars } })} /> ); @@ -208,10 +157,7 @@ const FakeData = () => { title: "Vos retours sont importants pour nous", message: "Avez-vous quelques secondes pour donner votre avis ?", }); - storage.set( - "@NPSNotificationDate", - Math.round(NPSNotificationDate.getTime() / 1000) * 1000 - ); + storage.set("@NPSNotificationDate", Math.round(NPSNotificationDate.getTime() / 1000) * 1000); }} /> { }); }} /> + { + API.post({ + path: "/test/test-notif", + body: { + matomoId: storage.getString("@UserIdv2"), + type: "NOT_ACTIVATED_3_DAYS", + date: new Date(Date.now() + 70000), + }, + }); + }} + /> + { + API.post({ + path: "/test/test-notif", + body: { + matomoId: storage.getString("@UserIdv2"), + type: "USER_SURVEY", + date: new Date(Date.now() + 70000), + }, + }); + }} + /> + { + API.post({ + path: "/test/test-notif", + body: { + matomoId: storage.getString("@UserIdv2"), + type: "DEFI1_DAY1", + date: new Date(Date.now() + 70000), + }, + }); + }} + /> { caption="A la prochaine sortie de Craving afficher la modale nps" onPress={() => { storage.set("@CravingToNpsModal", false); - storage.set( - "@firstTimeCraving", - dayjs().subtract(7, "day").format("YYYY-MM-DD") - ); + storage.set("@firstTimeCraving", dayjs().subtract(7, "day").format("YYYY-MM-DD")); }} /> Ma consommation d'alcool - replaceStorageValues(fakeOnboardingQuizz.good)} - /> - replaceStorageValues(fakeOnboardingQuizz.risk)} - /> - replaceStorageValues(fakeOnboardingQuizz.addicted)} - /> + replaceStorageValues(fakeOnboardingQuizz.good)} /> + replaceStorageValues(fakeOnboardingQuizz.risk)} /> + replaceStorageValues(fakeOnboardingQuizz.addicted)} /> Objectif - replaceStorageValues(fakeGain)} - /> + replaceStorageValues(fakeGain)} /> { setDaysWithGoalNoDrink(["wednesday", "thursday"]); - setDrinksByWeek([ - { drinkKey: "beer-half", quantity: 7, id: uuid() }, - ]); + setDrinksByWeek([{ drinkKey: "beer-half", quantity: 7, id: uuid() }]); const matomoId = storage.getString("@UserIdv2"); API.post({ path: "/goal", @@ -342,10 +313,7 @@ const FakeData = () => { daysWithGoalNoDrink: ["wednesday", "thursday"], dosesByDrinkingDay: 7, dosesPerWeek: 35, - forceDate: dayjs() - .startOf("week") - .subtract(7, "day") - .format("YYYY-MM-DD"), + forceDate: dayjs().startOf("week").subtract(7, "day").format("YYYY-MM-DD"), }, }).then((res) => { if (res.ok) { @@ -366,60 +334,37 @@ const FakeData = () => { replaceStorageValues(fakeDefi5); }} /> - replaceStorageValues(fakeDefi1)} - /> - replaceStorageValues(fakeDefi2)} - /> - replaceStorageValues(fakeDefi3)} - /> - replaceStorageValues(fakeDefi4)} - /> - replaceStorageValues(fakeDefi5)} - /> + replaceStorageValues(fakeDefi1)} /> + replaceStorageValues(fakeDefi2)} /> + replaceStorageValues(fakeDefi3)} /> + replaceStorageValues(fakeDefi4)} /> + replaceStorageValues(fakeDefi5)} /> Consommations { - setGlobalDrinksState( - sortConsosByTimestamp(fakeConsoData.long(700).drinks) - ); + setGlobalDrinksState(sortConsosByTimestamp(fakeConsoData.long(700).drinks)); storage.delete("nps-asked-after-more-than-3-consos"); }} /> { - setGlobalDrinksState( - sortConsosByTimestamp(fakeConsoData.full.drinks) - ); + setGlobalDrinksState(sortConsosByTimestamp(fakeConsoData.full.drinks)); storage.delete("nps-asked-after-more-than-3-consos"); }} /> { - setGlobalDrinksState( - sortConsosByTimestamp(fakeConsoData.partial.drinks) - ); + setGlobalDrinksState(sortConsosByTimestamp(fakeConsoData.partial.drinks)); storage.delete("nps-asked-after-more-than-3-consos"); }} /> { - setGlobalDrinksState( - sortConsosByTimestamp(fakeConsoData.onlyBelow.drinks) - ); + setGlobalDrinksState(sortConsosByTimestamp(fakeConsoData.onlyBelow.drinks)); storage.delete("nps-asked-after-more-than-3-consos"); }} /> @@ -480,14 +425,8 @@ const FakeData = () => { }} /> Effacer des données - storage.delete("@NPSDone")} - /> - deleteStorageValues(fakeOnboardingQuizz.good)} - /> + storage.delete("@NPSDone")} /> + deleteStorageValues(fakeOnboardingQuizz.good)} /> { @@ -498,41 +437,21 @@ const FakeData = () => { deleteStorageValues(fakeDefi5); }} /> - deleteStorageValues(fakeDefi1)} - /> - deleteStorageValues(fakeDefi2)} - /> - deleteStorageValues(fakeDefi3)} - /> - deleteStorageValues(fakeDefi4)} - /> - deleteStorageValues(fakeDefi5)} - /> + deleteStorageValues(fakeDefi1)} /> + deleteStorageValues(fakeDefi2)} /> + deleteStorageValues(fakeDefi3)} /> + deleteStorageValues(fakeDefi4)} /> + deleteStorageValues(fakeDefi5)} /> { - deleteStorageValues([ - "@NewFeaturesPopupIdsShown", - "NewFeaturesLastShownId", - ]); + deleteStorageValues(["@NewFeaturesPopupIdsShown", "NewFeaturesLastShownId"]); }} /> { - setGlobalDrinksState( - sortConsosByTimestamp(fakeConsoData.empty.drinks) - ); + setGlobalDrinksState(sortConsosByTimestamp(fakeConsoData.empty.drinks)); storage.delete("nps-asked-after-more-than-3-consos"); }} /> diff --git a/expo/src/scenes/NPS/Inactivity_NPSScreen.js b/expo/src/scenes/NPS/Inactivity_NPSScreen.js index ce63b953d..3fad64871 100644 --- a/expo/src/scenes/NPS/Inactivity_NPSScreen.js +++ b/expo/src/scenes/NPS/Inactivity_NPSScreen.js @@ -1,13 +1,12 @@ -import React, { useRef, useEffect, useState } from 'react'; -import { Platform, Text, View, KeyboardAvoidingView, TextInput, ScrollView, TouchableOpacity } from 'react-native'; -import { SafeAreaProvider } from 'react-native-safe-area-context'; -import pck from '../../../package.json'; -import Background from '../../components/Background'; -import ButtonPrimary from '../../components/ButtonPrimary'; -import { logEvent } from '../../services/logEventsWithMatomo'; -import { storage } from '../../services/storage'; -import BackButton from '../../components/BackButton'; -import { sendMail } from '../../services/mail'; +import React, { useRef, useEffect, useState } from "react"; +import { Platform, Text, View, KeyboardAvoidingView, TextInput, ScrollView, TouchableOpacity } from "react-native"; +import { SafeAreaProvider } from "react-native-safe-area-context"; +import pck from "../../../package.json"; +import Background from "../../components/Background"; +import ButtonPrimary from "../../components/ButtonPrimary"; +import { logEvent } from "../../services/logEventsWithMatomo"; +import { storage } from "../../services/storage"; +import { sendMail } from "../../services/mail"; const formatText = (answer, feedback, userId) => ` @@ -20,19 +19,19 @@ Qu'est-ce qui vous aurait fait rester ? : ${feedback} const Inactivity_NPSScreen = ({ navigation }) => { const [selectedAnswerKey, setSelectedAnswerKey] = useState(null); - const [feedback, setFeedback] = useState(''); - const [sendButton, setSendButton] = useState('Envoyer'); + const [feedback, setFeedback] = useState(""); + const [sendButton, setSendButton] = useState("Envoyer"); const answers = [ - { answerKey: 'OZ_HELPED', content: "Oz m'a aidé mais je n'en ai plus besoin", score: 0 }, - { answerKey: 'LAKE_FEATURES', content: 'Il manque des fonctionnalités', score: 1 }, - { answerKey: 'USING_OTHER_APP', content: 'Je préfère une autre application', score: 2 }, - { answerKey: 'OTHER', content: 'Autre', score: 3 }, + { answerKey: "OZ_HELPED", content: "Oz m'a aidé mais je n'en ai plus besoin", score: 0 }, + { answerKey: "LAKE_FEATURES", content: "Il manque des fonctionnalités", score: 1 }, + { answerKey: "USING_OTHER_APP", content: "Je préfère une autre application", score: 2 }, + { answerKey: "OTHER", content: "Autre", score: 3 }, ]; useEffect(() => { logEvent({ - category: 'INACTIVITY_NPS', - action: 'INACTIVITY_NPS_OPEN', + category: "INACTIVITY_NPS", + action: "INACTIVITY_NPS_OPEN", }); }, []); const onGoBackRequested = async () => { @@ -50,7 +49,7 @@ const Inactivity_NPSScreen = ({ navigation }) => { }; useEffect(() => { - const beforeRemoveListenerUnsbscribe = navigation.addListener('beforeRemove', handleBeforeRemove); + const beforeRemoveListenerUnsbscribe = navigation.addListener("beforeRemove", handleBeforeRemove); return () => { beforeRemoveListenerUnsbscribe(); }; @@ -60,23 +59,23 @@ const Inactivity_NPSScreen = ({ navigation }) => { const npsSent = useRef(false); const sendNPS = async () => { if (npsSent.current) return; - const userId = storage.getString('@UserIdv2'); - setSendButton('Merci !'); + const userId = storage.getString("@UserIdv2"); + setSendButton("Merci !"); logEvent({ - category: 'INACTIVITY_NPS', - action: 'INACTIVITY_NPS_SEND_ANSWER', + category: "INACTIVITY_NPS", + action: "INACTIVITY_NPS_SEND_ANSWER", value: answers.find(({ answerKey }) => answerKey === selectedAnswerKey)?.score, }); if (feedback) { logEvent({ - category: 'INACTIVITY_NPS', - action: 'INACTIVITY_NPS_SEND_FEEDBACK', + category: "INACTIVITY_NPS", + action: "INACTIVITY_NPS_SEND_FEEDBACK", }); } await sendMail({ - subject: 'Inactivity 10 days NPS Addicto', + subject: "Inactivity 10 days NPS Addicto", text: formatText(answers.find(({ answerKey }) => answerKey === selectedAnswerKey)?.content, feedback, userId), - }).catch((err) => console.log('sendNPS err', err)); + }).catch((err) => console.log("sendNPS err", err)); npsSent.current = true; navigation.goBack(); @@ -88,14 +87,15 @@ const Inactivity_NPSScreen = ({ navigation }) => { + behavior={Platform.select({ ios: "padding", android: null })} + keyboardVerticalOffset={Platform.select({ ios: 50, android: 250 })} + > - + keyboardDismissMode="none" + > Dites nous pourquoi vous êtes partis, ça nous aidera à améliorer l’application @@ -108,20 +108,22 @@ const Inactivity_NPSScreen = ({ navigation }) => { {answers.map(({ answerKey, content }, i) => ( { setSelectedAnswerKey(answerKey); - }}> + }} + > + className={["font-medium", answerKey === selectedAnswerKey ? "text-white" : "text-black"].join( + " " + )} + > {content} diff --git a/expo/src/scenes/NPS/not_activated_NPSScreen.js b/expo/src/scenes/NPS/not_activated_NPSScreen.js new file mode 100644 index 000000000..e3a0b2801 --- /dev/null +++ b/expo/src/scenes/NPS/not_activated_NPSScreen.js @@ -0,0 +1,192 @@ +import React, { useRef, useEffect, useState } from "react"; +import { Platform, Text, View, KeyboardAvoidingView, TextInput, ScrollView, TouchableOpacity } from "react-native"; +import { SafeAreaProvider } from "react-native-safe-area-context"; +import pck from "../../../package.json"; +import Background from "../../components/Background"; +import ButtonPrimary from "../../components/ButtonPrimary"; +import { logEvent } from "../../services/logEventsWithMatomo"; +import { storage } from "../../services/storage"; +import { sendMail } from "../../services/mail"; + +const formatText = (answer, feedback, userId, contact) => + ` +userId: ${userId} +Version: ${pck.version} +OS: ${Platform.OS} +Pourquoi n'utilisez-vous plus Oz ? : ${answer} +Qu'est-ce qui vous aurait fait rester ? : ${feedback} +Contact: ${contact} +`; + +const Not_Activated_NPSScreen = ({ navigation }) => { + const [selectedAnswerKey, setSelectedAnswerKey] = useState(null); + const [feedback, setFeedback] = useState(""); + const [sendButton, setSendButton] = useState("Envoyer"); + const [contact, setContact] = useState(""); + + const answers = [ + { answerKey: "NOT_WHAT_I_AM_LOOKING_FOR", content: "Oz n'est pas ce que je recherche", score: 0 }, + { answerKey: "LAKE_FEATURES", content: "Il manque des fonctionnalités", score: 1 }, + { answerKey: "USING_OTHER_APP", content: "Je préfère une autre application", score: 2 }, + { answerKey: "CHANGED_MY_MIND", content: "Je ne veux plus maîtriser ma consommation", score: 3 }, + { answerKey: "OTHER", content: "Autre", score: 4 }, + ]; + + useEffect(() => { + logEvent({ + category: "NOT_ACTIVATED_NPS", + action: "NOT_ACTIVATED_NPS_OPEN", + }); + }, []); + const onGoBackRequested = async () => { + backRequestHandledRef.current = true; + if (npsSent.current) return navigation.goBack(); + if (selectedAnswerKey !== null) await sendNPS(); + navigation.goBack(); + }; + + const backRequestHandledRef = useRef(null); + const handleBeforeRemove = (e) => { + if (backRequestHandledRef.current === true) return; + e.preventDefault(); + onGoBackRequested(); + }; + + useEffect(() => { + const beforeRemoveListenerUnsbscribe = navigation.addListener("beforeRemove", handleBeforeRemove); + return () => { + beforeRemoveListenerUnsbscribe(); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const npsSent = useRef(false); + const sendNPS = async () => { + if (npsSent.current) return; + const userId = storage.getString("@UserIdv2"); + setSendButton("Merci !"); + logEvent({ + category: "NOT_ACTIVATED_NPS", + action: "NOT_ACTIVATED_NPS_SEND_ANSWER", + value: answers.find(({ answerKey }) => answerKey === selectedAnswerKey)?.score, + }); + if (feedback) { + logEvent({ + category: "NOT_ACTIVATED_NPS", + action: "NOT_ACTIVATED_NPS_SEND_FEEDBACK", + }); + } + console.log( + "sendNPS", + formatText(answers.find(({ answerKey }) => answerKey === selectedAnswerKey)?.content, feedback, userId, contact) + ); + await sendMail({ + subject: "Not Activated 3 days NPS Addicto", + text: formatText( + answers.find(({ answerKey }) => answerKey === selectedAnswerKey)?.content, + feedback, + userId, + contact + ), + }).catch((err) => console.log("sendNPS err", err)); + + npsSent.current = true; + navigation.goBack(); + }; + + return ( + + + + + + + + Dites nous pourquoi vous n'êtes pas resté pour nous aider à améliorer l'application + + + + + Pourquoi ne pas avoir plus exploré l'application ? + + + + {answers.map(({ answerKey, content }, i) => ( + { + setSelectedAnswerKey(answerKey); + }} + > + + {content} + + + ))} + + + Qu'est-ce qui vous aurait fait rester ? + + + + + Échanger avec vous serait précieux pour améliorer notre service, laissez-nous votre numéro de + téléphone ou votre mail si vous le souhaitez. + + + StatusBar.setHidden(false, 'none')} + /> + + + + + + + + + ); +}; + +export default Not_Activated_NPSScreen; diff --git a/expo/src/services/deepLink.js b/expo/src/services/deepLink.js index feb986e2c..36cfaa7aa 100644 --- a/expo/src/services/deepLink.js +++ b/expo/src/services/deepLink.js @@ -9,6 +9,7 @@ export const deepLinkingConfig = { USER_SURVEY_START: "USER_SURVEY_START", USER_SURVEY_NOTIF: "USER_SURVEY_NOTIF", INACTIVITY_NPS_SCREEN: "INACTIVITY_NPS_SCREEN", + NOT_ACTIVATED_NPS_SCREEN: "NOT_ACTIVATED_NPS_SCREEN", APP: { screens: { ADD_DRINK: "ADD_DRINK",