Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion components/bill/BillTracker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Stage, useBillTracker } from "components/db/useBillStatus"
import styled from "styled-components"
import { BillProps, BillTracker } from "./types"
import { Row } from "react-bootstrap"
import { useTranslation } from "next-i18next"

export default function BillTrackerConnectedView({
bill,
Expand Down Expand Up @@ -31,7 +32,13 @@ export const BillTrackerView = ({
))}
</Row>
)
return <MapleCard className={className} header="Bill Tracker" body={body} />
return (
<MapleCard
className={className}
header={useTranslation("common").t("bill.bill_tracker")}
body={body}
/>
)
}

export const BillStageStrip = ({
Expand Down
11 changes: 6 additions & 5 deletions components/bill/Cosponsors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { MemberReference, useMember } from "../db"
import { memberLink } from "../links"
import { FC } from "../types"
import { BillProps } from "./types"
import { useTranslation } from "next-i18next"

const CoSponsorRow = ({
court,
Expand All @@ -13,9 +14,6 @@ const CoSponsorRow = ({
court: number
coSponsor: MemberReference
}) => {
const url = coSponsor
? `https://malegislature.gov/Legislators/Profile/${coSponsor.Id}`
: ""
const { member, loading } = useMember(court, coSponsor.Id)
if (loading) {
return null
Expand Down Expand Up @@ -66,7 +64,6 @@ export const Cosponsors: FC<React.PropsWithChildren<BillProps>> = ({
bill,
children
}) => {
const billNumber = bill.id
const court = bill.court
const coSponsors = bill.content.Cosponsors
const numCoSponsors = coSponsors ? coSponsors.length : 0
Expand All @@ -93,7 +90,11 @@ export const Cosponsors: FC<React.PropsWithChildren<BillProps>> = ({
size="lg"
>
<Modal.Header closeButton onClick={handleCloseBillCosponsors}>
<Modal.Title>{billNumber + " CoSponsors"}</Modal.Title>
<Modal.Title>
{useTranslation("common").t("bill.bill_cosponsors", {
billId: bill.id
})}
</Modal.Title>
</Modal.Header>
<Modal.Body>
<>
Expand Down
6 changes: 4 additions & 2 deletions components/bill/HistoryModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ import styled from "styled-components"
import { Button, Modal } from "../bootstrap"
import { HistoryTable } from "./HistoryTable"
import { BillProps } from "./types"
import { useTranslation } from "next-i18next"

export const HistoryModal = ({ bill }: BillProps) => {
const [showBillHistory, setShowBillHistory] = useState(false)
const handleShowBillHistory = () => setShowBillHistory(true)
const handleCloseBillHistory = () => setShowBillHistory(false)
const { t } = useTranslation("common")

return (
<>
<Button variant="primary" className="m-1" onClick={handleShowBillHistory}>
History
{t("bill.history")}
</Button>
<Modal show={showBillHistory} onHide={handleCloseBillHistory} size="lg">
<Modal.Header closeButton onClick={handleCloseBillHistory}>
<StyledModalTitle>Status & History</StyledModalTitle>
<StyledModalTitle>{t("bill.status_and_history")}</StyledModalTitle>
</Modal.Header>
<StyledBillTitle>
{bill.id + " - " + bill.content.Title}
Expand Down
6 changes: 4 additions & 2 deletions components/bill/HistoryTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useContext } from "react"
import styled from "styled-components"
import { BillHistory } from "../db"
import { CourtContext } from "./Status"
import { useTranslation } from "next-i18next"

export type HistoryProps = { billHistory: BillHistory }

Expand Down Expand Up @@ -50,14 +51,15 @@ const BillHistoryActionRows = ({ billHistory }: HistoryProps) => {
}

export const HistoryTable = ({ billHistory }: HistoryProps) => {
const { t } = useTranslation("common")
return (
<div className="text-center">
<StyledTable>
<thead>
<tr>
<th></th>
<th>Status History</th>
<th>Branch</th>
<th>{t("bill.status_history")}</th>
<th>{t("bill.branch")}</th>
</tr>
</thead>
<tbody>
Expand Down
26 changes: 14 additions & 12 deletions components/bill/LobbyingTable.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { useTranslation } from "next-i18next"
import { Table } from "react-bootstrap"
import { Card, Container } from "../bootstrap"
import { Card as MapleCard } from "../Card"
import { FC } from "../types"
import { BillProps } from "./types"
import { Table } from "react-bootstrap"
import { Card as MapleCard } from "../Card"

export const LobbyingTable: FC<React.PropsWithChildren<BillProps>> = ({
bill,
className
}) => {
const { t } = useTranslation("common")
const current = bill.currentCommittee
if (!current) return null
return (
Expand All @@ -16,29 +18,29 @@ export const LobbyingTable: FC<React.PropsWithChildren<BillProps>> = ({
className={`${className} bg-white`}
headerElement={
<Card.Header className="h4 bg-secondary text-light">
Lobbying Parties
{t("bill.lobbying_parties")}
</Card.Header>
}
body={
<Card.Body>
<Table>
<thead>
<tr>
<th>Client Name</th>
<th>Position</th>
<th>Disclosure Date</th>
<th>{t("bill.client_name")}</th>
<th>{t("bill.position")}</th>
<th>{t("bill.disclosure_date")}</th>
</tr>
</thead>
<tbody>
<tr>
<td>Example Name</td>
<td>Pro</td>
<td>April 10, 2023</td>
<td>{t("bill.example_name")}</td>
<td>{t("bill.pro")}</td>
<td>{t("date", { date: new Date("2023-04-15") })}</td>
</tr>
<tr>
<td>Example Name</td>
<td>Neutral</td>
<td>March 29, 2023</td>
<td>{t("bill.example_name")}</td>
<td>{t("bill.neutral")}</td>
<td>{t("date", { date: new Date("2023-03-29") })}</td>
</tr>
</tbody>
</Table>
Expand Down
24 changes: 14 additions & 10 deletions components/bill/SponsorsAndCommittees.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { format, fromUnixTime } from "date-fns"
import { fromUnixTime } from "date-fns"
import { useTranslation } from "next-i18next"
import styled from "styled-components"
import { Card, Container, Row } from "../bootstrap"
import { Card, Container } from "../bootstrap"
import { External } from "../links"
import { LabeledIcon } from "../shared"
import { FC } from "../types"
Expand Down Expand Up @@ -29,14 +30,15 @@ export const Committees: FC<React.PropsWithChildren<BillProps>> = ({
className
}) => {
const current = bill.currentCommittee
const { t } = useTranslation("common")
if (!current) return null
return (
<Container className={`${className} p-0`}>
<MapleCard
className={className}
headerElement={
<Card.Header className="h4 bg-secondary text-light">
Committee
{t("bill.committee")}
</Card.Header>
}
body={
Expand Down Expand Up @@ -64,13 +66,15 @@ export const Hearing: FC<React.PropsWithChildren<BillProps>> = ({
bill,
className
}) => {
const { t } = useTranslation("common")
return (
<>
{bill.nextHearingAt && dateInFuture(bill.nextHearingAt) ? (
<LabeledContainer className={className}>
<HearingDate>
Hearing Scheduled for{" "}
{format(fromUnixTime(bill.nextHearingAt?.seconds), "MMM d, y p")}
{t("bill.hearing_scheduled_for", {
date: fromUnixTime(bill.nextHearingAt?.seconds)
})}
</HearingDate>
</LabeledContainer>
) : null}
Expand All @@ -86,7 +90,7 @@ export const Sponsors: FC<React.PropsWithChildren<BillProps>> = ({
const cosponsors = bill.content.Cosponsors.filter(s => s.Id !== primary?.Id)
const more = cosponsors.length > 2
const isMobile = useMediaQuery("(max-width: 768px)")

const { t } = useTranslation("common")
const countShowSponsors = isMobile ? 1 : 2

return (
Expand All @@ -95,7 +99,7 @@ export const Sponsors: FC<React.PropsWithChildren<BillProps>> = ({
className={className}
headerElement={
<Card.Header className="h4 bg-secondary text-light">
Sponsors
{t("sponsors")}
</Card.Header>
}
body={
Expand All @@ -109,7 +113,7 @@ export const Sponsors: FC<React.PropsWithChildren<BillProps>> = ({
{primary && (
<LabeledIcon
idImage={`https://malegislature.gov/Legislators/Profile/170/${primary.Id}.jpg`}
mainText="Lead Sponsor"
mainText={t("leadSponsor")}
subText={
<External
href={`https://malegislature.gov/Legislators/Profile/${primary.Id}`}
Expand All @@ -126,7 +130,7 @@ export const Sponsors: FC<React.PropsWithChildren<BillProps>> = ({
<LabeledIcon
key={s.Id}
idImage={`https://malegislature.gov/Legislators/Profile/170/${s.Id}.jpg`}
mainText="Sponsor"
mainText={t("sponsor")}
subText={
<External
href={`https://malegislature.gov/Legislators/Profile/${s.Id}`}
Expand All @@ -140,7 +144,7 @@ export const Sponsors: FC<React.PropsWithChildren<BillProps>> = ({
<div className="d-flex justify-content-center">
{more && (
<Cosponsors bill={bill}>
See {bill.cosponsorCount} Sponsors
{t("bill.seeCosponsors", { count: bill.cosponsorCount })}
</Cosponsors>
)}
</div>
Expand Down
33 changes: 23 additions & 10 deletions components/search/bills/BillHit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import {
} from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { maple } from "components/links"
import { format, fromUnixTime } from "date-fns"
import { fromUnixTime } from "date-fns"
import { Hit } from "instantsearch.js"
import Link from "next/link"
import styled from "styled-components"
import { Card, Col } from "../../bootstrap"
import { formatBillId } from "../../formatting"
import { Timestamp } from "firebase/firestore"
import { dateInFuture } from "components/db/events"
import { useTranslation } from "next-i18next"

type BillRecord = {
number: string
Expand Down Expand Up @@ -132,6 +133,7 @@ export const DisplayUpcomingHearing = ({
export const BillHit = ({ hit }: { hit: Hit<BillRecord> }) => {
const url = maple.bill({ id: hit.number, court: hit.court })
const hearingDate = hit.nextHearingAt && hit.nextHearingAt / 1000 // convert to seconds
const { t } = useTranslation("common")

return (
<Link href={url} legacyBehavior>
Expand All @@ -142,7 +144,9 @@ export const BillHit = ({ hit }: { hit: Hit<BillRecord> }) => {
<Col className="left">
<div className="d-flex justify-content-between">
{hit.court && (
<span className="blurb me-2">Court {hit.court}</span>
<span className="blurb me-2">
{t("bill.court", { court: hit.court })}
</span>
)}
<span className="blurb">{hit.city}</span>
<span style={{ flex: "1" }} />
Expand All @@ -154,24 +158,33 @@ export const BillHit = ({ hit }: { hit: Hit<BillRecord> }) => {
</Card.Title>
<div className="d-flex justify-content-between flex-column">
<span className="blurb">
Sponsor: {hit.primarySponsor}{" "}
{hit.cosponsorCount > 0
? `and ${hit.cosponsorCount} other${
hit.cosponsorCount > 1 ? "s" : ""
}`
: ""}
{(() => {
const count = hit.cosponsorCount
if (!hit.primarySponsor) {
return `${t("sponsor")}: ${t("bill.cosponsor_count", {
count
})}`
}
let title = `${t("sponsor")}: ${hit.primarySponsor}`
if (count) {
title += ` ${t("bill.and_others", { count })}`
}
return title
})()}
</span>
<span className="blurb">
{hit.currentCommittee &&
`Committee: ${hit.currentCommittee}`}
`${t("bill.committee")}: ${hit.currentCommittee}`}
</span>
</div>
</Col>
</div>
</Card.Body>
{hit.nextHearingAt && dateInFuture(hit.nextHearingAt) ? (
<Card.Footer className="card-footer">
Hearing Scheduled {format(fromUnixTime(hearingDate!), "M/d/y p")}
{t("bill.hearing_scheduled_for", {
date: fromUnixTime(hearingDate!)
})}
</Card.Footer>
) : null}
</StyledCard>
Expand Down
25 changes: 25 additions & 0 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@
"about": "About",
"back_to_bills": "back to list of bills",
"bill": {
"and_others_one": "and {{count}} other",
"and_others_other": "and {{count}} others",
"bill_tracker": "Bill Tracker",
"bill_cosponsors": "{{billId}} Cosponsors",
"cosponsor_count_one": "{{count}} Cosponsor",
"cosponsor_count_other": "{{count}} Cosponsors",
"court": "Court",
"history": "History",
"status_and_history": "Status & History",
"status_history": "Status History",
"branch": "Branch",
"lobbying_parties": "Lobbying Parties",
"client_name": "Client Name",
"position": "Position",
"disclosure_date": "Disclosure Date",
"example_name": "Example Name",
"pro": "Pro",
"neutral": "Neutral",
"committee": "Committee",
"hearing_scheduled_for": "Hearing Scheduled for {{date, datetime(year: 'numeric'; month: 'long'; day: 'numeric'; hour: 'numeric'; minute: 'numeric')}}",
"old_session": "this bill is from session {{billCourt}} - not the current session",
"read_more": "Read More",
"download_pdf": "Download PDF",
Expand Down Expand Up @@ -29,6 +49,7 @@
"technology_and_communications": "Technology and Communications",
"transportation_and_public_works": "Transportation and Public Works"
},
"seeCosponsors": "See {{count}} Cosponsors",
"smart_tag": "AI Smart Tag",
"smart_summary": "Smart Summary & Tags",
"smart_disclaimer": "This content has been generated using artificial intelligence and may not accurately reflect the details of the legislation. Learn more about <0>how MAPLE uses AI</0>. To report an inaccuracy or to suggest an improvement, please email [email protected]"
Expand All @@ -42,7 +63,9 @@
},
"calendar": "Our Calendar",
"hideAns": "Hide Answer",
"date": "{{date, datetime(year: 'numeric'; month: 'long'; day: 'numeric')}}",
"joinTraining": "and join an upcoming training session!",
"leadSponsor": "Lead Sponsor",
"learn": "Learn",
"let_your_voice_be_heard": "Let your voice be heard!",
"loading": {
Expand Down Expand Up @@ -124,6 +147,8 @@
"bluesky": "BlueSky",
"mastodon": "Mastodon"
},
"sponsor": "Sponsor",
"sponsors": "Sponsors",
"table": {
"page": "Page {{currentPage}}"
},
Expand Down