Skip to content

Commit

Permalink
feat: bill follow and unfollow functionality to testimony page (#1661)
Browse files Browse the repository at this point in the history
* feat: bill follow and unfollow functionality to testimony page

* ran prettier

* fix: remove unnecesary code

* fix: run linter

---------

Co-authored-by: Merritt Baggett <mertbagt@gmail.com>
  • Loading branch information
aaerhart and mertbagt authored Jan 21, 2025
1 parent 3aa776a commit e6e99cc
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 82 deletions.
131 changes: 64 additions & 67 deletions components/bill/BillDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,86 +37,83 @@ export const BillDetails = ({ bill }: BillProps) => {
const isPendingUpgrade = useAuth().claims?.role === "pendingUpgrade"
const flags = useFlags()

const [followStatus, setFollowStatus] = useState<OrgFollowStatus>({})
const { user } = useAuth()

return (
<>
<FollowContext.Provider value={{ followStatus, setFollowStatus }}>
{isPendingUpgrade && <PendingUpgradeBanner />}
{!isCurrentCourt(bill.court) && (
<Banner>{t("bill.old_session", { billCourt: bill.court })}</Banner>
)}
{isPendingUpgrade && <PendingUpgradeBanner />}
{!isCurrentCourt(bill.court) && (
<Banner>{t("bill.old_session", { billCourt: bill.court })}</Banner>
)}

<StyledContainer className="mt-3 mb-3">
<Row>
<Col>
<Back href="/bills">{t("back_to_bills")}</Back>
</Col>
</Row>
{bill.history.length > 0 ? (
<>
<Row className="align-items-end justify-content-start">
<Col md={2}>
<BillNumber bill={bill} />
</Col>
<Col
xs={10}
md={6}
className="mb-3 ms-auto d-flex justify-content-end"
>
<Status bill={bill} />
</Col>
</Row>
<Row className="mb-4">
<Col xs={12} className="d-flex justify-content-end">
{flags.notifications && user && (
<FollowBillButton bill={bill} />
)}
</Col>
</Row>
</>
) : (
<Row>
<Col>
<StyledContainer className="mt-3 mb-3">
<Row>
<Col>
<Back href="/bills">{t("back_to_bills")}</Back>
</Col>
</Row>
{bill.history.length > 0 ? (
<>
<Row className="align-items-end justify-content-start">
<Col md={2}>
<BillNumber bill={bill} />
</Col>
<Col xs={6} className="d-flex justify-content-end">
<Styled>
{flags.notifications && user && (
<FollowBillButton bill={bill} />
)}
</Styled>
<Col
xs={10}
md={6}
className="mb-3 ms-auto d-flex justify-content-end"
>
<Status bill={bill} />
</Col>
</Row>
)}
<Row className="mt-2">
<Col>
<Summary bill={bill} />
</Col>
</Row>
<Row className="mb-4">
<Col xs={12} className="d-flex justify-content-end">
{flags.notifications && user && (
<FollowBillButton bill={bill} />
)}
</Col>
</Row>
</>
) : (
<Row>
<Col md={8}>
<Sponsors bill={bill} className="mt-4 pb-1" />
<BillTestimonies bill={bill} className="mt-4" />
{flags.lobbyingTable && (
<LobbyingTable bill={bill} className="mt-4 pb-1" />
)}
<Col>
<BillNumber bill={bill} />
</Col>
<Col md={4}>
<Committees bill={bill} className="mt-4 pb-1" />
<Hearing
bill={bill}
className="bg-secondary d-flex justify-content-center mt-4 pb-1 text-light"
/>
<TestimonyFormPanel bill={bill} />
{flags.billTracker && (
<BillTrackerConnectedView bill={bill} className="mt-4" />
)}
<Col xs={6} className="d-flex justify-content-end">
<Styled>
{flags.notifications && user && (
<FollowBillButton bill={bill} />
)}
</Styled>
</Col>
</Row>
</StyledContainer>
</FollowContext.Provider>
)}
<Row className="mt-2">
<Col>
<Summary bill={bill} />
</Col>
</Row>
<Row>
<Col md={8}>
<Sponsors bill={bill} className="mt-4 pb-1" />
<BillTestimonies bill={bill} className="mt-4" />
{flags.lobbyingTable && (
<LobbyingTable bill={bill} className="mt-4 pb-1" />
)}
</Col>
<Col md={4}>
<Committees bill={bill} className="mt-4 pb-1" />
<Hearing
bill={bill}
className="bg-secondary d-flex justify-content-center mt-4 pb-1 text-light"
/>
<TestimonyFormPanel bill={bill} />
{flags.billTracker && (
<BillTrackerConnectedView bill={bill} className="mt-4" />
)}
</Col>
</Row>
</StyledContainer>
</>
)
}
25 changes: 15 additions & 10 deletions components/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import AuthModal from "./auth/AuthModal"
import PageFooter from "./Footer/Footer"
import { MainNavbar } from "./Navbar"
import { TabContext, TabStatus } from "./shared/ProfileTabsContext"
import { FollowContext, OrgFollowStatus } from "./shared/FollowContext"

export const PageContainer: FC<React.PropsWithChildren<unknown>> = ({
children
Expand Down Expand Up @@ -36,6 +37,8 @@ export const Layout: React.FC<React.PropsWithChildren<LayoutProps>> = ({
setIsClient(true)
}, [])

const [followStatus, setFollowStatus] = useState<OrgFollowStatus>({})

return (
<>
{isClient ? (
Expand All @@ -45,16 +48,18 @@ export const Layout: React.FC<React.PropsWithChildren<LayoutProps>> = ({
<link rel="icon" href="/favicon.ico" />
</Head>
<TabContext.Provider value={{ tabStatus, setTabStatus }}>
<PageContainer>
<MainNavbar />
<AuthModal />
<div className={`col`}>{children}</div>
<PageFooter
authenticated={authenticated}
user={user as any}
signOut={signOutAndRedirectToHome}
/>
</PageContainer>
<FollowContext.Provider value={{ followStatus, setFollowStatus }}>
<PageContainer>
<MainNavbar />
<AuthModal />
<div className={`col`}>{children}</div>
<PageFooter
authenticated={authenticated}
user={user as any}
signOut={signOutAndRedirectToHome}
/>
</PageContainer>
</FollowContext.Provider>
</TabContext.Provider>
</>
) : (
Expand Down
54 changes: 49 additions & 5 deletions components/testimony/TestimonyDetailPage/PolicyActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@ import { Card, ListItem, ListItemProps } from "components/Card"
import { useFlags } from "components/featureFlags"
import { formatBillId } from "components/formatting"
import { formUrl } from "components/publish"
import { isNotNull } from "components/utils"
import { FC, ReactElement } from "react"
import { FC, ReactElement, useContext, useEffect } from "react"
import { useCurrentTestimonyDetails } from "./testimonyDetailSlice"
import { useTranslation } from "next-i18next"
import { useAuth } from "components/auth"
import { TopicQuery } from "components/shared/FollowingQueries"
import { StyledImage } from "components/ProfilePage/StyledProfileComponents"
import { FollowContext } from "components/shared/FollowContext"

interface PolicyActionsProps {
className?: string
isUser?: boolean
isReporting: boolean
setReporting: (boolean: boolean) => void
topicName: string
followAction: () => Promise<void>
unfollowAction: () => Promise<void>
}

const PolicyActionItem: FC<React.PropsWithChildren<ListItemProps>> = props => (
Expand All @@ -22,19 +28,57 @@ export const PolicyActions: FC<React.PropsWithChildren<PolicyActionsProps>> = ({
className,
isUser,
isReporting,
setReporting
setReporting,
topicName,
followAction,
unfollowAction
}) => {
const { bill } = useCurrentTestimonyDetails(),
billLabel = formatBillId(bill.id)
const { notifications } = useFlags()

const { user } = useAuth()
const uid = user?.uid

const { followStatus, setFollowStatus } = useContext(FollowContext)

useEffect(() => {
uid
? TopicQuery(uid, topicName).then(result => {
setFollowStatus(prevOrgFollowGroup => {
return { ...prevOrgFollowGroup, [topicName]: Boolean(result) }
})
})
: null
}, [uid, topicName, setFollowStatus])

const FollowClick = async () => {
await followAction()
setFollowStatus({ ...followStatus, [topicName]: true })
}

const UnfollowClick = async () => {
await unfollowAction()
setFollowStatus({ ...followStatus, [topicName]: false })
}

const isFollowing = followStatus[topicName]
const text = isFollowing ? "Unfollow" : "Follow"
const checkmark = isFollowing ? (
<StyledImage src="/check-white.svg" alt="" />
) : null
const handleClick = (event: React.MouseEvent<Element, MouseEvent>) => {
event.preventDefault()
isFollowing ? UnfollowClick() : FollowClick()
}

const items: ReactElement[] = []
if (notifications)
items.push(
<PolicyActionItem
onClick={() => window.alert("TODO")} // TODO: add follow action here
onClick={e => handleClick(e)}
key="follow"
billName={`Follow ${billLabel}`}
billName={`${text} ${billLabel}`}
/>
)
items.push(
Expand Down
11 changes: 11 additions & 0 deletions components/testimony/TestimonyDetailPage/TestimonyDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,27 @@ import { TestimonyDetail } from "./TestimonyDetail"
import { VersionBanner } from "./TestimonyVersionBanner"
import { useAuth } from "components/auth"
import { useMediaQuery } from "usehooks-ts"
import { setFollow, setUnfollow } from "components/shared/FollowingQueries"

export const TestimonyDetailPage: FC<React.PropsWithChildren<unknown>> = () => {
const [isReporting, setIsReporting] = useState(false)
const reportMutation = useReportTestimony()
const didReport = reportMutation.isError || reportMutation.isSuccess
const isMobile = useMediaQuery("(max-width: 768px)")
const { authorUid, revision } = useCurrentTestimonyDetails()
const { bill } = useCurrentTestimonyDetails()
const { user } = useAuth()
const isUser = user?.uid === authorUid
const handleReporting = (boolean: boolean) => {
setIsReporting(boolean)
}
const { t } = useTranslation("testimony", { keyPrefix: "reportModal" })
const uid = user?.uid
const { id: billId, court: courtId } = bill
const topicName = `bill-${courtId}-${billId}`
const followAction = () =>
setFollow(uid, topicName, bill, billId, courtId, undefined)
const unfollowAction = () => setUnfollow(uid, topicName)

return (
<>
Expand All @@ -49,6 +57,9 @@ export const TestimonyDetailPage: FC<React.PropsWithChildren<unknown>> = () => {
isUser={isUser}
isReporting={isReporting}
setReporting={handleReporting}
topicName={topicName}
followAction={followAction}
unfollowAction={unfollowAction}
/>
)}
<RevisionHistory />
Expand Down

0 comments on commit e6e99cc

Please sign in to comment.