● Zion Boggan
repos/Docket/app/members/page.tsx
zionboggan.com ↗
147 lines · tsx
History for this file →
1
import type { Metadata } from "next";
2
import Link from "next/link";
3
import {
4
  getMembersDefault,
5
  getMemberCounts,
6
  getMemberStates,
7
} from "@/lib/feed";
8
import { Card, PageHeader } from "@/components/ui";
9
import { MembersBrowser } from "@/components/members-browser";
10
import { CiteThis } from "@/components/cite-this";
11
 
12
export const metadata: Metadata = {
13
  title: "Members of Congress",
14
  description:
15
    "Browse the U.S. House and Senate. Search by name, state, chamber, or party. Each member links to their full record.",
16
};
17
 
18
export const revalidate = 300;
19
 
20
export default function MembersPage() {
21
  const counts = getMemberCounts();
22
  const defaultMembers = getMembersDefault();
23
  const hiddenCount = counts.total - defaultMembers.length;
24
  const states = getMemberStates();
25
 
26
  return (
27
    <div
28
      className="mx-auto w-full max-w-[860px] px-6 sm:px-8"
29
      style={{
30
        paddingTop: "clamp(32px, 6vw, 56px)",
31
        paddingBottom: "clamp(48px, 8vw, 80px)",
32
      }}
33
    >
34
      {}
35
      <nav aria-label="Breadcrumb" className="mb-10">
36
        <ol className="flex flex-wrap items-center gap-2" style={{ marginBottom: "12px" }}>
37
          <li>
38
            <Link
39
              href="/"
40
              className="focus-ring label no-underline hover:underline"
41
              style={{ color: "var(--dk-signal)", fontSize: "12px", letterSpacing: "0.12em" }}
42
            >
43
              Home
44
            </Link>
45
          </li>
46
          <li aria-hidden="true" className="label" style={{ color: "var(--dk-ash-2)", fontSize: "12px" }}>/</li>
47
          <li
48
            className="label"
49
            style={{ color: "var(--dk-ash)", fontSize: "12px", letterSpacing: "0.12em" }}
50
            aria-current="page"
51
          >
52
            Representatives
53
          </li>
54
        </ol>
55
        <Link
56
          href="/"
57
          className="focus-ring tap no-underline hover:underline"
58
          style={{
59
            display: "inline-flex",
60
            alignItems: "center",
61
            gap: "8px",
62
            fontFamily: "var(--font-mono), ui-monospace, monospace",
63
            fontSize: "13px",
64
            letterSpacing: "0.08em",
65
            color: "var(--dk-signal)",
66
          }}
67
        >
68
          ← Back to home
69
        </Link>
70
      </nav>
71
 
72
      <PageHeader
73
        eyebrow="Congress roster"
74
        title="Representatives"
75
        lead="Search and filter the sitting House and Senate. Open a member to see their recorded votes, sponsored bills, and amendments - what your representative did, on the record."
76
      />
77
 
78
      <div>
79
        {
80
}
81
        <div className="grid gap-4 sm:grid-cols-3">
82
          <SummaryCard
83
            label="Currently serving"
84
            count={counts.currentTotal}
85
            sub={`${counts.total.toLocaleString()} on record, all Congresses`}
86
          />
87
          <SummaryCard
88
            label="Senate"
89
            count={counts.currentSenate}
90
            sub={`${counts.senate.toLocaleString()} on record`}
91
          />
92
          <SummaryCard
93
            label="House"
94
            count={counts.currentHouse}
95
            sub={`${counts.house.toLocaleString()} on record`}
96
          />
97
        </div>
98
 
99
        <div className="mt-10">
100
          <MembersBrowser
101
            seed={defaultMembers}
102
            states={states}
103
            hiddenCount={hiddenCount > 0 ? hiddenCount : 0}
104
          />
105
        </div>
106
      </div>
107
 
108
      {}
109
      <div
110
        style={{
111
          marginTop: "clamp(40px, 7vw, 72px)",
112
          borderTop: "1px solid var(--dk-line)",
113
          paddingTop: "clamp(24px, 4vw, 40px)",
114
        }}
115
      >
116
        <p className="label mb-4" style={{ color: "var(--dk-ash)" }}>Cite this page</p>
117
        <CiteThis
118
          kind="page"
119
          title="Members of Congress - Roster"
120
          permalink="https://usdocket.org/members"
121
          sourceUrl="https://bioguide.congress.gov/"
122
        />
123
      </div>
124
    </div>
125
  );
126
}
127
 
128
function SummaryCard({
129
  label,
130
  count,
131
  sub,
132
}: {
133
  label: string;
134
  count: number;
135
  sub?: string;
136
}) {
137
  return (
138
    <Card className="p-5">
139
      <p className="label mb-2">{label}</p>
140
      <div className="flex items-baseline gap-2">
141
        <span className="display text-3xl text-paper">{count.toLocaleString()}</span>
142
        <span className="label text-ash-2">members</span>
143
      </div>
144
      {sub ? <p className="label mt-2 text-ash-2">{sub}</p> : null}
145
    </Card>
146
  );
147
}