diff --git a/app/assets/svg/icon/ArrowUp.tsx b/app/assets/svg/icon/ArrowUp.tsx new file mode 100644 index 00000000..9a2def9a --- /dev/null +++ b/app/assets/svg/icon/ArrowUp.tsx @@ -0,0 +1,20 @@ +import { ViewStyle } from "react-native"; +import Svg, { Path } from "react-native-svg"; + +export default function ArrowUpSvg({ + color, + style, + width = 20, + height = 20, +}: { + color?: string; + style?: ViewStyle; + width?: number; + height?: number; +}) { + return ( + + + + ); +} diff --git a/app/assets/svg/icon/Calendar.tsx b/app/assets/svg/icon/Calendar.tsx new file mode 100644 index 00000000..56ada1c4 --- /dev/null +++ b/app/assets/svg/icon/Calendar.tsx @@ -0,0 +1,15 @@ +import Svg, { Path } from "react-native-svg"; + +export default function CalendarIcon(props) { + return ( + + + + ); +} diff --git a/app/assets/svg/icon/TrendUp.tsx b/app/assets/svg/icon/TrendUp.tsx new file mode 100644 index 00000000..1705d8fe --- /dev/null +++ b/app/assets/svg/icon/TrendUp.tsx @@ -0,0 +1,15 @@ +import Svg, { Path } from "react-native-svg"; + +export default function TrendUpIcon(props) { + return ( + + + + ); +} diff --git a/app/package.json b/app/package.json index 7c153ecd..755c8fec 100644 --- a/app/package.json +++ b/app/package.json @@ -83,6 +83,7 @@ "react-native-keyboard-controller": "^1.17.5", "react-native-linear-gradient": "^2.6.2", "react-native-localize": "^2.2.4", + "react-native-markdown-display": "^7.0.2", "react-native-modal": "^13.0.1", "react-native-modal-datetime-picker": "^18.0.0", "react-native-multiple-select": "^0.5.12", diff --git a/app/src/components/Accordion.tsx b/app/src/components/Accordion.tsx new file mode 100644 index 00000000..a0c3dacb --- /dev/null +++ b/app/src/components/Accordion.tsx @@ -0,0 +1,156 @@ +import React, { useState } from "react"; +import { View, Text, TouchableOpacity, LayoutAnimation, Platform, UIManager } from "react-native"; +import Markdown from "react-native-markdown-display"; +import ArrowUpSvg from "../../assets/svg/icon/ArrowUp"; +import { mergeClassNames } from "@/utils/className"; +import { typography } from "@/utils/typography"; +import { TW_COLORS } from "@/utils/constants"; + +// Enable LayoutAnimation on Android +if (Platform.OS === "android" && UIManager.setLayoutAnimationEnabledExperimental) { + UIManager.setLayoutAnimationEnabledExperimental(true); +} + +export interface AccordionItem { + title: string; + description: string; // Markdown content +} + +interface AccordionProps { + items: AccordionItem[]; +} + +interface AccordionItemComponentProps { + item: AccordionItem; + isExpanded: boolean; + showDivider?: boolean; + onToggle: () => void; +} + +const AccordionItemComponent: React.FC = ({ item, isExpanded, onToggle, showDivider }) => { + const handleToggle = () => { + LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); + onToggle(); + }; + + const markdownStyles = { + body: { + fontSize: 16, + lineHeight: 24, + color: TW_COLORS.CNAM_PRIMARY_800, + fontFamily: "SourceSans3", + }, + heading1: { + fontSize: 24, + lineHeight: 32, + fontWeight: "700" as const, + color: TW_COLORS.CNAM_PRIMARY_800, + marginBottom: 12, + fontFamily: "SourceSans3", + }, + heading2: { + fontSize: 20, + lineHeight: 30, + fontWeight: "700" as const, + color: TW_COLORS.CNAM_PRIMARY_800, + marginBottom: 8, + fontFamily: "SourceSans3", + }, + heading3: { + fontSize: 18, + lineHeight: 26, + fontWeight: "700" as const, + color: TW_COLORS.CNAM_PRIMARY_800, + marginBottom: 6, + fontFamily: "SourceSans3", + }, + paragraph: { + fontSize: 16, + lineHeight: 24, + color: TW_COLORS.CNAM_PRIMARY_800, + marginBottom: 8, + fontFamily: "SourceSans3", + }, + strong: { + fontWeight: "600" as const, + color: TW_COLORS.CNAM_PRIMARY_800, + }, + list_item: { + fontSize: 16, + lineHeight: 24, + color: "#3D6874", + marginBottom: 4, + fontFamily: "SourceSans3", + }, + bullet_list: { + marginBottom: 8, + }, + ordered_list: { + marginBottom: 8, + }, + }; + + return ( + + + {item.title} + + + + + + {isExpanded && ( + + + {item.description} + + + )} + {showDivider && } + + ); +}; + +export const Accordion: React.FC = ({ items }) => { + const [expandedItems, setExpandedItems] = useState>(new Set()); + + const toggleItem = (index: number) => { + const newExpandedItems = new Set(expandedItems); + if (newExpandedItems.has(index)) { + newExpandedItems.delete(index); + } else { + newExpandedItems.add(index); + } + setExpandedItems(newExpandedItems); + }; + + return ( + + {items.map((item, index) => ( + toggleItem(index)} + /> + ))} + + ); +}; + +export default Accordion; diff --git a/app/src/components/ListItem/NavigationListItem.tsx b/app/src/components/ListItem/NavigationListItem.tsx new file mode 100644 index 00000000..b14ae6ce --- /dev/null +++ b/app/src/components/ListItem/NavigationListItem.tsx @@ -0,0 +1,50 @@ +import { mergeClassNames } from "@/utils/className"; +import { TW_COLORS } from "@/utils/constants"; +import { typography } from "@/utils/typography"; +import ArrowIcon from "@assets/svg/icon/Arrow"; +import CheckMarkIcon from "@assets/svg/icon/check"; +import React from "react"; +import { TouchableOpacity, View, Text } from "react-native"; + +interface NavigationListItemProps { + disabled?: false; + icon: JSX.Element; + label: string; + onPress: () => any; +} + +export default function NavigationListItem({ disabled, onPress, icon, label }: NavigationListItemProps) { + return ( + + {/* Left Icon */} + + {React.cloneElement(icon, { + color: disabled ? TW_COLORS.SUCCESS.TEXT : TW_COLORS.CNAM_PRIMARY_800, + width: 16, + height: 16, + })} + + + {/* Text */} + + {label} + + + {/* Right Arrow */} + {disabled ? : } + + ); +} diff --git a/app/src/components/drawer/index.tsx b/app/src/components/drawer/index.tsx index e74d58f9..af9c4c04 100644 --- a/app/src/components/drawer/index.tsx +++ b/app/src/components/drawer/index.tsx @@ -106,7 +106,7 @@ export default ({ navigation, visible, onClick }) => { Jardin Mental } /> - } /> + } /> } /> } /> } /> diff --git a/app/src/navigation/router.tsx b/app/src/navigation/router.tsx index 307759f6..fc63b48c 100644 --- a/app/src/navigation/router.tsx +++ b/app/src/navigation/router.tsx @@ -73,6 +73,8 @@ import { StatusBarProvider, useStatusBarInternal } from "../context/StatusBarCon import { TW_COLORS } from "@/utils/constants"; import SurveyV1 from "../scenes/survey/daySurvey"; import SurveySuccessScreen from "../scenes/survey/SurveySuccessScreen"; +import FaqMainScreen from "@/scenes/faq/FaqMainScreen"; +import FaqDetailScreen from "@/scenes/faq/FaqDetailScreen"; const Stack = createStackNavigator(); @@ -219,6 +221,8 @@ class Router extends React.Component { }} > + + diff --git a/app/src/scenes/faq/FaqData.tsx b/app/src/scenes/faq/FaqData.tsx new file mode 100644 index 00000000..1db0b9a3 --- /dev/null +++ b/app/src/scenes/faq/FaqData.tsx @@ -0,0 +1,166 @@ +import CalendarIcon from "@assets/svg/icon/Calendar"; +import Goal from "@assets/svg/icon/Goal"; +import HealthIcon from "@assets/svg/icon/Health"; +import ShareIcon from "@assets/svg/icon/Share"; +import TrendUpIcon from "@assets/svg/icon/TrendUp"; +import Pencil from "@assets/svg/Pencil"; + +type FaqSlug = "indicateurs" | "objectifs" | "questionnaire" | "analyse" | "traitement" | "données"; +interface FaqDataEntry { + icon: JSX.Element; + title: string; + subtitle?: string; + description: string; + exemple?: string; + accordion: { + title: string; + description: string; + }[]; + next: FaqSlug; +} + +export const FAQ_DATA: Record = { + indicateurs: { + icon: , + title: "Définir mes indicateurs", + subtitle: `Qu'est-ce qu'un indicateur ?`, + description: `Un indicateur est un repère sur l'état de votre santé mentale. Cela peut être une émotion, un symptôme ou un comportement. + \nSuivre leur évolution vous permettra de mieux comprendre ce que vous traversez et d'identifier ce qui influence vos hauts et vos bas.`, + exemple: `_**_Par exemple_** : si vous dormez mal, vous pourriez suivre la « qualité de votre sommeil » et le « nombre de réveils nocturnes »._`, + accordion: [ + { + title: "Comment les choisir ?", + description: `Concentrez-vous sur les indicateurs qui ont eu un impact sur votre bien-être **ces dernières semaines**. + \nNous vous conseillons de ne pas choisir plus de 9 indicateurs. Vous serez plus régulier dans votre suivi et cela vous sera plus utile pour comprendre votre fonctionnement !`, + }, + { + title: `Comment les paramétrer ?`, + description: `Vous pouvez accéder aux paramètres de vos indicateurs soit lorsque vous remplissez votre questionnaire quotidien, soit depuis les *Paramètres généraux* (⚙️ en haut à droite) en cliquant sur « *Personnaliser mes indicateurs* » : +- Pour **modifier vos indicateurs existants** : cliquez sur « *Modifier mon questionnaire* ». Vous pourrez alors supprimer vos indicateurs en cliquant sur la corbeille 🗑️ . +- Pour **créer un nouvel indicateur** : cliquez sur le bouton « Ajouter un nouvel indicateur ». Vous pourrez alors définir le nom de votre indicateur et choisir son échelle d'évaluation. Vous pouvez vous inspirer des exemples proposés ou réactiver un indicateur archivé.`, + }, + ], + next: "objectifs", + }, + objectifs: { + icon: , + title: "Définir mes objectifs", + subtitle: `Qu'est-ce qu'un objectif ?`, + description: `Un objectif est un petit défi que vous souhaitez réaliser régulièrement pour améliorer ou stabiliser votre bien-être. Cela peut être une activité comme marcher 30 minutes par jour, faire un exercice de respiration ou encore une habitude de soin comme prendre son traitement.`, + accordion: [ + { + title: "Comment les choisir ?", + description: `Commencez par 1 ou 2 objectifs seulement et fixez-vous des objectifs réalistes. C'est beaucoup plus motivant de cocher régulièrement ses réussites que de se décourager avec des objectifs inatteignables ! Vous pouvez aussi ajuster leur fréquence : un objectif peut être quotidien, mais aussi 2 fois par semaine ou seulement le week-end, selon ce qui vous convient. +\nLeur but est de vous aider à progresser pas à pas, pas de bousculer toutes vos habitudes d'un coup 😊`, + }, + { + title: `Comment les paramétrer ?`, + description: `Vous pouvez accéder aux paramètres de vos objectifs soit lorsque vous remplissez votre questionnaire quotidien, soit depuis les *Paramètres généraux* (⚙️ en haut à droite) en cliquant sur « *Personnaliser mes objectifs* » : +- Pour **créer un nouvel objectif** : cliquez sur le bouton « Ajouter un objectif ». Vous pourrez alors définir le nom de votre objectif. Vous pouvez vous inspirer des exemples proposés ou réactiver un objectif archivé. +- Pour **modifier vos objectifs existants** : + - Si vous souhaitez modifier la récurrence d'un objectif existant ou activer / éteindre les rappels, cliquez sur l'icône du stylo 🖊️ à côté de l'objectif en question. + - Si vous souhaitez supprimer un objectif existant, cliquez sur l'icône du stylo 🖊️ à côté de l'objectif en question puis sur le bouton "Désactiver mon objectif"`, + }, + ], + next: "questionnaire", + }, + questionnaire: { + icon: , + title: "Faire mon suivi quotidien", + description: `Chaque jour, prenez quelques minutes pour faire le point sur votre santé mentale.`, + accordion: [ + { + title: "Comment remplir mon questionnaire ?", + description: `Pour cela, rendez-vous dans l'onglet « Mes Entrées » et cliquez sur « Renseigner mon état pour ce jour-là ».`, + }, + { + title: `Que puis-je renseigner chaque jour ?`, + description: `Vous pourrez : + +- évaluer vos indicateurs ; +- cocher les objectifs atteints ; +- ajouter une note pour préciser un événement marquant ; +- indiquer si vous avez consommé des substances ; +- confirmer la prise de votre traitement (si vous en avez renseigné un) ; +- noter une prise de médicament "si besoin". +`, + }, + { + title: `Jusqu'à combien de jours en arrière puis-je compléter ?`, + description: `Vous pouvez remplir ou compléter votre questionnaire jusqu'à **7 jours en arrière**. Passé ce délai, il ne sera plus possible de le faire car les souvenirs deviennent moins fiables et risquent de fausser vos données. + +👉 **La régularité est essentielle** : plus vous prenez l'habitude de remplir votre questionnaire chaque jour, plus vous aurez une vision claire de ce qui influence votre état — que ce soit positivement ou négativement.`, + }, + ], + next: "analyse", + }, + analyse: { + title: "Comprendre mes analyses", + icon: , + description: `Cette section rassemble les données que vous saisissez chaque jour et les met en perspective. Cela vous permet de suivre l’évolution de votre état et d’identifier les facteurs qui influencent votre bien-être.`, + accordion: [ + { + title: "Comment lire mes frises ?", + description: `Les frises montrent l’évolution de vos indicateurs sur une période donnée. Elles permettent de repérer les variations dans le temps.`, + }, + { + title: `Comment lire mes statistiques ?`, + description: `Les statistiques donnent un bilan global de vos indicateurs sur une période donnée. +Elles ne suivent pas l’évolution de vos indicateur sjour après jour mais offrent une vue d’ensemble de votre état. +Vous y trouverez aussi le taux de réussite de vos objectifs.`, + }, + { + title: `Comment lire mes courbes ?`, + description: `Les courbes affichent l’évolution de vos indicateurs, jour après jour, semaine par semaine. +En cliquant sur un point, vous pouvez retrouver le contexte d’une journée précise.`, + }, + { + title: `Comment lire mes déclencheurs ?`, + description: `Les déclencheurs affichent, pour l’indicateur et l’intensité choisis, les notes que vous avez écrites dans vos questionnaires quotidiens. +Ils vous aident à repérer les situations ou facteurs qui influencent vos indicateurs.`, + }, + ], + next: "traitement", + }, + traitement: { + icon: , + title: "Renseigner mon traitement", + description: `Jardin Mental vous permet de suivre la prise de votre traitement si votre professionnel de santé vous en a prescrit un.`, + accordion: [ + { + title: "Comment ajouter mon traitement ?", + description: `Pour renseigner votre traitement, allez dans les *Paramètres généraux* (⚙️ en haut à droite) puis cliquez sur *« Saisir mon traitement »*. Vous pourrez alors ajouter votre traitement en sélectionnant dans la liste le nom de votre médicament, ou en ajouter un. +Un rappel apparaîtra dans votre questionnaire quotidien.`, + }, + { + title: `Puis-je créer un traitement qui n'est pas dans la liste ?`, + description: `Si vous ne trouvez pas votre traitement dans la liste, vous pouvez créer une nouvelle entrée en cliquant sur le symbole ➕. `, + }, + ], + next: "données", + }, + données: { + title: "Gérer mes données", + description: `Cette section répond à vos questions sur le récapitulatif de vos données et son utilisation.`, + accordion: [ + { + title: "Qui peut voir mes données ?", + description: `Les informations personnelles que vous saisissez dans Jardin Mental restent enregistrées uniquement sur votre appareil. Elles ne sont ni partagées ni accessibles à des tiers. +Seules des données anonymisées sur la fréquence d’utilisation de l’application sont recueillies par notre équipe afin d’améliorer continuellement Jardin Mental.`, + }, + { + title: "À quoi sert la génération de récapitulatif de mes données ?", + description: `Si vous êtes suivi·e par un·e professionnel·le de santé, vous pouvez si vous le souhaitez lui partager vos données. + Ces informations lui permettront d'avoir une vue d'ensemble de votre état entre vos consultations et l'aideront à adapter son accompagnement et / ou votre traitement en conséquence.`, + }, + { + title: `Comment générer un récapitulatif de mes données ?`, + description: `- Rendez-vous dans les *Paramètres généraux* (⚙️ en haut à droite) ; +- Cliquez sur « *Générer un récapitulatif de mes données* » ; +- Vous pourrez alors télécharger le fichier au format PDF.`, + }, + ], + icon: , + next: "indicateurs", + }, +}; diff --git a/app/src/scenes/faq/FaqDetailScreen.tsx b/app/src/scenes/faq/FaqDetailScreen.tsx new file mode 100644 index 00000000..a269bb6c --- /dev/null +++ b/app/src/scenes/faq/FaqDetailScreen.tsx @@ -0,0 +1,140 @@ +import { mergeClassNames } from "@/utils/className"; +import { typography } from "@/utils/typography"; +import React from "react"; +import { Text, View, ViewStyle, StyleSheet } from "react-native"; +import { AnimatedHeaderScrollScreen } from "../survey-v2/AnimatedHeaderScrollScreen"; +import { TW_COLORS } from "@/utils/constants"; +import JMButton from "@/components/JMButton"; +import Markdown, { MarkdownIt, stringToTokens, tokensToAST } from "react-native-markdown-display"; +import Accordion from "@/components/Accordion"; +import NavigationListItem from "@/components/ListItem/NavigationListItem"; +import { FAQ_DATA } from "./FaqData"; + +const markdownStyles = { + body: { + fontSize: 16, + fontWeight: "400" as const, + color: "red", + lineHeight: 24, + // color: TW_COLORS.CNAM_PRIMARY_900, + fontFamily: "SourceSans3", + }, + paragraph: { + fontSize: 16, + lineHeight: 24, + color: TW_COLORS.CNAM_PRIMARY_900, + marginBottom: 8, + fontFamily: "SourceSans3", + }, + strong: { + fontWeight: "600" as const, + color: TW_COLORS.CNAM_PRIMARY_800, + fontFamily: "SourceSans3", + }, + em: { + fontSize: 16, + // fontWeight: 400, + color: TW_COLORS.CNAM_PRIMARY_900, + fontFamily: "SourceSans3-Italic", + }, + // strong_em: { fontFamily: "SourceSans3-BoldItalic" }, + list_item: { + fontSize: 16, + lineHeight: 24, + color: TW_COLORS.CNAM_PRIMARY_900, + marginBottom: 4, + fontFamily: "SourceSans3", + }, + bullet_list: { + marginBottom: 8, + }, + ordered_list: { + marginBottom: 8, + }, + link: { + color: TW_COLORS.CNAM_CYAN_0, + textDecorationLine: "underline" as const, + fontFamily: "SourceSans3", + }, + code_inline: { + backgroundColor: TW_COLORS.GRAY_50, + color: TW_COLORS.CNAM_PRIMARY_900, + fontFamily: "SourceSans3", + paddingHorizontal: 4, + paddingVertical: 2, + borderRadius: 4, + }, + code_block: { + backgroundColor: TW_COLORS.GRAY_50, + color: TW_COLORS.CNAM_PRIMARY_900, + fontFamily: "SourceSans3", + padding: 12, + borderRadius: 8, + marginBottom: 8, + }, +}; + +export default function FaqDetailScreen({ + navigation, + route, +}: { + navigation: any; + route: { + params: { + slug: string; + }; + }; +}) { + const item = FAQ_DATA[route.params.slug]; + return ( + { + navigation.goBack(); + }} + showBottomButton={false} + navigation={navigation} + > + + + + {item.subtitle && ( + {item.subtitle} + )} + {/* + we encapsulate the Markdown tag in <> otherwise when and are next to each others, + markdownStyles is not applied (haven’t found out why yet) + */} + <> + {item.description} + + {item.exemple && ( + + {item.exemple} + + )} + + + + + + {item.next && ( + + A découvrir ensuite + { + navigation.push("faq-detail", { + slug: item.next, + }); + }} + /> + + )} + + + ); +} diff --git a/app/src/scenes/faq/FaqMainScreen.tsx b/app/src/scenes/faq/FaqMainScreen.tsx new file mode 100644 index 00000000..574dc4a5 --- /dev/null +++ b/app/src/scenes/faq/FaqMainScreen.tsx @@ -0,0 +1,73 @@ +import { mergeClassNames } from "@/utils/className"; +import { typography } from "@/utils/typography"; +import React from "react"; +import { Text, View } from "react-native"; +import { AnimatedHeaderScrollScreen } from "../survey-v2/AnimatedHeaderScrollScreen"; +import { TW_COLORS } from "@/utils/constants"; +import JMButton from "@/components/JMButton"; +import NavigationListItem from "@/components/ListItem/NavigationListItem"; +import Pencil from "@assets/svg/Pencil"; +import Goal from "@assets/svg/icon/Goal"; +import CalendarIcon from "@assets/svg/icon/Calendar"; +import TrendUpIcon from "@assets/svg/icon/TrendUp"; +import HealthIcon from "@assets/svg/icon/Health"; +import ShareIcon from "@assets/svg/icon/Share"; +import { FAQ_DATA } from "./FaqData"; + +export default function FaqMainScreen({ navigation, route }) { + return ( + { + navigation.goBack(); + }} + showBottomButton={false} + navigation={navigation} + > + + + + Jardin mental, qu’est-ce que c’est ? + + + + La santé mentale mérite d'être préservée au quotidien, pas seulement lorsqu'elle est en crise.{"\n\n"} + Un bon premier pas est d'apprendre à s'observer avec bienveillance, sans tomber dans + l'analyse excessive. Cela aide à reconnaître les signaux de mal-être et à identifier ce qui nous apporte du bien-être.{"\n\n"} + Notre application{" "} + + Jardin Mental offre un espace pour évaluer et suivre son état mental, même dans les moments positifs. + + + + + + Guide Pratique + + {Object.keys(FAQ_DATA).map((slug, index) => ( + { + navigation.navigate("faq-detail", { + slug: slug, + }); + }} + icon={FAQ_DATA[slug].icon} + /> + ))} + + + + Besoin d'assistance ? + + Si vous ne trouvez pas la réponse à votre question, contactez-nous sur + + + + + + ); +} diff --git a/app/src/utils/constants.ts b/app/src/utils/constants.ts index 85ca7354..267d9e04 100644 --- a/app/src/utils/constants.ts +++ b/app/src/utils/constants.ts @@ -360,6 +360,7 @@ export const TW_COLORS = { CNAM_CYAN_100_LIGHTEN_80: "#CCEDF9", CNAM_CYAN_0: "#00A5DF", CNAM_PRIMARY_900: "#134449", + CNAM_PRIMARY_800: "#3D6874", CNAM_PRIMARY_700: "#518B9A", BEIGE: "#FCEBD9", GRAY_800: "#4A5D5F", diff --git a/app/src/utils/typography.ts b/app/src/utils/typography.ts index 699c7e49..95775bd2 100644 --- a/app/src/utils/typography.ts +++ b/app/src/utils/typography.ts @@ -2,6 +2,7 @@ export const typography = { // Display displayMdBold: "text-display-md font-bold font-title", displayXsBold: "text-display-xs font-bold font-title text-center", + displayXsSemibold: "text-display-xs font-semibold font-title text-center", displayXsMedium: "text-display-xs font-medium font-title text-center", displayXsRegular: "text-display-xs-regular font-normal font-title text-center", diff --git a/app/tailwind.config.js b/app/tailwind.config.js index 942bd201..d72e8168 100644 --- a/app/tailwind.config.js +++ b/app/tailwind.config.js @@ -61,6 +61,8 @@ module.exports = { 900: "#134449", 800: "#3D6874", 500: "#65AEC1", + 300: "#A3CEDA", + 100: "#E0EFF3", 50: "#F0F7F9", 25: "#FAFDFD", }, diff --git a/app/yarn.lock b/app/yarn.lock index 3ea0db5d..e2f3ed67 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -3827,6 +3827,11 @@ entities@^4.2.0, entities@^4.4.0: resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== +entities@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" + integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== + env-editor@^0.4.1: version "0.4.2" resolved "https://registry.npmjs.org/env-editor/-/env-editor-0.4.2.tgz" @@ -6179,6 +6184,13 @@ lines-and-columns@^1.1.6: resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +linkify-it@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" + integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== + dependencies: + uc.micro "^1.0.1" + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz" @@ -6296,6 +6308,17 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" +markdown-it@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc" + integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg== + dependencies: + argparse "^1.0.7" + entities "~2.0.0" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + marky@^1.2.2: version "1.3.0" resolved "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz" @@ -6337,6 +6360,11 @@ mdn-data@2.0.30: resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz" integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== + memoize-one@^5.0.0: version "5.2.1" resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" @@ -7535,6 +7563,13 @@ react-native-draggable-flatlist@^4.0.1: dependencies: "@babel/preset-typescript" "^7.17.12" +react-native-fit-image@^1.5.5: + version "1.5.5" + resolved "https://registry.yarnpkg.com/react-native-fit-image/-/react-native-fit-image-1.5.5.tgz#c660d1ad74b9dcaa1cba27a0d9c23837e000226c" + integrity sha512-Wl3Vq2DQzxgsWKuW4USfck9zS7YzhvLNPpkwUUCF90bL32e1a0zOVQ3WsJILJOwzmPdHfzZmWasiiAUNBkhNkg== + dependencies: + prop-types "^15.5.10" + react-native-gesture-handler@~2.20.2: version "2.20.2" resolved "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.20.2.tgz" @@ -7579,6 +7614,16 @@ react-native-localize@^2.2.4: resolved "https://registry.npmjs.org/react-native-localize/-/react-native-localize-2.2.6.tgz" integrity sha512-EZETlC1ZlW/4g6xfsNCwAkAw5BDL2A6zk/08JjFR/GRGxYuKRD7iP1hHn1+h6DEu+xROjPpoNeXfMER2vkTVIQ== +react-native-markdown-display@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/react-native-markdown-display/-/react-native-markdown-display-7.0.2.tgz#b6584cec8d6670c0141fb8780bc2f0710188a4c2" + integrity sha512-Mn4wotMvMfLAwbX/huMLt202W5DsdpMO/kblk+6eUs55S57VVNni1gzZCh5qpznYLjIQELNh50VIozEfY6fvaQ== + dependencies: + css-to-react-native "^3.0.0" + markdown-it "^10.0.0" + prop-types "^15.7.2" + react-native-fit-image "^1.5.5" + react-native-modal-datetime-picker@^18.0.0: version "18.0.0" resolved "https://registry.npmjs.org/react-native-modal-datetime-picker/-/react-native-modal-datetime-picker-18.0.0.tgz" @@ -9000,6 +9045,11 @@ ua-parser-js@^1.0.35: resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.40.tgz" integrity sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew== +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + unbox-primitive@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz"