Skip to content

Commit 16c3235

Browse files
committed
Deduplicate state/jurisdiction references
1 parent ed85609 commit 16c3235

59 files changed

Lines changed: 229 additions & 363 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/src/content/docs/guides/building-forms.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import { defineForm } from "#lib/forms/defineForm";
3535
export default defineForm({
3636
title: "Court Order",
3737
description: "If you live in Massachusetts and want to update your name, this is the place to start.",
38-
state: "ma",
38+
jurisdiction: "ma",
3939
category: "court-order",
4040
steps: [
4141
// Step definitions...

pdf-manager/lib/fields.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ export function loadFormFields(): FormField[] {
4545
export function loadJurisdictions(): Jurisdiction[] {
4646
if (_jurisdictions) return _jurisdictions;
4747
const content = readFileSync(JURISDICTIONS_PATH, "utf8");
48-
const regex = /\{\s*name:\s*"([^"]+)",\s*abbreviation:\s*"([^"]+)"/g;
48+
const regex = /^\s*(\w{2}):\s*\{\s*name:\s*"([^"]+)"/gm;
4949
const result: Jurisdiction[] = [];
5050
for (const m of content.matchAll(regex)) {
51-
result.push({ name: m[1], abbreviation: m[2] });
51+
result.push({ name: m[2], abbreviation: m[1].toUpperCase() });
5252
}
5353
_jurisdictions = result;
5454
return _jurisdictions;

web/src/components/SupportMap.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { feature } from "topojson-client";
77
import type { GeometryCollection, Topology } from "topojson-specification";
88
import { formatStateList } from "#lib/utils/formatStateList";
99
10-
const stateEntries = await getCollection("states");
10+
const stateEntries = await getCollection("jurisdictions");
1111
1212
const stateSupport = stateEntries.reduce(
1313
(acc: Record<string, string>, entry) => {

web/src/components/forms/AddressField/AddressField.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ describe("AddressField", () => {
4747
// Select a state
4848
await userEvent.click(stateSelect);
4949
const californiaOption = screen.getByRole("option", {
50-
name: JURISDICTIONS.CA,
50+
name: JURISDICTIONS.ca.name,
5151
});
5252
await userEvent.click(californiaOption);
5353

@@ -238,7 +238,7 @@ describe("AddressField", () => {
238238
});
239239
await userEvent.click(stateSelect);
240240
const newYorkOption = screen.getByRole("option", {
241-
name: JURISDICTIONS.NY,
241+
name: JURISDICTIONS.ny.name,
242242
});
243243
await userEvent.click(newYorkOption);
244244

web/src/components/forms/AddressField/AddressField.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,9 @@ export function AddressField({
206206
errorMessage={error?.message}
207207
menuTrigger="focus"
208208
>
209-
{Object.entries(JURISDICTIONS).map(([value, label]) => (
210-
<ComboBoxItem key={value} id={value}>
211-
{label}
209+
{Object.entries(JURISDICTIONS).map(([id, j]) => (
210+
<ComboBoxItem key={id} id={id.toUpperCase()}>
211+
{j.name}
212212
</ComboBoxItem>
213213
))}
214214
</ComboBox>

web/src/constants/forms.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Step } from "#lib/forms/types";
22
import type { FormData } from "./fields";
3-
import type { StateId } from "./jurisdictions";
3+
import type { JurisdictionId } from "./jurisdictions";
44
import type { PDFId } from "./pdf";
55

66
export const FORM_SLUGS = [
@@ -80,8 +80,8 @@ export interface FormConfig {
8080
title: string;
8181
/** Optional description */
8282
description?: string;
83-
/** State abbreviation, e.g. "ma" */
84-
state?: StateId;
83+
/** Jurisdiction ID, e.g. "ma" */
84+
jurisdiction?: JurisdictionId;
8585
/** Category identifier */
8686
category: CategoryId;
8787
/** Costs associated with this form */

web/src/constants/jurisdictions.ts

Lines changed: 76 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,80 @@
1-
const usaStates = [
2-
{ name: "Alabama", abbreviation: "AL", territory: false },
3-
{ name: "Alaska", abbreviation: "AK", territory: false },
4-
{ name: "American Samoa", abbreviation: "AS", territory: true },
5-
{ name: "Arizona", abbreviation: "AZ", territory: false },
6-
{ name: "Arkansas", abbreviation: "AR", territory: false },
7-
{ name: "California", abbreviation: "CA", territory: false },
8-
{ name: "Colorado", abbreviation: "CO", territory: false },
9-
{ name: "Connecticut", abbreviation: "CT", territory: false },
10-
{ name: "Delaware", abbreviation: "DE", territory: false },
11-
{ name: "District Of Columbia", abbreviation: "DC", territory: false },
12-
{ name: "Florida", abbreviation: "FL", territory: false },
13-
{ name: "Georgia", abbreviation: "GA", territory: false },
14-
{ name: "Guam", abbreviation: "GU", territory: true },
15-
{ name: "Hawaii", abbreviation: "HI", territory: false },
16-
{ name: "Idaho", abbreviation: "ID", territory: false },
17-
{ name: "Illinois", abbreviation: "IL", territory: false },
18-
{ name: "Indiana", abbreviation: "IN", territory: false },
19-
{ name: "Iowa", abbreviation: "IA", territory: false },
20-
{ name: "Kansas", abbreviation: "KS", territory: false },
21-
{ name: "Kentucky", abbreviation: "KY", territory: false },
22-
{ name: "Louisiana", abbreviation: "LA", territory: false },
23-
{ name: "Maine", abbreviation: "ME", territory: false },
24-
{ name: "Maryland", abbreviation: "MD", territory: false },
25-
{ name: "Massachusetts", abbreviation: "MA", territory: false },
26-
{ name: "Michigan", abbreviation: "MI", territory: false },
27-
{ name: "Minnesota", abbreviation: "MN", territory: false },
28-
{ name: "Mississippi", abbreviation: "MS", territory: false },
29-
{ name: "Missouri", abbreviation: "MO", territory: false },
30-
{ name: "Montana", abbreviation: "MT", territory: false },
31-
{ name: "Nebraska", abbreviation: "NE", territory: false },
32-
{ name: "Nevada", abbreviation: "NV", territory: false },
33-
{ name: "New Hampshire", abbreviation: "NH", territory: false },
34-
{ name: "New Jersey", abbreviation: "NJ", territory: false },
35-
{ name: "New Mexico", abbreviation: "NM", territory: false },
36-
{ name: "New York", abbreviation: "NY", territory: false },
37-
{ name: "North Carolina", abbreviation: "NC", territory: false },
38-
{ name: "North Dakota", abbreviation: "ND", territory: false },
39-
{ name: "Northern Mariana Islands", abbreviation: "MP", territory: true },
40-
{ name: "Ohio", abbreviation: "OH", territory: false },
41-
{ name: "Oklahoma", abbreviation: "OK", territory: false },
42-
{ name: "Oregon", abbreviation: "OR", territory: false },
43-
{ name: "Pennsylvania", abbreviation: "PA", territory: false },
44-
{ name: "Puerto Rico", abbreviation: "PR", territory: true },
45-
{ name: "Rhode Island", abbreviation: "RI", territory: false },
46-
{ name: "South Carolina", abbreviation: "SC", territory: false },
47-
{ name: "South Dakota", abbreviation: "SD", territory: false },
48-
{ name: "Tennessee", abbreviation: "TN", territory: false },
49-
{ name: "Texas", abbreviation: "TX", territory: false },
50-
{ name: "Utah", abbreviation: "UT", territory: false },
51-
{ name: "Vermont", abbreviation: "VT", territory: false },
52-
{ name: "Virgin Islands", abbreviation: "VI", territory: true },
53-
{ name: "Virginia", abbreviation: "VA", territory: false },
54-
{ name: "Washington", abbreviation: "WA", territory: false },
55-
{ name: "West Virginia", abbreviation: "WV", territory: false },
56-
{ name: "Wisconsin", abbreviation: "WI", territory: false },
57-
{ name: "Wyoming", abbreviation: "WY", territory: false },
58-
] as const;
59-
601
/**
61-
* Jurisdictions, a.k.a. US States and territories.
2+
* Jurisdictions, a.k.a. US States and territories, keyed by lowercase
3+
* abbreviation (matching content collection jurisdiction IDs).
624
*/
63-
export const JURISDICTIONS = usaStates.reduce(
64-
(acc, state) => {
65-
acc[state.abbreviation] = state.name;
66-
return acc;
5+
export const JURISDICTIONS = {
6+
al: { name: "Alabama", territory: false, namesakeSupport: "none" },
7+
ak: { name: "Alaska", territory: false, namesakeSupport: "none" },
8+
as: { name: "American Samoa", territory: true, namesakeSupport: "none" },
9+
az: { name: "Arizona", territory: false, namesakeSupport: "none" },
10+
ar: { name: "Arkansas", territory: false, namesakeSupport: "none" },
11+
ca: { name: "California", territory: false, namesakeSupport: "none" },
12+
co: { name: "Colorado", territory: false, namesakeSupport: "none" },
13+
ct: { name: "Connecticut", territory: false, namesakeSupport: "none" },
14+
de: { name: "Delaware", territory: false, namesakeSupport: "none" },
15+
dc: {
16+
name: "District of Columbia",
17+
territory: false,
18+
namesakeSupport: "none",
6719
},
68-
{} as Record<string, string>,
69-
);
70-
71-
export type Jurisdiction = (typeof usaStates)[number]["abbreviation"];
20+
fl: { name: "Florida", territory: false, namesakeSupport: "none" },
21+
ga: { name: "Georgia", territory: false, namesakeSupport: "none" },
22+
gu: { name: "Guam", territory: true, namesakeSupport: "none" },
23+
hi: { name: "Hawaii", territory: false, namesakeSupport: "none" },
24+
id: { name: "Idaho", territory: false, namesakeSupport: "none" },
25+
il: { name: "Illinois", territory: false, namesakeSupport: "prioritized" },
26+
in: { name: "Indiana", territory: false, namesakeSupport: "none" },
27+
ia: { name: "Iowa", territory: false, namesakeSupport: "none" },
28+
ks: { name: "Kansas", territory: false, namesakeSupport: "none" },
29+
ky: { name: "Kentucky", territory: false, namesakeSupport: "none" },
30+
la: { name: "Louisiana", territory: false, namesakeSupport: "none" },
31+
me: { name: "Maine", territory: false, namesakeSupport: "none" },
32+
md: { name: "Maryland", territory: false, namesakeSupport: "none" },
33+
ma: { name: "Massachusetts", territory: false, namesakeSupport: "full" },
34+
mi: { name: "Michigan", territory: false, namesakeSupport: "none" },
35+
mn: { name: "Minnesota", territory: false, namesakeSupport: "none" },
36+
ms: { name: "Mississippi", territory: false, namesakeSupport: "none" },
37+
mo: { name: "Missouri", territory: false, namesakeSupport: "none" },
38+
mt: { name: "Montana", territory: false, namesakeSupport: "none" },
39+
ne: { name: "Nebraska", territory: false, namesakeSupport: "none" },
40+
nv: { name: "Nevada", territory: false, namesakeSupport: "none" },
41+
nh: { name: "New Hampshire", territory: false, namesakeSupport: "none" },
42+
nj: { name: "New Jersey", territory: false, namesakeSupport: "none" },
43+
nm: { name: "New Mexico", territory: false, namesakeSupport: "none" },
44+
ny: { name: "New York", territory: false, namesakeSupport: "prioritized" },
45+
nc: { name: "North Carolina", territory: false, namesakeSupport: "none" },
46+
nd: { name: "North Dakota", territory: false, namesakeSupport: "none" },
47+
mp: {
48+
name: "Northern Mariana Islands",
49+
territory: true,
50+
namesakeSupport: "none",
51+
},
52+
oh: { name: "Ohio", territory: false, namesakeSupport: "none" },
53+
ok: { name: "Oklahoma", territory: false, namesakeSupport: "none" },
54+
or: { name: "Oregon", territory: false, namesakeSupport: "none" },
55+
pa: { name: "Pennsylvania", territory: false, namesakeSupport: "none" },
56+
pr: { name: "Puerto Rico", territory: true, namesakeSupport: "none" },
57+
ri: { name: "Rhode Island", territory: false, namesakeSupport: "full" },
58+
sc: { name: "South Carolina", territory: false, namesakeSupport: "none" },
59+
sd: { name: "South Dakota", territory: false, namesakeSupport: "none" },
60+
tn: { name: "Tennessee", territory: false, namesakeSupport: "none" },
61+
tx: { name: "Texas", territory: false, namesakeSupport: "none" },
62+
ut: { name: "Utah", territory: false, namesakeSupport: "none" },
63+
vt: { name: "Vermont", territory: false, namesakeSupport: "none" },
64+
vi: { name: "Virgin Islands", territory: true, namesakeSupport: "none" },
65+
va: { name: "Virginia", territory: false, namesakeSupport: "none" },
66+
wa: { name: "Washington", territory: false, namesakeSupport: "none" },
67+
wv: { name: "West Virginia", territory: false, namesakeSupport: "none" },
68+
wi: { name: "Wisconsin", territory: false, namesakeSupport: "none" },
69+
wy: { name: "Wyoming", territory: false, namesakeSupport: "none" },
70+
} as const satisfies Record<
71+
string,
72+
{
73+
name: string;
74+
territory: boolean;
75+
namesakeSupport: "full" | "prioritized" | "none";
76+
}
77+
>;
7278

73-
/** Lowercase state/territory abbreviation, matching content collection state IDs. */
74-
export type StateId = Lowercase<Jurisdiction>;
79+
/** Lowercase state/territory abbreviation, matching content collection jurisdiction IDs. */
80+
export type JurisdictionId = keyof typeof JURISDICTIONS;

web/src/constants/pdf.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { FormData } from "./fields";
2-
import type { Jurisdiction } from "./jurisdictions";
2+
import type { JurisdictionId } from "./jurisdictions";
33

44
export type PDFFieldValue = string | boolean | undefined;
55

@@ -38,9 +38,9 @@ export interface PDFDefinition<TPdfFieldName extends string = string> {
3838

3939
/**
4040
* The jurisdiction of the form.
41-
* @example "MA"
41+
* @example "ma"
4242
*/
43-
jurisdiction?: Jurisdiction;
43+
jurisdiction?: JurisdictionId;
4444

4545
/**
4646
* The canonical URL of the original form. This should be a link to a .gov website or other official source.

web/src/content.config.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { z } from "astro/zod";
44
import { ANNOTATION_TYPES } from "./constants/annotations";
55
import { COLOR_KEYS } from "./constants/colors";
66
import type { FormConfig } from "./constants/forms";
7+
import { JURISDICTIONS } from "./constants/jurisdictions";
78
import type { PDFDefinition } from "./constants/pdf";
89
import { SERVICES } from "./constants/services";
910

@@ -39,7 +40,7 @@ const directory = defineCollection({
3940
z.object({
4041
name: z.string(),
4142
description: z.string(),
42-
states: z.array(reference("states")),
43+
jurisdictions: z.array(reference("jurisdictions")),
4344
url: z.url(),
4445
services: z.array(
4546
z.enum(SERVICES.map((s) => s.value) as [string, ...string[]]),
@@ -68,7 +69,7 @@ const forms = defineCollection({
6869
id,
6970
title: config.title,
7071
description: config.description,
71-
state: config.state,
72+
jurisdiction: config.jurisdiction,
7273
category: config.category,
7374
costs: config.costs,
7475
unlisted: config.unlisted ?? false,
@@ -78,7 +79,7 @@ const forms = defineCollection({
7879
schema: z.object({
7980
title: z.string(),
8081
description: z.string().optional(),
81-
state: reference("states").optional(),
82+
jurisdiction: reference("jurisdictions").optional(),
8283
category: reference("categories"),
8384
unlisted: z.boolean().default(false),
8485
costs: z
@@ -98,13 +99,28 @@ const guides = defineCollection({
9899
schema: z.object({
99100
title: z.string(),
100101
description: z.string().optional(),
101-
state: reference("states").optional(),
102+
jurisdiction: reference("jurisdictions").optional(),
102103
category: reference("categories"),
103104
stub: z.boolean().default(false),
104105
unlisted: z.boolean().default(false),
105106
}),
106107
});
107108

109+
const jurisdictions = defineCollection({
110+
loader: () =>
111+
Object.entries(JURISDICTIONS).map(([id, jurisdiction]) => ({
112+
id,
113+
name: jurisdiction.name,
114+
territory: jurisdiction.territory,
115+
namesakeSupport: jurisdiction.namesakeSupport,
116+
})),
117+
schema: z.object({
118+
name: z.string(),
119+
territory: z.boolean(),
120+
namesakeSupport: z.enum(["full", "prioritized", "none"]),
121+
}),
122+
});
123+
108124
const pages = defineCollection({
109125
loader: glob({ base: "./src/content/pages", pattern: "**/*.md" }),
110126
schema: z.object({
@@ -128,15 +144,15 @@ const pdfs = defineCollection({
128144
id,
129145
title: config.title,
130146
code: config.code,
131-
state: config.jurisdiction?.toLowerCase(),
147+
jurisdiction: config.jurisdiction,
132148
canonicalUrl: config.canonicalUrl,
133149
};
134150
});
135151
},
136152
schema: z.object({
137153
title: z.string(),
138154
code: z.string().optional(),
139-
state: reference("states").optional(),
155+
jurisdiction: reference("jurisdictions").optional(),
140156
canonicalUrl: z.url(),
141157
}),
142158
});
@@ -187,24 +203,16 @@ const sponsors = defineCollection({
187203
}),
188204
});
189205

190-
const states = defineCollection({
191-
loader: file("./src/content/states/states.yml"),
192-
schema: z.object({
193-
name: z.string(),
194-
namesakeSupport: z.enum(["full", "prioritized", "none"]),
195-
}),
196-
});
197-
198206
export const collections = {
199207
authors,
200208
categories,
201209
directory,
202210
forms,
203211
guides,
212+
jurisdictions,
204213
pages,
205214
pdfs,
206215
posts,
207216
press,
208217
sponsors,
209-
states,
210218
};

web/src/content/directory/atls/index.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Advocates for Trans* Law Students
22
description: Advocates for Trans* Law Students (ATLS) is the nation's first transgender law student advocacy group, aiming to provide support, community, and advocacy for TNBGNC students at Fordham Law School.
3-
states:
3+
jurisdictions:
44
- ny
55
url: https://www.advocatesfortranslaw.org/
66
services:

0 commit comments

Comments
 (0)