Skip to content
4 changes: 2 additions & 2 deletions components/EditProfilePage/PersonalInfoTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { TooltipButton } from "components/buttons"
import { useTranslation } from "next-i18next"
import styled from "styled-components"

type UpdateProfileData = {
export type UpdateProfileData = {
fullName: string
aboutYou: string
twitter: string
Expand All @@ -37,7 +37,7 @@ type Props = {
legislatorsProps?: YourLegislatorsProps
}

async function updateProfile(
export async function updateProfile(
{ profile, actions, uid }: Props,
data: UpdateProfileData
) {
Expand Down
2 changes: 1 addition & 1 deletion components/db/profile/urlCleanup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function cleanSocialLinks(network: keyof SocialLinks, link: string) {
const index: number = path.indexOf(".com/") + 5
path = path.substring(index)
}
if (network === "mastodon" && path.startsWith("@")) {
if (path && network === "mastodon" && path.startsWith("@")) {
path = path.substring(1)
}
}
Expand Down
2 changes: 1 addition & 1 deletion components/legislator/LegislatorPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ export function LegislatorPage(props: { id: string }) {
<LegislatorTabs fullname={profile.fullName} pageId={props.id} />
</Col>
<Col className={`mt-4`} md="3">
<LegislatorSidebar />
<LegislatorSidebar pageId={props.id} publicProfile={profile} />
</Col>
</Row>
</Container>
Expand Down
153 changes: 151 additions & 2 deletions components/legislator/SidebarComponents/Biography.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,152 @@
export function Biography() {
return <div>- Biography</div>
import { useTranslation } from "next-i18next"
import { useEffect, useState } from "react"
import { useForm } from "react-hook-form"
import styled from "styled-components"

import { Form, Row, Spinner } from "../../bootstrap"
import { Profile, ProfileHook, useProfile } from "../../db"
import Input from "../../forms/Input"

import { useAuth } from "components/auth"
import {
updateProfile,
UpdateProfileData
} from "components/EditProfilePage/PersonalInfoTab"

const BioBlock = styled.div`
background-color: white;
border: "1px #ced4da solid";
border-radius: 5px;
font-size: 11px;
margin-top: 8px;
padding: 8px 16px;
`

const BioButton = styled.button`
font-size: 9px;
padding: 2px;
`

const BioTitle = styled.div`
font-weight: 700;
color: #0b0a3e;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 10px;
`

export function Biography({
pageId,
publicProfile
}: {
pageId: string
publicProfile: Profile | undefined
}) {
const { user } = useAuth()
const uid = user?.uid
const pageOwnerResult = useProfile()

let pageOwner = false

if (uid === pageId) {
pageOwner = true
}

if (pageOwnerResult.loading) {
return (
<Row>
<Spinner animation="border" className="mx-auto" />
</Row>
)
}

if (pageOwnerResult.profile && pageOwner) {
// the user is the legislator whose page this is
// therefore they get edit privledges
return (
<EditableBiography
actions={pageOwnerResult}
pageId={pageId}
profile={pageOwnerResult.profile}
/>
)
}

if (publicProfile) {
// the user is not the legislator whose page this is
// therefore they get read-only privledges
return <ReadonlyBiography profile={publicProfile} />
}
}

function EditableBiography({
actions,
pageId,
profile
}: {
actions: ProfileHook
pageId: string
profile: Profile
}) {
const {
register,
formState: { errors, isDirty },
handleSubmit
} = useForm<UpdateProfileData>()

const { about }: Profile = profile

const onSubmit = handleSubmit(async update => {
await updateProfile({ profile, actions }, update)
location.assign(`/legislators/profile?id=${pageId}`)
setFormUpdated(false)
})

const { t } = useTranslation("legislators")
const [formUpdated, setFormUpdated] = useState(false)

useEffect(() => {
setFormUpdated(isDirty)
}, [isDirty, setFormUpdated])

return (
<BioBlock>
<Form onSubmit={onSubmit}>
<div className={`d-flex justify-content-between`}>
<BioTitle className={`align-self-center d-inline my-1`}>
{t("biography")}
</BioTitle>
<BioButton
type="submit"
className={`btn btn-primary d-inline m-1 w-auto`}
disabled={!formUpdated}
>
{t("submit")}
</BioButton>
</div>
<Input
as="textarea"
{...register("aboutYou")}
style={{ fontSize: "11px", height: "10rem" }}
className="mt-3"
label={t("editBio")}
defaultValue={about ? about : t("addBio")}
/>
</Form>
</BioBlock>
)
}

function ReadonlyBiography({ profile }: { profile: Profile }) {
const { about }: Profile = profile
const { t } = useTranslation("legislators")

return (
<BioBlock>
<BioTitle className={`my-1`}>{t("biography")}</BioTitle>
<div style={{ whiteSpace: "pre-wrap" }}>
{about ? about : t("notClaimed")}
</div>
</BioBlock>
)
}
12 changes: 9 additions & 3 deletions components/legislator/SidebarComponents/LegislatorSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { Profile } from "../../db"
import { Biography } from "./Biography"
import { OtherTestimony } from "./OtherTestimony"
import { UpcomingHearings } from "./UpcomingHearings"

export function LegislatorSidebar() {
export function LegislatorSidebar({
pageId,
publicProfile
}: {
pageId: string
publicProfile: Profile | undefined
}) {
return (
<>
Sidebar Components
<OtherTestimony />
<UpcomingHearings />
<Biography />
<Biography pageId={pageId} publicProfile={publicProfile} />
</>
)
}
5 changes: 5 additions & 0 deletions public/locales/en/legislators.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
{
"addBio": "Add your biography",
"billsSponsored": "Bills Sponsored",
"biography": "Biography",
"canSubmit": "can submit testimony on any bill or ballot question, just like any constituent. Her stance and reasoning are shown exactly as submitted — MAPLE does not edit or editorialize.",
"contact": "Contact",
"cosponsored": "Cosponsored",
"editBio": "Edit your biography",
"fundsRaised": "Funds Raised",
"home": "Home",
"legislators": "Legislators",
"notClaimed": "This legislator has not claimed their MAPLE account",
"party": {
"democratic": "Democratic Party",
"party": "Party",
"republican": "Republican Party"
},
"stateRepresentative": "State Representative",
"stateSenator": "State Senator",
"submit": "Submit",
"tabs": {
"bills": "Bills",
"district": "District",
Expand Down
Loading