Skip to content
2 changes: 2 additions & 0 deletions components/EditProfilePage/FollowersTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const FollowersTab = ({
})
}
}

useEffect(() => {
if (uid) {
setState(prev => ({ ...prev, loading: true, error: null }))
Expand All @@ -55,6 +56,7 @@ export const FollowersTab = ({
setState({ items: [], loading: false, error: null })
}
}, [uid])

return (
<PaginatedItemsCard
className={className}
Expand Down
9 changes: 9 additions & 0 deletions components/LegislatorProfile/LegislatorComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ export const formatPhoneNumber = (value: string) => {
`
}

export function shuffleArray(array: any) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))

;[array[i], array[j]] = [array[j], array[i]]
}
return array
}

export const TabBlock = styled.div`
background-color: white;
border: 1px #b8c0c9 solid;
Expand Down
1 change: 1 addition & 0 deletions components/LegislatorProfile/LegislatorProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ export function LegislatorProfilePage({
legislatorData={legislatorData}
legislatorId={legislatorId}
memberCode={memberCode}
sponsoredBills={member.SponsoredBills}
/>
</Col>
</Row>
Expand Down
18 changes: 16 additions & 2 deletions components/LegislatorProfile/LegislatorSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import styled from "styled-components"

import * as links from "../links"

import { Biography } from "./SidebarComponents/Biography"
import { OtherTestimony } from "./SidebarComponents/OtherTestimony"
import { UpcomingHearings } from "./SidebarComponents/UpcomingHearings"
Expand All @@ -9,17 +11,19 @@ export function LegislatorSidebar({
court,
legislatorData,
legislatorId,
memberCode
memberCode,
sponsoredBills
}: {
committeeList: any[]
court: number
legislatorData: any[]
legislatorId: string
memberCode: string
sponsoredBills: any[]
}) {
return (
<>
<OtherTestimony />
<OtherTestimony court={court} sponsoredBills={sponsoredBills} />
<UpcomingHearings committeeList={committeeList} />
<Biography
court={court}
Expand All @@ -41,6 +45,16 @@ export const SidebarBlock = styled.div`
padding: 16px;
`

export const SidebarLink = styled(links.Internal)`
font-size: 12px;
font-weight: 700;
color: #1a3185;
padding: 10px;
display: block;
text-align: center;
text-decoration: none;
`

export const SidebarTitle = styled.div`
font-weight: 700;
color: #0b0a3e;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.billTestimonyCard
~ .billTestimonyCard
~ .billTestimonyCard
~ .billTestimonyCard {
display: none;
}
176 changes: 173 additions & 3 deletions components/LegislatorProfile/SidebarComponents/OtherTestimony.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,184 @@
import { useTranslation } from "next-i18next"
import { useMemo } from "react"
import styled from "styled-components"

import { SidebarBlock, SidebarTitle } from "../LegislatorSidebar"
import { Col } from "../../bootstrap"
import { shuffleArray } from "../LegislatorComponents"
import { SidebarBlock, SidebarLink, SidebarTitle } from "../LegislatorSidebar"

export function OtherTestimony() {
import styles from "./OtherTestimony.module.css"

import { usePublishedTestimonyListing } from "components/db"

const TestimonyBlock = styled.div`
background: #f8f9fa;
border-radius: 6px;
padding: 10px;
margin-bottom: 6px;
`

/* Position Components */

const EndorseBubble = styled.div.attrs(props => ({
className: `${props.className}`
}))`
background: #d4edda;
color: #155724;

font-size: 10px;
font-weight: 700;
padding: 2px 7px;
border-radius: 999px;
margin-bottom: 4px;
display: inline-block;
`

const NeutralBubble = styled.div.attrs(props => ({
className: `${props.className}`
}))`
background: #d1d6e7;
color: #1a3185;

font-size: 10px;
font-weight: 700;
padding: 2px 7px;
border-radius: 999px;
margin-bottom: 4px;
display: inline-block;
`

const OpposeBubble = styled.div.attrs(props => ({
className: `${props.className}`
}))`
background: #f4d2d6;
color: #8b0000;

font-size: 10px;
font-weight: 700;
padding: 2px 7px;
border-radius: 999px;
margin-bottom: 4px;
display: inline-block;
`

function PositionButton(props: { position: string }) {
const { t } = useTranslation("legislators")

switch (props.position) {
case "endorse":
return <EndorseBubble>{t("position.endorse")}</EndorseBubble>
case "oppose":
return <OpposeBubble>{t("position.oppose")}</OpposeBubble>
default:
return <NeutralBubble>{t("position.neutral")}</NeutralBubble>
}
}

/* Misc Testimony Components */

const TestimonyBorder = styled.div`
border-bottom: 1px solid #b8c0c9;
`

const TestimonyMeta = styled.div`
color: #6c757d;
font-size: 10px;
`

const TestimonyText = styled.div`
color: #495057;
line-height: 1.5;
font-size: 12px;
font-style: italic;
margin-bottom: 3px;
`

export const OtherTestimony = ({
court,
sponsoredBills
}: {
court: number
sponsoredBills: any[]
}) => {
const { t } = useTranslation("legislators")

const randomBills: any[] = shuffleArray(sponsoredBills)

return (
<SidebarBlock className="mb-2">
<SidebarTitle className={`my-1`}>{t("otherTestimony")}</SidebarTitle>
<div>Content To Be Added</div>
{randomBills.map(bill => (
<BillTestimonyList key={bill} billId={bill} court={court} />
))}
<Col>
<TestimonyBorder />
<SidebarLink href="/testimony">
{t("viewAllTestimony")}
{" ↗"}
</SidebarLink>
</Col>
</SidebarBlock>
)
}

const BillTestimonyList = ({
billId,
court
}: {
billId: string
court: number
}) => {
const { t } = useTranslation("legislators")

const data = usePublishedTestimonyListing({ billId, court })
const length = data?.items?.result?.length ?? 0
const hasData = length > 0

const topTestimonies = useMemo(() => {
return data?.items?.result
? [...data.items.result]
.sort((a, b) => b.updatedAt.toMillis() - a.updatedAt.toMillis())
.slice(0, 1)
: []
}, [data])

if (!hasData)
return <div className="billTestimonyEmpty" style={{ display: "none" }} />

/* formatted Testimony On Legislator Bills */
const formattedTOLB = topTestimonies.map(obj => {
const date = new Date(obj.updatedAt.toMillis())

const monthYear = date.toLocaleString("en-US", {
month: "long",
year: "numeric",
timeZone: "UTC"
})

return {
...obj,
formattedDate: monthYear
}
})

return (
<div className={styles.billTestimonyCard}>
{formattedTOLB ? (
<>
{formattedTOLB.map(t => (
<TestimonyBlock key={t.id}>
<PositionButton position={t.position} />
<TestimonyText>{t.content}</TestimonyText>
<TestimonyMeta>
{t.authorDisplayName} {" · "} {t.billId} {" · "}
{t.formattedDate}
</TestimonyMeta>
</TestimonyBlock>
))}
</>
) : (
<div>{t("noTestimony")}</div>
)}
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { DateTime } from "luxon"
import { useTranslation } from "next-i18next"
import styled from "styled-components"

import * as links from "../../links"
import { Col } from "../../bootstrap"
import { SidebarBlock, SidebarTitle } from "../LegislatorSidebar"
import { SidebarBlock, SidebarLink, SidebarTitle } from "../LegislatorSidebar"

import { useUpcomingEvents } from "components/db/events"
import { EventData } from "components/HearingsScheduled"
Expand Down Expand Up @@ -33,16 +32,6 @@ const EventLocation = styled.div`
margin-top: 1px;
`

export const HearingsLink = styled(links.Internal)`
font-size: 12px;
font-weight: 700;
color: #1a3185;
padding: 10px;
display: block;
text-align: center;
text-decoration: none;
`

export function UpcomingHearings({ committeeList }: { committeeList: any[] }) {
const { t } = useTranslation("legislators")

Expand Down Expand Up @@ -78,20 +67,18 @@ export function UpcomingHearings({ committeeList }: { committeeList: any[] }) {
}
}

const LegislatorCommitteCodes = committeeList.map(code => code.CommitteeCode)
const LegislatorCommitteeCodes = committeeList.map(code => code.CommitteeCode)

let legislatorEvents: any[] = []

if (events) {
eventList.forEach(event => {
if (LegislatorCommitteCodes.includes(event.code)) {
if (LegislatorCommitteeCodes.includes(event.code)) {
legislatorEvents.push(event)
}
})
}

console.log("legislatorEvents", legislatorEvents)

return (
<SidebarBlock className="mb-2">
<SidebarTitle className={`my-1`}>{t("upcomingHearings")}</SidebarTitle>
Expand All @@ -111,10 +98,10 @@ export function UpcomingHearings({ committeeList }: { committeeList: any[] }) {
<div>{t("noEvents")}</div>
)}
<Col>
<HearingsLink href="/hearings">
<SidebarLink href="/hearings">
{t("viewAllHearings")}
{" ↗"}
</HearingsLink>
</SidebarLink>
</Col>
</SidebarBlock>
)
Expand Down
9 changes: 8 additions & 1 deletion public/locales/en/legislators.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,19 @@
"legislators": "Legislators",
"loading": "Loading district...",
"noEvents": "This legislator does not have hearings in the near term future",
"noTestimony": "This legislator does not yet have testimony for any of their bills",
"notClaimed": "This legislator has not claimed their MAPLE account",
"otherTestimony": "Others' testimony on their bills",
"party": {
"democratic": "Democratic Party",
"party": "Party",
"republican": "Republican Party"
},
"position": {
"endorse": "Endorse",
"neutral": "Neutral",
"oppose": "Oppose"
},
"stateRepresentative": "State Representative",
"stateSenator": "State Senator",
"submit": "Submit",
Expand All @@ -66,5 +72,6 @@
},
"termsServed": "Terms Served",
"upcomingHearings": "Upcoming Hearings",
"viewAllHearings": "View all hearings"
"viewAllHearings": "View all hearings",
"viewAllTestimony": "View all testimony"
}
1 change: 1 addition & 0 deletions public/locales/en/profile.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"followedContent": "Followed Content",
"following" : "Following",
"notficationFrequencyDropdown": "open envelope with letter, toggles update frequency options",
"unfollow": "Unfollow",
"yourTestimonies": "Your Testimonies"
},
"content": {
Expand Down
Loading