From 109f41e35ea523b47ac1eba5ed18c84b5d2762f3 Mon Sep 17 00:00:00 2001 From: Carissa Knipe Date: Fri, 28 Jun 2024 13:00:08 -0700 Subject: [PATCH 01/12] feat: Location dashboard displays "Loading..." or "No matches" or soil id results --- .../LocationDashboardContent.tsx | 62 ++++++++++++------- dev-client/src/translations/en.json | 2 + 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/dev-client/src/screens/LocationScreens/LocationDashboardContent.tsx b/dev-client/src/screens/LocationScreens/LocationDashboardContent.tsx index 0dc9cce1d..be21a11b8 100644 --- a/dev-client/src/screens/LocationScreens/LocationDashboardContent.tsx +++ b/dev-client/src/screens/LocationScreens/LocationDashboardContent.tsx @@ -60,19 +60,47 @@ const LocationDetail = ({label, value}: {label: string; value: string}) => ( type LocationPredictionProps = { label: string; - soilName: string; - ecologicalSiteName?: string; + coords: Coords; + siteId?: string; onExploreDataPress: () => void; }; const LocationPrediction = ({ label, - soilName, - ecologicalSiteName, + coords, + siteId, onExploreDataPress, }: LocationPredictionProps) => { const {t} = useTranslation(); + const soilIdData = useSoilIdData(coords, siteId); + const topSoilMatch = useMemo(() => getTopMatch(soilIdData), [soilIdData]); + + // TODO-cknipe: I feel like this should be extracted so multiple things can use it + let soilIdMatchText: string; + let ecologicalSiteText: string; + if (soilIdData.status === 'loading') { + soilIdMatchText = t('soil.loading'); + ecologicalSiteText = t('soil.loading'); + } else if (soilIdData.status === 'error') { + soilIdMatchText = t('soil.no_matches'); + ecologicalSiteText = t('soil.no_matches'); + } else if (soilIdData.status === 'DATA_UNAVAILABLE') { + soilIdMatchText = t('soil.no_matches'); + ecologicalSiteText = t('soil.no_matches'); + } else if (soilIdData.status === 'ALGORITHM_FAILURE') { + soilIdMatchText = t('soil.no_matches'); + ecologicalSiteText = t('soil.no_matches'); + } else if (soilIdData.status === 'ready') { + soilIdMatchText = + topSoilMatch?.soilInfo.soilSeries.name ?? t('soil.no_matches'); + ecologicalSiteText = + topSoilMatch?.soilInfo.ecologicalSite?.name ?? t('soil.no_matches'); + } else { + soilIdMatchText = t('soil.no_matches'); + ecologicalSiteText = t('soil.no_matches'); + } + return ( @@ -90,13 +118,11 @@ const LocationPrediction = ({ {t('soil.top_match')}: - {soilName ?? t('site.soil_id.soil_info.no_matches')} + {soilIdMatchText} {t('soil.ecological_site_name')}: - - {ecologicalSiteName ?? t('site.soil_id.soil_info.no_matches')} - + {ecologicalSiteText} - - ); -}; - export const LocationDashboardContent = ({ siteId, coords, diff --git a/dev-client/src/screens/LocationScreens/components/LocationPrediction.tsx b/dev-client/src/screens/LocationScreens/components/LocationPrediction.tsx new file mode 100644 index 000000000..6a080abca --- /dev/null +++ b/dev-client/src/screens/LocationScreens/components/LocationPrediction.tsx @@ -0,0 +1,112 @@ +/* + * Copyright © 2024 Technology Matters + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ + +import {useMemo} from 'react'; +import {useTranslation} from 'react-i18next'; + +import {TFunction} from 'i18next'; +import {Button} from 'native-base'; + +import {useSoilIdData} from 'terraso-client-shared/soilId/soilIdHooks'; +import {Coords} from 'terraso-client-shared/types'; + +import StackedBarChart from 'terraso-mobile-client/assets/stacked-bar.svg'; +import {Icon} from 'terraso-mobile-client/components/icons/Icon'; +import { + Box, + Row, + Text, +} from 'terraso-mobile-client/components/NativeBaseAdapters'; +import {getTopMatch} from 'terraso-mobile-client/model/soilId/soilIdRanking'; +import {SoilIdData} from 'terraso-mobile-client/model/soilId/soilIdTypes'; + +type LocationPredictionProps = { + label: string; + coords: Coords; + siteId?: string; + onExploreDataPress: () => void; +}; + +export const LocationPrediction = ({ + label, + coords, + siteId, + onExploreDataPress, +}: LocationPredictionProps) => { + const {t} = useTranslation(); + + const soilIdData = useSoilIdData(coords, siteId); + const {soilIdMatchText, ecologicalSiteText} = useMemo(() => { + return getSoilIdDetailDisplayValues(soilIdData, t); + }, [soilIdData, t]); + + return ( + + + + + + + {label} + + + + + {t('soil.top_match')}: + {soilIdMatchText} + + + {t('soil.ecological_site_name')}: + {ecologicalSiteText} + + + + + ); +}; + +const getSoilIdDetailDisplayValues = (soilIdData: SoilIdData, t: TFunction) => { + const topSoilMatch = getTopMatch(soilIdData); + let soilIdMatchText: string; + let ecologicalSiteText: string; + if (soilIdData.status === 'loading') { + soilIdMatchText = t('soil.loading'); + ecologicalSiteText = t('soil.loading'); + } else if (soilIdData.status === 'DATA_UNAVAILABLE') { + soilIdMatchText = t('soil.no_matches'); + ecologicalSiteText = t('soil.no_matches'); + } else if (soilIdData.status === 'ready') { + soilIdMatchText = + topSoilMatch?.soilInfo.soilSeries.name ?? t('soil.no_matches'); + ecologicalSiteText = + topSoilMatch?.soilInfo.ecologicalSite?.name ?? t('soil.no_matches'); + } else { + soilIdMatchText = t('soil.error'); + ecologicalSiteText = t('soil.error'); + } + return {soilIdMatchText, ecologicalSiteText}; +}; From a11159e650df07af1b60eeda2b3e1b07079639f1 Mon Sep 17 00:00:00 2001 From: Carissa Knipe Date: Tue, 2 Jul 2024 10:07:27 -0700 Subject: [PATCH 08/12] fix: use consistent apostrophe characters in strings --- dev-client/src/translations/en.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev-client/src/translations/en.json b/dev-client/src/translations/en.json index 5052dfe1d..5821c588d 100644 --- a/dev-client/src/translations/en.json +++ b/dev-client/src/translations/en.json @@ -9,7 +9,7 @@ "bullet_4": "Project management" }, "next": { - "title": "What's next?", + "title": "What’s next?", "subtitle": "Future versions will include:", "bullet_1": "Offline capabilities", "bullet_2": "Data visualization enhancements", @@ -121,7 +121,7 @@ } }, "match": "match", - "error_generic_title": "Can't fetch soil map", + "error_generic_title": "Can’t fetch soil map", "error_generic_body": "LandPKS was unable to fetch the soil map for this location. Try again later.", "no_map_data_title": "No soil map data", "no_map_data_body": "There is no soil map data available for this site, so LandPKS cannot generate soil matches for this site. Data can still be collected for this site, and if soil map data becomes available in the future, soil matches will appear here.", @@ -354,7 +354,7 @@ "contributor_help": "Can view, add, and edit site data", "viewer_help": "Can view site data", "remove": "Remove from project", - "remove_help": "Remove the team member's access to this project, retaining any data contributed to sites", + "remove_help": "Remove the team member’s access to this project, retaining any data contributed to sites", "confirm_removal_title": "Remove from Project?", "confirm_removal_body": "This will remove the team member from the project, but will retain their contributed site data.", "confirm_removal_action": "Remove" @@ -547,7 +547,7 @@ "bedrock": "Bedrock", "top_match": "Top Match", "ecological_site_name": "Ecological Site Name", - "loading": "Loading...", + "loading": "Loading…", "no_matches": "No matches", "error": "Error", "explore_data": "Explore the data", From cb05a75d0b7f9b601940a2d32f775e89e30180ab Mon Sep 17 00:00:00 2001 From: Carissa Knipe Date: Tue, 2 Jul 2024 14:10:51 -0700 Subject: [PATCH 09/12] fix: minor styling and refactoring --- .../src/components/messages/AlertMessageBox.tsx | 12 ++++-------- .../src/components/messages/ErrorMessageBox.tsx | 12 ++++-------- .../components/TemporaryLocationCallout.tsx | 4 +--- .../components/LocationPrediction.tsx | 2 +- .../components/soilId/SoilIdMatchesSection.tsx | 3 +-- dev-client/src/theme.ts | 8 +++----- 6 files changed, 14 insertions(+), 27 deletions(-) diff --git a/dev-client/src/components/messages/AlertMessageBox.tsx b/dev-client/src/components/messages/AlertMessageBox.tsx index 80c79c17b..aeb57ae64 100644 --- a/dev-client/src/components/messages/AlertMessageBox.tsx +++ b/dev-client/src/components/messages/AlertMessageBox.tsx @@ -22,7 +22,6 @@ import { Row, Text, } from 'terraso-mobile-client/components/NativeBaseAdapters'; -import {theme} from 'terraso-mobile-client/theme'; type MessageBoxProps = React.PropsWithChildren<{ title?: string; @@ -31,18 +30,15 @@ type MessageBoxProps = React.PropsWithChildren<{ export const AlertMessageBox = ({title, children}: MessageBoxProps) => { return ( - + - + {title} {children} diff --git a/dev-client/src/components/messages/ErrorMessageBox.tsx b/dev-client/src/components/messages/ErrorMessageBox.tsx index c383f704d..dcd9866ad 100644 --- a/dev-client/src/components/messages/ErrorMessageBox.tsx +++ b/dev-client/src/components/messages/ErrorMessageBox.tsx @@ -22,7 +22,6 @@ import { Row, Text, } from 'terraso-mobile-client/components/NativeBaseAdapters'; -import {theme} from 'terraso-mobile-client/theme'; type MessageBoxProps = React.PropsWithChildren<{ title?: string; @@ -31,18 +30,15 @@ type MessageBoxProps = React.PropsWithChildren<{ export const ErrorMessageBox = ({title, children}: MessageBoxProps) => { return ( - + - + {title} {children} diff --git a/dev-client/src/screens/HomeScreen/components/TemporaryLocationCallout.tsx b/dev-client/src/screens/HomeScreen/components/TemporaryLocationCallout.tsx index 7359e9865..49d7080f4 100644 --- a/dev-client/src/screens/HomeScreen/components/TemporaryLocationCallout.tsx +++ b/dev-client/src/screens/HomeScreen/components/TemporaryLocationCallout.tsx @@ -100,9 +100,7 @@ export const TemporaryLocationCallout = ({ label={t('site.elevation_label')} value={ elevation ? ( - - {renderElevation(t, elevation)} - + {renderElevation(t, elevation)} ) : ( ) diff --git a/dev-client/src/screens/LocationScreens/components/LocationPrediction.tsx b/dev-client/src/screens/LocationScreens/components/LocationPrediction.tsx index 6a080abca..d990506c1 100644 --- a/dev-client/src/screens/LocationScreens/components/LocationPrediction.tsx +++ b/dev-client/src/screens/LocationScreens/components/LocationPrediction.tsx @@ -79,7 +79,7 @@ export const LocationPrediction = ({