diff --git a/domains/dashboard/Dashboard.tsx b/domains/dashboard/Dashboard.tsx index 58b016d..893000e 100644 --- a/domains/dashboard/Dashboard.tsx +++ b/domains/dashboard/Dashboard.tsx @@ -1,4 +1,4 @@ -import { type FC, type ReactNode } from 'react'; +import { memo, type FC, type ReactNode } from 'react'; import { ApolloError } from '@apollo/client'; import { useFetchDataset } from '@/domains/dashboard/hooks'; @@ -35,7 +35,10 @@ const Dashboard: FC = ({ clinicalData }): ReactNode => {
- +
+ + +
= ({ clinicalData }): ReactNode => { ); }; -export { Dashboard }; +export default memo(Dashboard); diff --git a/domains/dashboard/components/Banner/Banner.tsx b/domains/dashboard/components/Banner/Banner.tsx index 54aa06d..36626a9 100644 --- a/domains/dashboard/components/Banner/Banner.tsx +++ b/domains/dashboard/components/Banner/Banner.tsx @@ -1,15 +1,21 @@ +/* eslint-disable no-extra-boolean-cast */ import { type FC, type PropsWithChildren, type ReactNode } from 'react'; import dayjs from 'dayjs'; import { useSelectDate } from '@/domains/dashboard/hooks/useSelectDate'; +import { useSelectCityStore } from '../../store'; interface Props extends PropsWithChildren {} const Banner: FC = (props): ReactNode => { const { selectedDate } = useSelectDate(); + const { city } = useSelectCityStore(); const startDate = dayjs(selectedDate.startDate).format('DD/MM/YYYY'); const endDate = dayjs(selectedDate.endDate).format('DD/MM/YYYY'); + const hasDate = Boolean(selectedDate.startDate) && Boolean(selectedDate.endDate); + const hasCity = Boolean(city); + return (
@@ -17,10 +23,21 @@ const Banner: FC = (props): ReactNode => { Covid  Insights. -

- Pesquisa entre {startDate} e{' '} - {endDate} -

+ {hasDate ? ( +

+ Pesquisa entre {startDate} e{' '} + {endDate}{' '} + {hasCity ? ( + + na cidade de {city} + + ) : ( + '' + )} +

+ ) : ( +
+ )}
{props.children}
diff --git a/domains/dashboard/components/DashboardSkeleton/DashboardSkeleton.tsx b/domains/dashboard/components/DashboardSkeleton/DashboardSkeleton.tsx index 24a391e..508b646 100644 --- a/domains/dashboard/components/DashboardSkeleton/DashboardSkeleton.tsx +++ b/domains/dashboard/components/DashboardSkeleton/DashboardSkeleton.tsx @@ -22,6 +22,10 @@ const DashboardSkeleton = (): ReactNode => (
+
+ + +
diff --git a/domains/dashboard/hooks/useFetchDataset/useFetchDataset.ts b/domains/dashboard/hooks/useFetchDataset/useFetchDataset.ts index 6b7d5a8..d2ced7e 100644 --- a/domains/dashboard/hooks/useFetchDataset/useFetchDataset.ts +++ b/domains/dashboard/hooks/useFetchDataset/useFetchDataset.ts @@ -1,8 +1,9 @@ import { useEffect, useState } from 'react'; -import { useSelectDate } from '../useSelectDate'; +import { useSelectDate } from '@/domains/dashboard/hooks'; import { type ApolloError, useLazyQuery } from '@apollo/client'; import { clinicalDataQuery } from '@/services/graphql/query'; import { type QueryProps } from '@/domains/dashboard/types/QueryProps'; +import { useSelectCityStore } from '@/domains/dashboard/store'; interface UseFetchDatasetReturn { data: QueryProps | undefined; @@ -13,28 +14,32 @@ interface UseFetchDatasetReturn { const useFetchDataset = (): UseFetchDatasetReturn => { const [isMounted, setIsMounted] = useState(false); const { selectedDate } = useSelectDate(); + const { cityCode } = useSelectCityStore(); + // !TODO: Invalidate cache if city is changed const [fetch, { data, loading, error }] = useLazyQuery(clinicalDataQuery, { - variables: { - startDate: selectedDate?.startDate, - endDate: selectedDate?.endDate, - }, fetchPolicy: 'cache-and-network', nextFetchPolicy: 'cache-first', }); // fetch data when the component is mounted && when the date is changed useEffect(() => { - if (isMounted) { + if (isMounted && selectedDate.startDate !== null && selectedDate.endDate !== null) { void (async function () { - await fetch(); + await fetch({ + variables: { + startDate: selectedDate.startDate, + endDate: selectedDate.endDate, + cityCode, + }, + }); })(); } setIsMounted(true); return () => { setIsMounted(false); }; - }, [selectedDate]); + }, [selectedDate.startDate, selectedDate.endDate]); return { data, loading, error }; }; diff --git a/domains/dashboard/hooks/useSelectDate/useSelectDate.tsx b/domains/dashboard/hooks/useSelectDate/useSelectDate.tsx index ad55808..e0948e8 100644 --- a/domains/dashboard/hooks/useSelectDate/useSelectDate.tsx +++ b/domains/dashboard/hooks/useSelectDate/useSelectDate.tsx @@ -2,6 +2,7 @@ import type { Dayjs } from 'dayjs'; import { useSlectedDateStore } from '@/domains/dashboard/store/useSlectedDateStore'; import { PANDEMIC_START_DATE, LAST_DATABASE_UPDATE } from '@/domains/dashboard/constants'; import dayjs from 'dayjs'; +import { useSelectCityStore } from '@/domains/dashboard/store'; type EventValue = DateType | null; type RangeValue = [EventValue, EventValue] | null; @@ -11,6 +12,7 @@ interface UseSelectDateReturnType { startDate: string; endDate: string; }; + onChangeDate: (date: RangeValue) => void; disabledDate: (current: Dayjs) => boolean; } diff --git a/domains/dashboard/index.ts b/domains/dashboard/index.ts index 41a54b5..15d6d11 100644 --- a/domains/dashboard/index.ts +++ b/domains/dashboard/index.ts @@ -1 +1 @@ -export { Dashboard } from './Dashboard'; +export { default as Dashboard } from './Dashboard'; diff --git a/domains/dashboard/store/index.ts b/domains/dashboard/store/index.ts index 9ee4b08..fc7eedf 100644 --- a/domains/dashboard/store/index.ts +++ b/domains/dashboard/store/index.ts @@ -1 +1,2 @@ export { useSlectedDateStore } from './useSlectedDateStore'; +export { useSelectCityStore } from './useSelectCityStore'; diff --git a/domains/dashboard/store/useSelectCityStore/index.ts b/domains/dashboard/store/useSelectCityStore/index.ts new file mode 100644 index 0000000..b05d59f --- /dev/null +++ b/domains/dashboard/store/useSelectCityStore/index.ts @@ -0,0 +1 @@ +export { useSelectCityStore } from './useSelectCityStore'; diff --git a/domains/dashboard/store/useSelectCityStore/useSelectCityStore.ts b/domains/dashboard/store/useSelectCityStore/useSelectCityStore.ts new file mode 100644 index 0000000..ac71f0d --- /dev/null +++ b/domains/dashboard/store/useSelectCityStore/useSelectCityStore.ts @@ -0,0 +1,27 @@ +import { create } from 'zustand'; + +interface City { + city: string; + cityCode: string; +} + +interface SelectedCityStore { + city: string; + cityCode: string; + setSelectedCity: ({ city, cityCode }: City) => void; + getSelectedCity: () => { city: string; cityCode: string }; +} + +const useSelectCityStore = create((set, get) => ({ + city: '', + cityCode: '', + setSelectedCity: ({ city, cityCode }) => { + set({ city, cityCode }); + }, + getSelectedCity: () => { + const { city, cityCode } = get(); + return { city, cityCode }; + }, +})); + +export { useSelectCityStore }; diff --git a/domains/dashboard/store/useSlectedDateStore/useSlectedDateStore.ts b/domains/dashboard/store/useSlectedDateStore/useSlectedDateStore.ts index f8c2adb..fef1241 100644 --- a/domains/dashboard/store/useSlectedDateStore/useSlectedDateStore.ts +++ b/domains/dashboard/store/useSlectedDateStore/useSlectedDateStore.ts @@ -11,8 +11,8 @@ interface SelectedDateStore { const useSlectedDateStore = create((set, get) => ({ selectedDate: { - startDate: '2022-01-01T10:00:00Z', - endDate: '2022-12-31T10:00:00Z', + startDate: '', + endDate: '', }, setSelectedDate: (startDate: string, endDate: string) => { set({ selectedDate: { startDate, endDate } }); diff --git a/services/graphql/query/cities.ts b/services/graphql/query/cities.ts new file mode 100644 index 0000000..0bc0113 --- /dev/null +++ b/services/graphql/query/cities.ts @@ -0,0 +1,10 @@ +import { gql } from '@apollo/client'; + +export const cities = gql` + query cities { + cities { + name + code + } + } +`; diff --git a/services/graphql/query/clinicalDataQuery.ts b/services/graphql/query/clinicalDataQuery.ts index e81415c..9667048 100644 --- a/services/graphql/query/clinicalDataQuery.ts +++ b/services/graphql/query/clinicalDataQuery.ts @@ -1,10 +1,12 @@ import { gql } from '@apollo/client'; export const clinicalDataQuery = gql` - query Symptoms($startDate: DateTime, $endDate: DateTime) { - countPatients(filters: { startDate: $startDate, endDate: $endDate }) + query Symptoms($startDate: DateTime, $endDate: DateTime, $cityCode: String) { + countPatients(filters: { startDate: $startDate, endDate: $endDate, cityCode: $cityCode }) - countPatientsSymptoms(filters: { startDate: $startDate, endDate: $endDate }) { + countPatientsSymptoms( + filters: { startDate: $startDate, endDate: $endDate, cityCode: $cityCode } + ) { febre garganta tosse @@ -12,31 +14,39 @@ export const clinicalDataQuery = gql` outros } - countPatientsByAge(filters: { startDate: $startDate, endDate: $endDate }) { + countPatientsByAge(filters: { startDate: $startDate, endDate: $endDate, cityCode: $cityCode }) { age count } - countPatientsByRecoveryStatus(filters: { startDate: $startDate, endDate: $endDate }) { + countPatientsByRecoveryStatus( + filters: { startDate: $startDate, endDate: $endDate, cityCode: $cityCode } + ) { status count } - countPatientsByDiagnosisCriteria(filters: { startDate: $startDate, endDate: $endDate }) { + countPatientsByDiagnosisCriteria( + filters: { startDate: $startDate, endDate: $endDate, cityCode: $cityCode } + ) { criteria count } - countDeadPatients(filters: { startDate: $startDate, endDate: $endDate }) { + countDeadPatients(filters: { startDate: $startDate, endDate: $endDate, cityCode: $cityCode }) { count } - countDeadPatientsGroupedByMonth(filters: { startDate: $startDate, endDate: $endDate }) { + countDeadPatientsGroupedByMonth( + filters: { startDate: $startDate, endDate: $endDate, cityCode: $cityCode } + ) { month year count } - averageDeadPatientAge(filters: { startDate: $startDate, endDate: $endDate }) { + averageDeadPatientAge( + filters: { startDate: $startDate, endDate: $endDate, cityCode: $cityCode } + ) { avg } } diff --git a/services/graphql/query/index.ts b/services/graphql/query/index.ts index e07e0d2..1034198 100644 --- a/services/graphql/query/index.ts +++ b/services/graphql/query/index.ts @@ -1,2 +1,3 @@ export { symptomsQuery } from './symptomsQuery'; export { clinicalDataQuery } from './clinicalDataQuery'; +export { cities } from './cities'; diff --git a/services/graphql/query/symptomsQuery.ts b/services/graphql/query/symptomsQuery.ts index c31bb5c..274fa95 100644 --- a/services/graphql/query/symptomsQuery.ts +++ b/services/graphql/query/symptomsQuery.ts @@ -2,7 +2,9 @@ import { gql } from '@apollo/client'; export const symptomsQuery = gql` query Symptoms($startDate: DateTime, $endDate: DateTime) { - countPatientsSymptoms(filters: {startDate: $startDate, endDate: $endDate}) { + countPatientsSymptoms( + filters: { startDate: $startDate, endDate: $endDate, cityCode: $cityCode } + ) { febre garganta tosse diff --git a/shared/components/DatePicker/DatePicker.tsx b/shared/components/DatePicker/DatePicker.tsx index d4ba1dd..2be07a2 100644 --- a/shared/components/DatePicker/DatePicker.tsx +++ b/shared/components/DatePicker/DatePicker.tsx @@ -5,6 +5,7 @@ import locale from 'antd/lib/date-picker/locale/pt_BR'; const DatePicker = (): ReactNode => { const { onChangeDate, disabledDate } = useSelectDate(); + return (
{} + +interface City { + name: string; + code: string; +} + +interface Data { + cities: City[]; +} + +const SelectCity: FC = (props) => { + const { data, error } = useQuery(cities); + const { setSelectedCity } = useSelectCityStore(); + + const handleSelectCity = (value: unknown, label: string): void => { + // eslint-disable-next-line no-extra-boolean-cast + if (Boolean(value)) { + setSelectedCity({ city: label, cityCode: String(value) }); + } + }; + + if (error != null || data == null) { + return; + } + + const refined = data.cities.map((city) => ({ + label: city.name, + value: city.code, + })); + + return ( +