Convert src/ JavaScript modules to TypeScript
Renames every .js module under src/ to .ts (api, useResource, adminSchema, navConfig, adminNav and src/data/*) and points imports, comments and the seed script's module paths at the new names. Their types now come from inference; no .d.ts files and no shape interfaces. tsc stays strict (noImplicitAny off). The errors inference leaves behind get the lightest fix that clears them: `any` on empty state, contexts and list defaults, `: any` on components with optional or spread props, class fields on ApiError, and option shapes on get/useResource. Kept as real types, since they belong to modules that were already TypeScript and later features import them: PageShell's ShellSection and props, useContent's corrected record types (website/email/ instagram are bare strings) and EventListItem, and TimelineRef's orgKind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5cedc68fd7
commit
22d5328885
43 changed files with 195 additions and 135 deletions
|
|
@ -11,10 +11,10 @@
|
|||
|
||||
Two things live elsewhere:
|
||||
|
||||
the tile grid src/data/mapGrid.js. Where a state sits never
|
||||
the tile grid src/data/mapGrid.ts. Where a state sits never
|
||||
changes, so it isn't worth a round trip.
|
||||
|
||||
the fetch src/data/organizations.js. One endpoint for
|
||||
the fetch src/data/organizations.ts. One endpoint for
|
||||
every kind, so a section listing regions and
|
||||
a section listing partners read alike.
|
||||
═══════════════════════════════════════════════════════════════ */
|
||||
|
|
@ -25,12 +25,12 @@ import {
|
|||
areasSentence,
|
||||
initialsFor,
|
||||
useOrganizations,
|
||||
} from "./organizations.js";
|
||||
} from "./organizations.ts";
|
||||
import {
|
||||
areaForChapter,
|
||||
buildAreaSlices,
|
||||
countChaptersByArea,
|
||||
} from "./mapGrid.js";
|
||||
} from "./mapGrid.ts";
|
||||
|
||||
const byName = (a, b) => a.name.localeCompare(b.name);
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
One request, filtered per section. The Retreats page has three
|
||||
bands of events, and all three call this hook — the cache in
|
||||
api.js keys on the path, so they share a single fetch and each
|
||||
api.ts keys on the path, so they share a single fetch and each
|
||||
narrows the result to what it shows.
|
||||
|
||||
useEvents({ section: "national" }) one band
|
||||
|
|
@ -33,13 +33,13 @@
|
|||
|
||||
import { useMemo } from "react";
|
||||
|
||||
import { useResource } from "../lib/useResource.js";
|
||||
import { useResource } from "../lib/useResource.ts";
|
||||
|
||||
/* One shared empty list, so a memo keyed on `sections` doesn't
|
||||
restart on every render before the data arrives. */
|
||||
const NO_SECTIONS = [];
|
||||
const NO_SECTIONS: any[] = [];
|
||||
|
||||
export function useEvents({ section, host, status, type } = {}) {
|
||||
export function useEvents({ section, host, status, type }: any = {}) {
|
||||
const { data, error, loading } = useResource("/events");
|
||||
|
||||
const all = data?.events;
|
||||
|
|
@ -71,9 +71,9 @@ export function useEvents({ section, host, status, type } = {}) {
|
|||
/* Past and upcoming, split. `status` arrives already resolved — the
|
||||
explicit value when there is one, otherwise derived from ends_on
|
||||
— so nothing here needs to know which of the two it got. */
|
||||
export function splitByStatus(events = []) {
|
||||
const upcoming = [];
|
||||
const past = [];
|
||||
export function splitByStatus(events: any[] = []) {
|
||||
const upcoming: any[] = [];
|
||||
const past: any[] = [];
|
||||
|
||||
for (const event of events) {
|
||||
(event.status === "past" ? past : upcoming).push(event);
|
||||
|
|
@ -86,7 +86,7 @@ export function splitByStatus(events = []) {
|
|||
EVENT_TYPES order rather than whatever order the rows arrived
|
||||
in. A section with one type has nothing to filter, which is what
|
||||
lets the chip bar hide itself. */
|
||||
export function typesPresent(events = [], declared = []) {
|
||||
export function typesPresent(events: any[] = [], declared: any[] = []) {
|
||||
const seen = new Set(events.map(e => e.event_type));
|
||||
return declared.filter(entry => seen.has(entry.id));
|
||||
}
|
||||
|
|
@ -121,9 +121,9 @@ export function areaForChapter(chapter) {
|
|||
regionAreas [{ region_id, area_code, share, edge, note }]
|
||||
regions [{ id, name, color, ... }]
|
||||
───────────────────────────────────────────────────────────── */
|
||||
export function buildAreaSlices(regionAreas = [], regions = []) {
|
||||
export function buildAreaSlices(regionAreas: any[] = [], regions: any[] = []) {
|
||||
const regionById = Object.fromEntries(regions.map((r) => [r.id, r]));
|
||||
const byArea = {};
|
||||
const byArea: Record<string, any[]> = {};
|
||||
|
||||
for (const row of regionAreas) {
|
||||
const area = AREA_BY_CODE[row.area_code];
|
||||
|
|
@ -151,7 +151,7 @@ export function buildAreaSlices(regionAreas = [], regions = []) {
|
|||
/* ── Chapter counts per tile ───────────────────────────────────
|
||||
{ WA: 2, MO: 1, CANADA: 1 }
|
||||
───────────────────────────────────────────────────────────── */
|
||||
export function countChaptersByArea(chapters = []) {
|
||||
export function countChaptersByArea(chapters: any[] = []) {
|
||||
const counts = {};
|
||||
for (const chapter of chapters) {
|
||||
const code = areaForChapter(chapter);
|
||||
|
|
@ -165,7 +165,7 @@ export function countChaptersByArea(chapters = []) {
|
|||
from the row rather than being looked up in a splits table and
|
||||
branched on whether this region is the primary.
|
||||
───────────────────────────────────────────────────────────── */
|
||||
export function areasLabel(regionId, regionAreas = []) {
|
||||
export function areasLabel(regionId, regionAreas: any[] = []) {
|
||||
return regionAreas
|
||||
.filter((row) => row.region_id === regionId && row.area_code !== "CANADA")
|
||||
.map((row) => (row.note ? `${row.area_code} (${row.note})` : row.area_code))
|
||||
|
|
@ -18,12 +18,12 @@
|
|||
chapter { region_id, region_name, region_color, meets, started }
|
||||
partner {}
|
||||
|
||||
Each kind is a separate request path, so the cache in api.js
|
||||
Each kind is a separate request path, so the cache in api.ts
|
||||
keys them apart and two sections asking for regions share one
|
||||
fetch.
|
||||
═══════════════════════════════════════════════════════════════ */
|
||||
|
||||
import { useResource } from "../lib/useResource.js";
|
||||
import { useResource } from "../lib/useResource.ts";
|
||||
|
||||
const EMPTY = { organizations: [] };
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ export function orgPath(org) {
|
|||
any more.
|
||||
───────────────────────────────────────────────────────────── */
|
||||
|
||||
export function areasSentence(areas = []) {
|
||||
export function areasSentence(areas: any[] = []) {
|
||||
return areas
|
||||
.filter((area) => area.area_code !== "CANADA")
|
||||
.map((area) => (area.note ? `${area.area_code} (${area.note})` : area.area_code))
|
||||
Loading…
Add table
Add a link
Reference in a new issue