Skip to content

Commit

Permalink
Add Council District view
Browse files Browse the repository at this point in the history
  • Loading branch information
zack committed Jul 8, 2024
1 parent e9180f7 commit 33bb9ee
Show file tree
Hide file tree
Showing 7 changed files with 306 additions and 165 deletions.
18 changes: 9 additions & 9 deletions app/BoroughData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ import LoadingSpinner from './LoadingSpinner';
import Topline from './Topline';
import { Box, FormControl, InputLabel, MenuItem, Select } from '@mui/material';
import React, { memo } from 'react';
import { Timeframe, getBoroughTimeframe } from './action';
import { getBoroughData, getToplineBoroughData } from './action';
import {
Timeframe,
getChartData,
getTimeframeData,
getToplineData,
} from './action';

export type BoroughDataFetcherFunction = (
borough: string,
Expand All @@ -28,25 +32,21 @@ export default memo(function BoroughData() {
if (borough !== '') {
setIsLoading(true);
setTimeframe(undefined);
getBoroughTimeframe(borough).then((newData) => {
getTimeframeData({ dock: { borough } }).then((newData) => {
setTimeframe(newData);
setIsLoading(false);
});
}
}, [borough]);

const toplineFetcherFunc = () => {
return getToplineBoroughData(borough);
};

const dataFetcherFunc: BoroughDataFetcherFunction = (
borough: string,
granularity: Granularity,
startDate: Date,
endDate: Date,
) => {
const daily = granularity === Granularity.Daily;
return getBoroughData(borough, daily, startDate, endDate);
return getChartData({ dock: { borough } }, daily, startDate, endDate);
};

return (
Expand Down Expand Up @@ -84,7 +84,7 @@ export default memo(function BoroughData() {
{!isLoading && timeframe !== undefined && (
<Topline
borough={borough}
dataFetcherFunc={toplineFetcherFunc}
dataFetcherFunc={() => getToplineData({ dock: { borough } })}
maxDate={timeframe.lastDate}
minDate={timeframe.firstDate}
/>
Expand Down
175 changes: 175 additions & 0 deletions app/CouncilDistrictData.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
'use client';

import { ChartData } from './action';
import DataContainer from './DataContainer';
import { Granularity } from './constants';
import LoadingSpinner from './LoadingSpinner';
import Topline from './Topline';
import {
Box,
FormControl,
InputLabel,
ListSubheader,
MenuItem,
Select,
} from '@mui/material';
import React, { memo } from 'react';
import {
Timeframe,
getChartData,
getCouncilDistricts,
getTimeframeData,
getToplineData,
} from './action';

export type CouncilDistrictDataFetcherFunction = (
councilDistrict: string,
granularity: Granularity,
startDate: Date,
endDate: Date,
) => Promise<ChartData[]>;

export default memo(function BoroughData() {
const [borough, setBorough] = React.useState<string | undefined>(undefined);
const [councilDistricts, setCouncilDistricts] = React.useState<
{ councilDistrict: number; borough: string }[]
>([]);
const [councilDistrict, setCouncilDistrict] = React.useState<
number | undefined
>(undefined);
const [councilDistrictsLoading, setCouncilDistrictsLoading] =
React.useState(false);
const [timeframe, setTimeframe] = React.useState<Timeframe | undefined>(
undefined,
);
const [isLoading, setIsLoading] = React.useState(false);

React.useEffect(() => {
setCouncilDistrictsLoading(true);
async function fn() {
const councilDistricts = await getCouncilDistricts();
setCouncilDistricts([...councilDistricts]);
setCouncilDistrictsLoading(false);
}
fn();
}, []);

React.useEffect(() => {
if (councilDistrict !== undefined) {
setIsLoading(true);
setTimeframe(undefined);
getTimeframeData({ dock: { councilDistrict } }).then((newData) => {
setTimeframe(newData);
setIsLoading(false);
});
}
}, [councilDistrict]);

const dataFetcherFunc: CouncilDistrictDataFetcherFunction = (
councilDistrict: string,
granularity: Granularity,
startDate: Date,
endDate: Date,
) => {
const daily = granularity === Granularity.Daily;
return getChartData(
{ dock: { councilDistrict: parseInt(councilDistrict) } },
daily,
startDate,
endDate,
);
};

const generateGroupedMenuItems = (
councilDistricts: { borough: string; councilDistrict: number }[],
) => {
let currentBorough = '';
const output: { borough?: string; councilDistrict?: number }[] = [];

councilDistricts.forEach((cd) => {
if (cd.borough !== currentBorough) {
currentBorough = cd.borough;
output.push({
borough: cd.borough === 'Bronx' ? 'The Bronx' : cd.borough,
});
}

output.push({ councilDistrict: cd.councilDistrict });
});

return output;
};
const groupedMenuItems = generateGroupedMenuItems(councilDistricts);

return (
<>
<Box sx={{ marginTop: 4, paddingTop: 1 }}>
<FormControl fullWidth>
<InputLabel id='council-district-options-label'>
Council District
</InputLabel>
<Select
disabled={councilDistrictsLoading}
labelId='council-district-options-label'
id='council-district-options'
value={councilDistrict}
label='council district'
onChange={(e) => {
setBorough(
councilDistricts.find(
(cd) => cd.councilDistrict === e.target.value,
)?.borough,
);
setCouncilDistrict(parseInt(`${e.target.value}`) ?? undefined);
}}
>
{groupedMenuItems.map(({ borough, councilDistrict }) => {
if (borough) {
return <ListSubheader key={borough}>{borough}</ListSubheader>;
} else {
return (
<MenuItem key={councilDistrict} value={councilDistrict}>
{councilDistrict}
</MenuItem>
);
}
})}
</Select>
</FormControl>
</Box>

{isLoading && (
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<LoadingSpinner />
</Box>
)}

{!isLoading && councilDistrict && timeframe !== undefined && (
<Topline
borough={borough}
councilDistrict={councilDistrict}
dataFetcherFunc={() => getToplineData({ dock: { councilDistrict } })}
maxDate={timeframe.lastDate}
minDate={timeframe.firstDate}
/>
)}

{councilDistrict && (
<Box sx={{ paddingBottom: 5 }}>
<DataContainer
dataFetcherFunc={dataFetcherFunc}
maxDate={timeframe?.lastDate}
minDate={timeframe?.firstDate}
userSelection={`${councilDistrict}`}
/>
</Box>
)}
</>
);
});
6 changes: 5 additions & 1 deletion app/DataContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { BoroughDataFetcherFunction } from './BoroughData';
import ChartContainer from './ChartContainer';
import ChartControls from './ChartControls';
import { ChartData } from './action';
import { CouncilDistrictDataFetcherFunction } from './CouncilDistrictData';
import { DockDataFetcherFunction } from './DockData';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { Granularity } from './constants';
Expand All @@ -25,7 +26,10 @@ export enum View {
Table,
}

type DataFetcherFunction = BoroughDataFetcherFunction | DockDataFetcherFunction;
type DataFetcherFunction =
| BoroughDataFetcherFunction
| CouncilDistrictDataFetcherFunction
| DockDataFetcherFunction;

export interface NamedChartData extends ChartData {
name: string;
Expand Down
24 changes: 15 additions & 9 deletions app/DockData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@ import {
} from '@mui/material';
import { ChartData, getMostRecentDateInDatabase } from './action';
import React, { SyntheticEvent, memo } from 'react';
import { Timeframe, getDockTimeframe } from './action';
import { getDockData, getDocks, getToplineDockData } from './action';
import {
Timeframe,
getChartData,
getDocks,
getTimeframeData,
getToplineData,
} from './action';

export type DockDataFetcherFunction = (
dockId: string,
Expand Down Expand Up @@ -98,25 +103,26 @@ export default memo(function DockData() {
if (dock.name !== '') {
setIsLoading(true);
setTimeframe(undefined);
getDockTimeframe(dock.id).then((newData) => {
getTimeframeData({ dockId: dock.id }).then((newData) => {
setTimeframe(newData);
setIsLoading(false);
});
}
}, [dock]);

const toplineFetcherFunc = () => {
return getToplineDockData(dock.id);
};

const dataFetcherFunc: DockDataFetcherFunction = (
dockId: string,
granularity: Granularity,
startDate: Date,
endDate: Date,
) => {
const daily = granularity === Granularity.Daily;
return getDockData(parseInt(dockId), daily, startDate, endDate);
return getChartData(
{ dockId: parseInt(dockId) },
daily,
startDate,
endDate,
);
};

const dataIsNotUpToDate = !!(
Expand Down Expand Up @@ -253,7 +259,7 @@ export default memo(function DockData() {
{!isLoading && dock.name !== '' && timeframe !== undefined && (
<Topline
borough={borough}
dataFetcherFunc={toplineFetcherFunc}
dataFetcherFunc={() => getToplineData({ dockId: dock.id })}
dockName={dock.name}
maxDate={timeframe.lastDate}
minDate={timeframe.firstDate}
Expand Down
26 changes: 20 additions & 6 deletions app/Topline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ function Bold({

export default function Topline({
borough,
councilDistrict,
dataFetcherFunc,
outOfDate,
dockName,
maxDate,
minDate,
}: {
borough: string;
borough?: string;
councilDistrict?: number;
dataFetcherFunc: () => Promise<ToplineData | undefined>;
outOfDate?: boolean;
dockName?: string;
Expand All @@ -42,14 +44,14 @@ export default function Topline({
const [isLoading, setIsLoading] = React.useState(false);

React.useEffect(() => {
if (borough || dockName) {
if (borough || dockName || councilDistrict) {
setIsLoading(true);
dataFetcherFunc().then((newData) => {
setData(newData);
setIsLoading(false);
});
}
}, [borough, dataFetcherFunc, dockName, minDate, maxDate]);
}, [borough, councilDistrict, dataFetcherFunc, dockName, minDate, maxDate]);

if (isLoading) {
return (
Expand Down Expand Up @@ -77,7 +79,10 @@ export default function Topline({
: 0;

let unit;
if (dockName) {

if (councilDistrict) {
unit = 'council district';
} else if (dockName) {
unit = 'dock';
} else if (borough) {
unit = 'borough';
Expand All @@ -99,10 +104,19 @@ export default function Topline({
has
</>
)}
{!dockName && borough && (
{councilDistrict && (
<>
Docks in
<Bold>{` ${borough === 'Bronx' ? 'The Bronx' : borough} `}</Bold>
<Bold>{` Council District ${councilDistrict} `}</Bold>
in
<Bold>{` ${borough === 'Bronx' ? 'the Bronx' : borough} `}</Bold>
have
</>
)}
{!dockName && !councilDistrict && borough && (
<>
Docks in
<Bold>{` ${borough === 'Bronx' ? 'the Bronx' : borough} `}</Bold>
have
</>
)}{' '}
Expand Down
Loading

0 comments on commit 33bb9ee

Please sign in to comment.