Skip to content

Commit

Permalink
feat(articles): ajout filtre favoris (#1430)
Browse files Browse the repository at this point in the history
  • Loading branch information
MorganeDe authored Sep 7, 2022
1 parent 694ce60 commit aeb5c1e
Show file tree
Hide file tree
Showing 13 changed files with 461 additions and 127 deletions.
2 changes: 1 addition & 1 deletion front/src/assets/images/checkbox_checked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions front/src/assets/images/checkbox_unchecked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 31 additions & 3 deletions front/src/components/article/articleListHeader.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,28 @@ import type { StackNavigationProp } from "@react-navigation/stack";
import _ from "lodash";
import type { FC } from "react";
import * as React from "react";
import { useCallback } from "react";
import { useCallback, useState } from "react";
import { StyleSheet } from "react-native";

import { Labels } from "../../constants";
import { useFavoriteArticlesIds } from "../../hooks";
import { Colors, Margins, Paddings, Sizes } from "../../styles";
import type { TrackerEvent } from "../../type";
import type {
Article,
ArticleFilter,
Step,
TabHomeParamList,
Thematique,
} from "../../types";
import { TrackerUtils } from "../../utils";
import { ArticleFilterUtils, TrackerUtils } from "../../utils";
import ArticlesFilter from "../article/articlesFilter.component";
import BackButton from "../baseComponents/backButton.component";
import CustomButton from "../baseComponents/customButton.component";
import { CommonText, SecondaryText } from "../baseComponents/StyledText";
import { View } from "../baseComponents/Themed";
import TitleH1 from "../baseComponents/titleH1.component";
import TrackerHandler from "../tracker/trackerHandler.component";

interface Props {
title: string;
Expand All @@ -45,6 +48,8 @@ const ArticleListHeader: FC<Props> = ({
navigation,
step,
}) => {
const [trackerEventObject, setTrackerEventObject] = useState<TrackerEvent>();
const favoriteIds = useFavoriteArticlesIds();
const stepIsFirstThreeMonths = step
? step.id == ETAPE_ENFANT_3_PREMIERS_MOIS
: false;
Expand Down Expand Up @@ -89,6 +94,24 @@ const ArticleListHeader: FC<Props> = ({
[articles, sendFiltersTracker, setArticles]
);

const filterArticlesByFavorites = useCallback(() => {
const filteredArticles = ArticleFilterUtils.getFavoriteArticles(
articles,
favoriteIds
);
const result = articles.map((article) => {
return ArticleFilterUtils.hideArticleNotInFavorites(
article,
filteredArticles
);
});
setTrackerEventObject({
action: "FilterByFavorites",
name: `Step: ${step?.nom}`,
});
setArticles(result);
}, [articles, favoriteIds, setArticles, step]);

const navigateToSurvey = useCallback(() => {
navigation.navigate("epdsSurvey");
}, [navigation]);
Expand All @@ -99,6 +122,7 @@ const ArticleListHeader: FC<Props> = ({

return (
<View>
<TrackerHandler eventObject={trackerEventObject} />
<View style={styles.topContainer}>
<View style={[styles.flexStart]}>
<BackButton action={onGoBack} />
Expand All @@ -124,7 +148,11 @@ const ArticleListHeader: FC<Props> = ({
</View>
)}
{articles.length > 0 && (
<ArticlesFilter articles={articles} applyFilters={applyFilters} />
<ArticlesFilter
articles={articles}
applyFilters={applyFilters}
filterByFavorites={filterArticlesByFavorites}
/>
)}
</View>
);
Expand Down
84 changes: 72 additions & 12 deletions front/src/components/article/articlesFilter.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ScrollView } from "react-native-gesture-handler";

import { Labels } from "../../constants";
import { PLATFORM_IS_ANDROID } from "../../constants/platform.constants";
import { useFavoriteArticlesIds } from "../../hooks";
import { Colors, Margins, Paddings, Sizes, Styles } from "../../styles";
import type { Article, ArticleFilter } from "../../types";
import { ArticleFilterUtils } from "../../utils";
Expand All @@ -20,18 +21,31 @@ import {
TitleH1,
View,
} from "../baseComponents";
import CustomDivider from "../baseComponents/customDivider.component";
import ArticlesFilterFavoritesRow from "./articlesFilterFavoritesRow.component";

interface Props {
articles: Article[];
applyFilters: (filters: ArticleFilter[]) => void;
filterByFavorites: () => void;
}

const ArticlesFilter: FC<Props> = ({ articles, applyFilters }) => {
const ArticlesFilter: FC<Props> = ({
articles,
applyFilters,
filterByFavorites,
}) => {
const favoriteArticlesIds = useFavoriteArticlesIds();
const [filters, setFilters] = useState<ArticleFilter[]>([]);
const [lastAppliedFilters, setLastAppliedFilters] = useState<ArticleFilter[]>(
[]
);
const [isModalVisible, setIsModalVisible] = useState(false);
const [showFavoriteToggle, setShowFavoriteToggle] = useState(false);

const [lastToggleOnFavoritesValue, setLastToggleOnFavoritesValue] =
useState(false);
const [isToggleOn, setIsToggleOn] = useState(false);

useEffect(() => {
if (filters.length === 0) {
Expand All @@ -42,34 +56,78 @@ const ArticlesFilter: FC<Props> = ({ articles, applyFilters }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [articles]);

useEffect(() => {
setShowFavoriteToggle(
ArticleFilterUtils.shouldShowFavoriteToggle(articles, favoriteArticlesIds)
);
}, [articles, favoriteArticlesIds]);

useEffect(() => {
if (showFavoriteToggle && !isToggleOn) {
const areArticlesAllFavorites =
!ArticleFilterUtils.areArticlesNotAllFavorites(
articles,
favoriteArticlesIds
);

setLastToggleOnFavoritesValue(areArticlesAllFavorites);
setIsToggleOn(areArticlesAllFavorites);
}
}, [articles, favoriteArticlesIds, isToggleOn, showFavoriteToggle]);

const onShowModal = useCallback(() => {
if (lastAppliedFilters.length > 0) {
setFilters(lastAppliedFilters);
}
setIsToggleOn(lastToggleOnFavoritesValue);
setIsModalVisible(!isModalVisible);
}, [isModalVisible, lastAppliedFilters]);
}, [isModalVisible, lastAppliedFilters, lastToggleOnFavoritesValue]);

const resetFilters = useCallback(() => {
setFilters(ArticleFilterUtils.getFilters(articles));
setIsToggleOn(false);
}, [articles]);

const cancelFiltersModal = useCallback(() => {
setFilters(lastAppliedFilters);
setIsToggleOn(lastToggleOnFavoritesValue);
setIsModalVisible(false);
}, [lastAppliedFilters]);
}, [lastAppliedFilters, lastToggleOnFavoritesValue]);

const onCheckboxPressed = useCallback(
(selectedFilter: ArticleFilter) => () => {
if (isToggleOn) setIsToggleOn(false);
setFilters(ArticleFilterUtils.updateFilters(filters, selectedFilter));
},
[filters]
[filters, isToggleOn]
);

const onToggleFavorite = useCallback(() => {
setIsToggleOn(!isToggleOn);
setFilters(ArticleFilterUtils.getFilters(articles));
}, [isToggleOn, articles]);

const onValidateFilter = useCallback(() => {
setLastToggleOnFavoritesValue(isToggleOn);
setLastAppliedFilters(filters);
applyFilters(filters);

if (isToggleOn) filterByFavorites();
else applyFilters(filters);

setIsModalVisible(false);
}, [applyFilters, filters]);
}, [applyFilters, filters, isToggleOn, filterByFavorites]);

const renderFavoriteToggleRow = () => {
return showFavoriteToggle ? (
<>
<CustomDivider />
<ArticlesFilterFavoritesRow
onToggleFavorite={onToggleFavorite}
isToggleOn={isToggleOn}
/>
</>
) : null;
};

return (
<View style={styles.paddingsDefault}>
Expand Down Expand Up @@ -130,21 +188,22 @@ const ArticlesFilter: FC<Props> = ({ articles, applyFilters }) => {
<CheckBox
containerStyle={styles.checkboxItem}
textStyle={{
color: Colors.primaryBlueDark,
flex: 1,
fontWeight: filter.active ? "bold" : "normal",
}}
key={index}
iconRight
uncheckedIcon={
<BaseAssets.UncheckedIcon
width={Sizes.lg}
height={Sizes.lg}
<BaseAssets.CheckboxUncheckedIcon
width={Sizes.sm}
height={Sizes.sm}
/>
}
checkedIcon={
<BaseAssets.CheckedIcon
width={Sizes.lg}
height={Sizes.lg}
<BaseAssets.CheckboxCheckedIcon
width={Sizes.sm}
height={Sizes.sm}
/>
}
uncheckedColor={Colors.primaryBlueDark}
Expand All @@ -157,6 +216,7 @@ const ArticlesFilter: FC<Props> = ({ articles, applyFilters }) => {
onPress={onCheckboxPressed(filter)}
/>
))}
{renderFavoriteToggleRow()}
</ScrollView>

<View style={styles.buttonsContainer}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from "react";
import { StyleSheet, View } from "react-native";

import { Labels } from "../../constants";
import { Colors, FontWeight, Margins, Paddings, Sizes } from "../../styles";
import { SecondaryText, Toggle } from "../baseComponents";

interface Props {
isToggleOn: boolean;
onToggleFavorite: () => void;
}

const ArticlesFilterFavoritesRow: React.FC<Props> = ({
isToggleOn,
onToggleFavorite,
}) => {
return (
<View style={styles.mainContainer}>
<SecondaryText
style={{
color: Colors.primaryBlueDark,
fontSize: Sizes.xs,
fontWeight: isToggleOn ? FontWeight.bold : FontWeight.normal,
}}
>
{Labels.articleList.filterByFavorites}
</SecondaryText>
<Toggle isToggleOn={isToggleOn} toggleSwitch={onToggleFavorite} />
</View>
);
};

const styles = StyleSheet.create({
mainContainer: {
alignItems: "center",
flexDirection: "row",
justifyContent: "space-between",
margin: Margins.default,
marginEnd: 0,
padding: Paddings.default,
paddingTop: 0,
},
rowTitleStyle: {
color: Colors.primaryBlueDark,
fontSize: Sizes.xs,
},
});

export default ArticlesFilterFavoritesRow;
12 changes: 11 additions & 1 deletion front/src/components/assets/baseAssets.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import IcomoonFont from "../../assets/icomoon/icomoon.ttf";
import CheckboxCheckedIcon from "../../assets/images/checkbox_checked.svg";
import CheckboxUncheckedIcon from "../../assets/images/checkbox_unchecked.svg";
import LogoMinistere from "../../assets/images/Logo ministere.svg";
import AppLogo from "../../assets/images/logo.svg";
import CheckedIcon from "../../assets/images/radio_checked.svg";
import UncheckedIcon from "../../assets/images/radio_unchecked.svg";

export { AppLogo, CheckedIcon, IcomoonFont, LogoMinistere, UncheckedIcon };
export {
AppLogo,
CheckboxCheckedIcon,
CheckboxUncheckedIcon,
CheckedIcon,
IcomoonFont,
LogoMinistere,
UncheckedIcon,
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const CustomDivider: FC = () => {
const styles = StyleSheet.create({
divider: {
alignSelf: "center",
backgroundColor: Colors.navigation,
backgroundColor: Colors.primaryBlue,
borderRadius: Sizes.xs,
height: Sizes.divider,
marginVertical: Margins.default,
Expand Down
2 changes: 2 additions & 0 deletions front/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import SubmitNewFilter from "./aroundMe/submitNewFilter.component";
import ArticleCard from "./article/articleCard.component";
import ArticleList from "./article/articleList.component";
import ArticlesFilter from "./article/articlesFilter.component";
import ArticlesFilterFavoritesRow from "./article/articlesFilterFavoritesRow.component";
import DidYouKnow from "./article/didYouKnow.component";
import ImageBanner from "./article/imageBanner.component";
import InShort from "./article/inShort.component";
Expand Down Expand Up @@ -57,6 +58,7 @@ export {
ArticleCard,
ArticleList,
ArticlesFilter,
ArticlesFilterFavoritesRow,
CheckAppVersion,
ConditionsOfUse,
CustomMapMarker,
Expand Down
1 change: 1 addition & 0 deletions front/src/constants/Labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ export default {
articleList: {
articlesAlreadyRead: "article(s) déjà lu(s)",
articlesToRead: "article(s) à lire",
filterByFavorites: "Afficher seulement mes favoris",
filters: "Filtrer",
resetFilters: "Réinitialiser",
},
Expand Down
2 changes: 2 additions & 0 deletions front/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import useAccessibilityReader from "./useAccessibilityReader";
import useCachedResources from "./useCachedResources";
import useColorScheme from "./useColorScheme";
import useFavoriteArticlesIds from "./useFavoriteArticlesIds";
import useSavedCartographyFilters from "./useSavedCartographyFilters";

export {
useAccessibilityReader,
useCachedResources,
useColorScheme,
useFavoriteArticlesIds,
useSavedCartographyFilters,
};
Loading

0 comments on commit aeb5c1e

Please sign in to comment.