Skip to content

Commit

Permalink
feat(user counties): Add get counties hook to pull user state counties (
Browse files Browse the repository at this point in the history
#762)

* working through api logic

* figuring out logic to call get counties

* add get county logic to user context

* Update states.ts

* Update user.ts

* clean up logic

* Update userContext.tsx

* Update userContext.tsx

* Update userContext.tsx

* Update userContext.tsx

* Update userContext.tsx

* add optional chain

* add feedback to apiCall logic

* Update SlotField.tsx

* wrap in try catch

* adjust array name

* add bens feedback

* Update useGetUser.ts

* Update user.ts
  • Loading branch information
jdinh8124 committed Sep 11, 2024
1 parent 1f2e368 commit 59602c4
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 10 deletions.
1 change: 1 addition & 0 deletions lib/packages/shared-types/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type SelectProps = React.ComponentPropsWithoutRef<
> & {
options: { label: string; value: any }[];
className?: string;
apiCall?: string;
};

export interface MultiselectOption {
Expand Down
59 changes: 59 additions & 0 deletions lib/packages/shared-types/states.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,62 @@ export const STATE_CODES = [
"ZZ",
] as const;
export type StateCode = (typeof STATE_CODES)[number];

export const FULL_CENSUS_STATES = [
{ label: "Alabama", value: "AL", code: "01" },
{ label: "Alaska", value: "AK", code: "02" },
{ label: "American Samoa", value: "AS", code: "00" },
{ label: "Arizona", value: "AZ", code: "04" },
{ label: "Arkansas", value: "AR", code: "05" },
{ label: "California", value: "CA", code: "06" },
{ label: "Colorado", value: "CO", code: "08" },
{ label: "Connecticut", value: "CT", code: "09" },
{ label: "Delaware", value: "DE", code: "10" },
{ label: "District of Columbia", value: "DC", code: "11" },
{ label: "Florida", value: "FL", code: "12" },
{ label: "Georgia", value: "GA", code: "13" },
{ label: "Guam", value: "GU", code: "00" },
{ label: "Hawaii", value: "HI", code: "15" },
{ label: "Idaho", value: "ID", code: "16" },
{ label: "Illinois", value: "IL", code: "17" },
{ label: "Indiana", value: "IN", code: "18" },
{ label: "Iowa", value: "IA", code: "19" },
{ label: "Kansas", value: "KS", code: "20" },
{ label: "Kentucky", value: "KY", code: "21" },
{ label: "Louisiana", value: "LA", code: "22" },
{ label: "Maine", value: "ME", code: "23" },
{ label: "Maryland", value: "MD", code: "24" },
{ label: "Massachusetts", value: "MA", code: "25" },
{ label: "Michigan", value: "MI", code: "26" },
{ label: "Minnesota", value: "MN", code: "27" },
{ label: "Mississippi", value: "MS", code: "28" },
{ label: "Missouri", value: "MO", code: "29" },
{ label: "Montana", value: "MT", code: "30" },
{ label: "Nebraska", value: "NE", code: "31" },
{ label: "Nevada", value: "NV", code: "32" },
{ label: "New Hampshire", value: "NH", code: "33" },
{ label: "New Jersey", value: "NJ", code: "34" },
{ label: "New Mexico", value: "NM", code: "35" },
{ label: "New York", value: "NY", code: "36" },
{ label: "North Carolina", value: "NC", code: "37" },
{ label: "North Dakota", value: "ND", code: "38" },
{ label: "Northern Mariana Islands", value: "MP", code: "00" },
{ label: "Ohio", value: "OH", code: "39" },
{ label: "Oklahoma", value: "OK", code: "40" },
{ label: "Oregon", value: "OR", code: "41" },
{ label: "Pennsylvania", value: "PA", code: "42" },
{ label: "Puerto Rico", value: "PR", code: "72" },
{ label: "Rhode Island", value: "RI", code: "44" },
{ label: "South Carolina", value: "SC", code: "45" },
{ label: "South Dakota", value: "SD", code: "46" },
{ label: "Tennessee", value: "TN", code: "47" },
{ label: "Texas", value: "TX", code: "48" },
{ label: "Utah", value: "UT", code: "49" },
{ label: "Vermont", value: "VT", code: "50" },
{ label: "Virgin Islands", value: "VI", code: "00" },
{ label: "Virginia", value: "VA", code: "51" },
{ label: "Washington", value: "WA", code: "53" },
{ label: "West Virginia", value: "WV", code: "54" },
{ label: "Wisconsin", value: "WI", code: "55" },
{ label: "Wyoming", value: "WY", code: "56" },
];
1 change: 1 addition & 0 deletions react-app/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from "./useGetTypes";
export * from "./amplifyConfig";
export * from "./submissionService";
export * from "./itemExists";
export * from "./useGetCounties";
35 changes: 35 additions & 0 deletions react-app/src/api/useGetCounties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useQuery } from "@tanstack/react-query";

const fetchPopulationData = async (stateString: string) => {
try {
if (stateString) {
const response = await fetch(
`https://api.census.gov/data/2019/pep/population?get=NAME&for=county:*&in=state:${stateString}`,
);
if (!response.ok) {
throw new Error("Failed to fetch county data");
}

const data = await response.json();
return data.slice(1).map((item) => item[0]);
}
return [];
} catch (error) {
console.error("Error fetching county data:", error);
throw error;
}
};

export const usePopulationData = (stateString: string) => {
return useQuery(
["populationData", stateString],
() => fetchPopulationData(stateString),
{
refetchOnWindowFocus: false,
refetchOnReconnect: false,
refetchOnMount: false,
},
);
};

export default usePopulationData;
1 change: 1 addition & 0 deletions react-app/src/api/useGetUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { isCmsUser } from "shared-utils";
export type OneMacUser = {
isCms?: boolean;
user: CognitoUserAttributes | null;
counties?: { label: string; value: string }[];
};

export const getUser = async (): Promise<OneMacUser> => {
Expand Down
56 changes: 52 additions & 4 deletions react-app/src/components/Context/userContext.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,61 @@
import { OneMacUser, useGetUser } from "@/api";
import { PropsWithChildren, createContext, useContext } from "react";
import { PropsWithChildren, createContext, useContext, useMemo } from "react";
import { getUserStateCodes } from "@/utils";
import { usePopulationData } from "@/api";
import { FULL_CENSUS_STATES } from "shared-types";

const initialState = { user: null };
const initialState = { user: null, counties: [] };

export const UserContext = createContext<OneMacUser | undefined>(initialState);

export const UserContextProvider = ({ children }: PropsWithChildren) => {
const { data: userData } = useGetUser();
const { data: userData, error: userError } = useGetUser();

const stateCodes = useMemo(
() => getUserStateCodes(userData?.user),
[userData],
);

const stateNumericCodesString = useMemo(
() =>
stateCodes
.map(
(code) =>
FULL_CENSUS_STATES.find((state) => state.value === code)?.code,
)
.filter((code): code is string => code !== undefined && code !== "00")
.join(","),
[stateCodes],
);

const { data: populationData, error: populationError } = usePopulationData(
stateNumericCodesString,
);

const counties = useMemo(
() =>
populationData?.map((county) => {
const [label] = county.split(",");
return { label, value: county };
}) ?? [],
[populationData],
);

const contextValue = useMemo(
() => ({
user: userData?.user ?? null,
counties,
}),
[userData, counties],
);

if (userError || populationError) {
console.error("Error fetching data:", userError || populationError);
return null;
}

return (
<UserContext.Provider value={userData}>{children}</UserContext.Provider>
<UserContext.Provider value={contextValue}>{children}</UserContext.Provider>
);
};

Expand Down
33 changes: 27 additions & 6 deletions react-app/src/components/RHF/SlotField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ import {
import { CalendarIcon } from "lucide-react";
import { format } from "date-fns";
import { cn } from "@/utils";
import { Popover, PopoverContent, PopoverTrigger } from "@/components";
import {
Popover,
PopoverContent,
PopoverTrigger,
useUserContext,
} from "@/components";
import {
DependencyWrapper,
RHFFieldArray,
Expand Down Expand Up @@ -57,6 +62,8 @@ export const SlotField = ({
horizontalLayout,
index,
}: SlotFieldProps) => {
const userContext = useUserContext();

switch (rhf) {
case "Input":
return <Input {...props} {...field} aria-label={field.name} />;
Expand Down Expand Up @@ -90,11 +97,25 @@ export const SlotField = ({
/>
);
case "Select": {
const opts = props?.options.sort((a, b) =>
props.customSort
? sortFunctions[props.customSort](a.label, b.label)
: stringCompare(a, b),
);
let opts;
switch (props?.apiCall) {
case undefined:
opts = props?.options?.sort((a, b) =>
props.customSort
? sortFunctions[props.customSort](a.label, b.label)
: stringCompare(a, b),
);
break;

case "countySelect":
opts =
userContext?.counties?.sort((a, b) =>
props.customSort
? sortFunctions[props.customSort](a.label, b.label)
: stringCompare(a, b),
) || [];
break;
}

return (
<Select
Expand Down

0 comments on commit 59602c4

Please sign in to comment.