● Zion Boggan
repos/Docket/app/bills/page.tsx
zionboggan.com ↗
201 lines · tsx
History for this file →
1
import type { Metadata } from "next";
2
import Link from "next/link";
3
import { Suspense } from "react";
4
import { getPolicyAreaLabels, getBillCongresses } from "@/lib/feed";
5
import { CiteThis } from "@/components/cite-this";
6
import { BillsBrowser } from "@/components/bills-browser";
7
 
8
export const revalidate = 300;
9
 
10
export const metadata: Metadata = {
11
  title: "Bills",
12
  description:
13
    "Browse bills by policy area. Each bill links to its sponsor, status timeline, and the official record.",
14
};
15
 
16
export default function BillsPage() {
17
  const policyAreas = getPolicyAreaLabels();
18
  const congresses = getBillCongresses();
19
 
20
  return (
21
    <div
22
      className="mx-auto w-full max-w-[860px] px-6 sm:px-8"
23
      style={{
24
        paddingTop: "clamp(32px, 6vw, 56px)",
25
        paddingBottom: "clamp(48px, 8vw, 80px)",
26
      }}
27
    >
28
      {}
29
      <nav aria-label="Breadcrumb" className="mb-10">
30
        <ol className="flex flex-wrap items-center gap-2" style={{ marginBottom: "12px" }}>
31
          <li>
32
            <Link
33
              href="/"
34
              className="focus-ring label no-underline hover:underline"
35
              style={{ color: "var(--dk-signal)", fontSize: "12px", letterSpacing: "0.12em" }}
36
            >
37
              Home
38
            </Link>
39
          </li>
40
          <li aria-hidden="true" className="label" style={{ color: "var(--dk-ash-2)", fontSize: "12px" }}>
41
            /
42
          </li>
43
          <li
44
            className="label"
45
            style={{ color: "var(--dk-ash)", fontSize: "12px", letterSpacing: "0.12em" }}
46
            aria-current="page"
47
          >
48
            Bills
49
          </li>
50
        </ol>
51
        <Link
52
          href="/"
53
          className="focus-ring tap no-underline hover:underline"
54
          style={{
55
            display: "inline-flex",
56
            alignItems: "center",
57
            gap: "8px",
58
            fontFamily: "var(--font-mono), ui-monospace, monospace",
59
            fontSize: "13px",
60
            letterSpacing: "0.08em",
61
            color: "var(--dk-signal)",
62
          }}
63
        >
64
          ← Back to home
65
        </Link>
66
      </nav>
67
 
68
      {}
69
      <header
70
        style={{
71
          borderBottom: "1px solid var(--dk-line)",
72
          paddingBottom: "clamp(28px, 5vw, 48px)",
73
          marginBottom: "clamp(28px, 5vw, 48px)",
74
        }}
75
      >
76
        {}
77
        <p
78
          className="label"
79
          style={{
80
            color: "var(--dk-signal)",
81
            marginBottom: "20px",
82
            display: "flex",
83
            alignItems: "center",
84
            gap: "8px",
85
            fontSize: "12px",
86
            letterSpacing: "0.14em",
87
          }}
88
        >
89
          <span
90
            aria-hidden="true"
91
            style={{
92
              width: "5px",
93
              height: "5px",
94
              borderRadius: "50%",
95
              background: "var(--dk-signal)",
96
              display: "inline-block",
97
              flexShrink: 0,
98
            }}
99
          />
100
          Legislation
101
        </p>
102
        {}
103
        <h1
104
          className="font-display text-paper"
105
          style={{
106
            fontSize: "clamp(2.2rem, 7vw, 3.75rem)",
107
            fontWeight: 900,
108
            lineHeight: 1.0,
109
            letterSpacing: "-0.01em",
110
            wordSpacing: "0.06em",
111
            textTransform: "uppercase",
112
            maxWidth: "18ch",
113
            marginBottom: "24px",
114
          }}
115
        >
116
          All Bills
117
        </h1>
118
        {}
119
        <p
120
          className="font-prose"
121
          style={{
122
            fontStyle: "italic",
123
            fontSize: "clamp(1rem, 1.8vw, 1.125rem)",
124
            lineHeight: 1.55,
125
            color: "var(--dk-ash)",
126
            maxWidth: "52ch",
127
          }}
128
        >
129
          Bills on record, newest action first. Filter by policy area, congress,
130
          or search by title or number. Each bill links to its sponsor, status
131
          timeline, and the official record.
132
        </p>
133
        <p style={{ marginTop: "20px" }}>
134
          <Link
135
            href="/laws"
136
            className="focus-ring no-underline"
137
            style={{
138
              display: "inline-flex",
139
              alignItems: "center",
140
              gap: "8px",
141
              minHeight: "44px",
142
              padding: "0 16px",
143
              border: "1px solid var(--dk-line)",
144
              borderRadius: "8px",
145
              background: "var(--dk-surface)",
146
              fontFamily: "var(--font-mono), ui-monospace, monospace",
147
              fontSize: "12px",
148
              letterSpacing: "0.08em",
149
              textTransform: "uppercase",
150
              color: "var(--dk-signal)",
151
            }}
152
          >
153
            Became law → View Public Laws
154
          </Link>
155
        </p>
156
      </header>
157
 
158
      {}
159
      <Suspense fallback={<BillsSkeleton />}>
160
        <BillsBrowser policyAreas={policyAreas} congresses={congresses} />
161
      </Suspense>
162
 
163
      {}
164
      <div
165
        style={{
166
          marginTop: "clamp(40px, 7vw, 72px)",
167
          borderTop: "1px solid var(--dk-line)",
168
          paddingTop: "clamp(24px, 4vw, 40px)",
169
        }}
170
      >
171
        <p className="label mb-8" style={{ color: "var(--dk-ash-2)" }}>
172
          Bills sourced from congress.gov. Order is by last action date -no
173
          editorial weighting. No comment surface appears here, by policy.
174
        </p>
175
        <p className="label mb-4" style={{ color: "var(--dk-ash)" }}>
176
          Cite this page
177
        </p>
178
        <CiteThis
179
          kind="page"
180
          title="Bills -Browse all bills"
181
          permalink="https://usdocket.org/bills"
182
          sourceUrl="https://www.congress.gov/browse/bills"
183
        />
184
      </div>
185
    </div>
186
  );
187
}
188
 
189
function BillsSkeleton() {
190
  return (
191
    <div className="mt-8">
192
      <div className="h-14 w-full animate-pulse rounded-sm bg-graphite" />
193
      <div className="mt-8 mb-4 h-4 w-40 animate-pulse rounded-sm bg-graphite" />
194
      <div className="space-y-3">
195
        {Array.from({ length: 16 }).map((_, i) => (
196
          <div key={i} className="h-24 w-full animate-pulse rounded-sm bg-graphite" />
197
        ))}
198
      </div>
199
    </div>
200
  );
201
}