Skip to content

Commit

Permalink
Preload docks, etc (#39)
Browse files Browse the repository at this point in the history
Preloads docks, community districts, council districts

Simplifies lots of code and also should speed things up
  • Loading branch information
zack authored Jul 25, 2024
1 parent 308c741 commit 44c305a
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 148 deletions.
21 changes: 21 additions & 0 deletions CouncilDistrictsProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use client';

import React from 'react';

import { createContext } from 'react';

export const CouncilDistrictsContext = createContext<number[]>([]);

export default function CouncilDistrictsProvider({
councilDistricts,
children,
}: {
councilDistricts: number[];
children: React.ReactNode;
}) {
return (
<CouncilDistrictsContext.Provider value={councilDistricts}>
{children}
</CouncilDistrictsContext.Provider>
);
}
44 changes: 33 additions & 11 deletions app/BoroughData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@ import DataContainer from './DataContainer';
import { Granularity } from './constants';
import LoadingSpinner from './LoadingSpinner';
import Topline from './Topline';
import { isBorough } from './utils';
import {
Borough,
Timeframe,
getChartData,
getTimeframeData,
getToplineData,
} from './action';
import {
Box,
FormControl,
InputLabel,
MenuItem,
Select,
SelectChangeEvent,
Typography,
} from '@mui/material';
import React, { memo } from 'react';
import {
Timeframe,
getChartData,
getTimeframeData,
getToplineData,
} from './action';

export type BoroughDataFetcherFunction = (
borough: string,
Expand All @@ -29,14 +32,21 @@ export type BoroughDataFetcherFunction = (
) => Promise<ChartData[]>;

export default memo(function BoroughData() {
const [borough, setBorough] = React.useState<string | undefined>(undefined);
const [borough, setBorough] = React.useState<Borough | undefined>(undefined);
const [timeframe, setTimeframe] = React.useState<Timeframe | undefined>(
undefined,
);
const [isLoading, setIsLoading] = React.useState(false);

function handleBoroughChange(event: SelectChangeEvent<Borough>) {
const value = event.target.value;
if (isBorough(value)) {
setBorough(value);
}
}

React.useEffect(() => {
if (borough !== undefined) {
if (borough) {
setIsLoading(true);
setTimeframe(undefined);
getTimeframeData({ dock: { borough } }).then((newData) => {
Expand All @@ -53,7 +63,19 @@ export default memo(function BoroughData() {
endDate: Date,
) => {
const daily = granularity === Granularity.Daily;
return getChartData({ dock: { borough } }, daily, startDate, endDate);

// Unfortunately due to how the function is used, we cannot require the
// borough parameter is Borough
if (isBorough(borough)) {
return getChartData({ dock: { borough } }, daily, startDate, endDate);
} else {
return getChartData(
{ dock: { borough: 'Brooklyn' } },
daily,
startDate,
endDate,
);
}
};

return (
Expand All @@ -66,7 +88,7 @@ export default memo(function BoroughData() {
id='borough-options'
value={borough}
label='borough'
onChange={(e) => setBorough(e.target.value)}
onChange={handleBoroughChange}
>
<MenuItem value={'Bronx'}> The Bronx </MenuItem>
<MenuItem value={'Brooklyn'}> Brooklyn </MenuItem>
Expand All @@ -88,7 +110,7 @@ export default memo(function BoroughData() {
</Box>
)}

{!isLoading && borough === undefined && (
{!isLoading && !borough && (
<Box
sx={{
display: 'flex',
Expand Down
52 changes: 18 additions & 34 deletions app/CommunityDistrictData.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { ChartData } from './action';
import { CommunityDistrictsContext } from './CommunityDistrictsProvider';
import DataContainer from './DataContainer';
import { Granularity } from './constants';
import LoadingSpinner from './LoadingSpinner';
Expand All @@ -14,11 +15,10 @@ import {
Select,
Typography,
} from '@mui/material';
import React, { memo } from 'react';
import React, { memo, useContext } from 'react';
import {
Timeframe,
getChartData,
getCommunityDistricts,
getTimeframeData,
getToplineData,
} from './action';
Expand All @@ -32,28 +32,15 @@ export type CommunityDistrictDataFetcherFunction = (

export default memo(function CommunityDistrictData() {
const [borough, setBorough] = React.useState<string | undefined>(undefined);
const [communityDistricts, setCommunityDistricts] = React.useState<
{ communityDistrict: number; borough: string }[]
>([]);
const [communityDistrict, setCommunityDistrict] = React.useState<
number | undefined
>(undefined);
const [communityDistrictsLoading, setCommunityDistrictsLoading] =
React.useState(false);
const [timeframe, setTimeframe] = React.useState<Timeframe | undefined>(
undefined,
);
const [isLoading, setIsLoading] = React.useState(false);

React.useEffect(() => {
setCommunityDistrictsLoading(true);
async function fn() {
const communityDistricts = await getCommunityDistricts();
setCommunityDistricts([...communityDistricts]);
setCommunityDistrictsLoading(false);
}
fn();
}, []);
const communityDistricts = useContext(CommunityDistrictsContext);

React.useEffect(() => {
if (communityDistrict !== undefined) {
Expand Down Expand Up @@ -107,10 +94,9 @@ export default memo(function CommunityDistrictData() {
<Box sx={{ marginTop: 4, paddingTop: 1 }}>
<FormControl fullWidth>
<InputLabel id='community-district-options-label'>
Community District{communityDistrictsLoading && 's Loading...'}
Community District
</InputLabel>
<Select
disabled={communityDistrictsLoading}
labelId='community-district-options-label'
id='community-district-options'
value={communityDistrict}
Expand Down Expand Up @@ -151,22 +137,20 @@ export default memo(function CommunityDistrictData() {
</Box>
)}

{!isLoading
&& !communityDistrictsLoading
&& communityDistrict === undefined && (
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
}}
>
<Typography>
<>Select a community district to see some data.</>
</Typography>
</Box>
)}
{!isLoading && communityDistrict === undefined && (
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
}}
>
<Typography>
<>Select a community district to see some data.</>
</Typography>
</Box>
)}

{!isLoading && communityDistrict && timeframe !== undefined && (
<Topline
Expand Down
23 changes: 23 additions & 0 deletions app/CommunityDistrictsProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use client';

import { CommunityDistrict } from './action';

import React from 'react';

import { createContext } from 'react';

export const CommunityDistrictsContext = createContext<CommunityDistrict[]>([]);

export default function CommunityDistrictsProvider({
communityDistricts,
children,
}: {
communityDistricts: CommunityDistrict[];
children: React.ReactNode;
}) {
return (
<CommunityDistrictsContext.Provider value={communityDistricts}>
{children}
</CommunityDistrictsContext.Provider>
);
}
52 changes: 18 additions & 34 deletions app/CouncilDistrictData.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { ChartData } from './action';
import { CouncilDistrictsContext } from './CouncilDistrictsProvider';
import DataContainer from './DataContainer';
import { Granularity } from './constants';
import LoadingSpinner from './LoadingSpinner';
Expand All @@ -14,11 +15,10 @@ import {
Select,
Typography,
} from '@mui/material';
import React, { memo } from 'react';
import React, { memo, useContext } from 'react';
import {
Timeframe,
getChartData,
getCouncilDistricts,
getTimeframeData,
getToplineData,
} from './action';
Expand All @@ -32,28 +32,15 @@ export type CouncilDistrictDataFetcherFunction = (

export default memo(function CouncilDistrictData() {
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();
}, []);
const councilDistricts = useContext(CouncilDistrictsContext);

React.useEffect(() => {
if (councilDistrict !== undefined) {
Expand Down Expand Up @@ -107,10 +94,9 @@ export default memo(function CouncilDistrictData() {
<Box sx={{ marginTop: 4, paddingTop: 1 }}>
<FormControl fullWidth>
<InputLabel id='council-district-options-label'>
Council District{councilDistrictsLoading && 's Loading...'}
Council District
</InputLabel>
<Select
disabled={councilDistrictsLoading}
labelId='council-district-options-label'
id='council-district-options'
value={councilDistrict}
Expand Down Expand Up @@ -151,22 +137,20 @@ export default memo(function CouncilDistrictData() {
</Box>
)}

{!isLoading
&& !councilDistrictsLoading
&& councilDistrict === undefined && (
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
}}
>
<Typography>
<>Select a council district to see some data.</>
</Typography>
</Box>
)}
{!isLoading && councilDistrict === undefined && (
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
}}
>
<Typography>
<>Select a council district to see some data.</>
</Typography>
</Box>
)}

{!isLoading && councilDistrict && timeframe !== undefined && (
<Topline
Expand Down
23 changes: 23 additions & 0 deletions app/CouncilDistrictsProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use client';

import { CouncilDistrict } from './action';

import React from 'react';

import { createContext } from 'react';

export const CouncilDistrictsContext = createContext<CouncilDistrict[]>([]);

export default function CouncilDistrictsProvider({
councilDistricts,
children,
}: {
councilDistricts: CouncilDistrict[];
children: React.ReactNode;
}) {
return (
<CouncilDistrictsContext.Provider value={councilDistricts}>
{children}
</CouncilDistrictsContext.Provider>
);
}
Loading

0 comments on commit 44c305a

Please sign in to comment.