Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Newsfeed UI and Navigation #1651

Merged
merged 13 commits into from
Dec 4, 2024
43 changes: 41 additions & 2 deletions components/AlertCard/AlertCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CardTitle } from "components/Card"
import { CardTitle, CardTitleV2 } from "components/Card"
import { Timestamp } from "firebase/firestore"
import { Card as MapleCard } from "../Card/Card"
import { AlertCardBody } from "./AlertCardBody"
import { AlertCardBody, AlertCardBodyV2 } from "./AlertCardBody"

export const AlertCard = (props: {
header: string
Expand Down Expand Up @@ -35,3 +35,42 @@ export const AlertCard = (props: {

return <MapleCard headerElement={header} body={body} />
}

// newsfeed bill card
export const AlertCardV2 = (props: {
court: string
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Could we give this a more descriptive name than AlertCardV2? NewsfeedBillCard would work for me for now - we can always generalize the card and name if someone ever needs to use the design in another context.

header: string
subheader: string
timestamp: Timestamp
headerImgSrc: string
headerImgTitle?: string
bodyImgSrc: string
bodyImgAltTxt: string
bodyText: string
isBillMatch: boolean
}) => {
const date = props.timestamp.toDate()
const formattedTimestamp = `${date.toLocaleDateString()}`
const header = (
<CardTitleV2
court={props.court}
header={props.header}
subheader={props.subheader}
timestamp={formattedTimestamp}
imgSrc={props.headerImgSrc}
imgTitle={props.headerImgTitle ?? ""}
isBillMatch={props.isBillMatch}
/>
)

const body = (
<AlertCardBodyV2
imgSrc={props.bodyImgSrc}
imgAltTxt={props.bodyImgAltTxt}
text={props.bodyText}
timestamp={formattedTimestamp}
/>
)

return <MapleCard headerElement={header} body={body} />
}
38 changes: 38 additions & 0 deletions components/AlertCard/AlertCardBody.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { ReactElement } from "react"
import CardBootstrap from "react-bootstrap/Card"
import styled from "styled-components"
import { Col, Row, Spinner } from "../bootstrap"
import { Timestamp } from "firebase/firestore"

const AlertCardInnerBodyV2 = styled.div`
background-color: #d1d6e7;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to be the same nit on all of these V2 components - if they're just NewsfeedCard*, let's just name them that to be unambiguous. The props are pretty tied to the newsfeed data model anyway.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also nit: Can this background-color be one of our color variables? I think we're looking to keep these more consistent going forward.

`

interface AlertCardBodyProps {
imgSrc?: string
imgAltTxt?: string
text: string
timestamp?: string
}

export const AlertCardBody = (props: AlertCardBodyProps) => {
Expand All @@ -18,3 +26,33 @@ export const AlertCardBody = (props: AlertCardBodyProps) => {
</div>
)
}

export const AlertCardBodyV2 = (props: AlertCardBodyProps) => {
const { imgSrc, imgAltTxt, text, timestamp } = props
return (
<div>
<CardBootstrap.Body className={`p-0`}>
<AlertCardInnerBodyV2
className={`align-items-center d-flex mx-2 mt-1 mb-2 p-2 rounded`}
>
<img
src="\images\clock.svg"
height="105.6"
width="105.6"
alt={imgAltTxt}
className={`m-3`}
/>
<Col className={`m-2`}>
<CardBootstrap.Text className={`mb-0`}>
<strong>{text}</strong>
</CardBootstrap.Text>
<>
{"Action taken on "}
{timestamp}
</>
</Col>
</AlertCardInnerBodyV2>
</CardBootstrap.Body>
</div>
)
}
75 changes: 75 additions & 0 deletions components/Card/CardTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
import { collection, getDocs, query, where } from "firebase/firestore"
import { getFunctions, httpsCallable } from "firebase/functions"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { ReactElement } from "react"
import CardBootstrap from "react-bootstrap/Card"
import { formatBillId } from "components/formatting"

import { useTranslation } from "next-i18next"
import { useAuth } from "../auth"
import { Stack } from "../bootstrap"
import { firestore } from "../firebase"
import { TitledSectionCard } from "../shared"

import {
BillElement,
UserElement
} from "components/EditProfilePage/FollowingTabComponents"
import { is } from "date-fns/locale"

interface CardTitleProps {
court?: string
header?: string
subheader?: string
timestamp?: string
imgSrc?: string
imgTitle?: string
inHeaderElement?: ReactElement
isBillMatch?: boolean
isUserMatch?: boolean
}

export const CardTitle = (props: CardTitleProps) => {
Expand Down Expand Up @@ -42,3 +61,59 @@ export const CardTitle = (props: CardTitleProps) => {
</CardBootstrap.Body>
)
}

// newsfeed bill card title
export const CardTitleV2 = (props: CardTitleProps) => {
const {
court,
header,
subheader,
timestamp,
imgSrc,
imgTitle,
inHeaderElement,
isBillMatch
} = props
const { t } = useTranslation("common")

return (
<CardBootstrap.Body className={`align-items-center d-flex px-2 pt-2 pb-0`}>
<div className="justify-content-middle d-flex flex-column align-items-center">
{imgSrc && <img alt="" src={imgSrc} width="32" height="32" />}
</div>
<CardBootstrap.Body className="px-3 py-0">
{header && (
<CardBootstrap.Title
className={`align-items-start fs-6 lh-sm mb-1 text-secondary`}
>
<a href={`/bills/${court}/${header}`}>
<strong>{formatBillId(header)}</strong>
</a>{" "}
{subheader ? (
<>
{t("newsfeed.action_update")}
{subheader}
</>
) : (
<></>
)}
</CardBootstrap.Title>
)}
{header ? (
<CardBootstrap.Title
className={`align-items-start fs-6 lh-sm mb-1 text-body-tertiary`}
>
{header && isBillMatch ? (
<>{t("newsfeed.follow")}</>
) : (
<>{t("newsfeed.not_follow")}</>
)}
<strong>{formatBillId(header)}</strong>
</CardBootstrap.Title>
) : (
<></>
)}
</CardBootstrap.Body>
</CardBootstrap.Body>
)
}
13 changes: 13 additions & 0 deletions components/DesktopNav.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useFlags } from "components/featureFlags"
import { useTranslation } from "next-i18next"
import React from "react"
import { SignInWithButton, signOutAndRedirectToHome, useAuth } from "./auth"
Expand All @@ -12,6 +13,7 @@ import {
NavbarLinkFAQ,
NavbarLinkGoals,
NavbarLinkLogo,
NavbarLinkNewsfeed,
NavbarLinkProcess,
NavbarLinkSignOut,
NavbarLinkSupport,
Expand All @@ -23,6 +25,7 @@ import {

export const DesktopNav: React.FC<React.PropsWithChildren<unknown>> = () => {
const { authenticated } = useAuth()
const { notifications } = useFlags()
const { t } = useTranslation(["common", "auth"])

return (
Expand All @@ -47,6 +50,16 @@ export const DesktopNav: React.FC<React.PropsWithChildren<unknown>> = () => {
</Nav>
</div>

{authenticated && notifications ? (
<div className="align-self-center">
<Nav>
<NavbarLinkNewsfeed />
</Nav>
</div>
) : (
<></>
)}

<div className={`align-self-center`}>
<Dropdown>
<Dropdown.Toggle className={`btn-secondary text-white-50`}>
Expand Down
3 changes: 3 additions & 0 deletions components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ const AccountLinks = ({ authenticated, user, signOut }: PageFooterProps) => {
>
{t("navigation.accountProfile")}
</StyledInternalLink>
<StyledInternalLink href={"/newsfeed"}>
{t("navigation.newsfeed")}
</StyledInternalLink>
<StyledInternalLink handleClick={() => signOut()}>
{t("signOut", { ns: "auth" })}
</StyledInternalLink>
Expand Down
8 changes: 8 additions & 0 deletions components/MobileNav.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useFlags } from "components/featureFlags"
import { useTranslation } from "next-i18next"
import React, { useState } from "react"
import Image from "react-bootstrap/Image"
Expand All @@ -13,6 +14,7 @@ import {
NavbarLinkFAQ,
NavbarLinkGoals,
NavbarLinkLogo,
NavbarLinkNewsfeed,
NavbarLinkProcess,
NavbarLinkSignOut,
NavbarLinkSupport,
Expand Down Expand Up @@ -64,6 +66,11 @@ export const MobileNav: React.FC<React.PropsWithChildren<unknown>> = () => {
<Nav className="my-4">
<NavbarLinkBills handleClick={closeNav} />
<NavbarLinkTestimony handleClick={closeNav} />
{authenticated && notifications ? (
<NavbarLinkNewsfeed handleClick={closeNav} />
) : (
<></>
)}
<NavDropdown className={"navLink-primary"} title={t("about")}>
<NavbarLinkGoals handleClick={closeNav} />
<NavbarLinkTeam handleClick={closeNav} />
Expand All @@ -82,6 +89,7 @@ export const MobileNav: React.FC<React.PropsWithChildren<unknown>> = () => {
}

const { authenticated } = useAuth()
const { notifications } = useFlags()
const [isExpanded, setIsExpanded] = useState(false)
const [whichMenu, setWhichMenu] = useState("site")
const { t } = useTranslation(["common", "auth"])
Expand Down
21 changes: 21 additions & 0 deletions components/NavbarComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,27 @@ export const NavbarLinkLogo: React.FC<
)
}

export const NavbarLinkNewsfeed: React.FC<
React.PropsWithChildren<{
handleClick?: any
other?: any
}>
> = ({ handleClick, other }) => {
const isMobile = useMediaQuery("(max-width: 768px)")
const { t } = useTranslation(["common", "auth", "profile"])
return (
<Nav.Item onClick={handleClick}>
<NavLink
className={isMobile ? "navLink-primary" : "text-white-50"}
href="/newsfeed"
{...other}
>
{t("navigation.newsfeed")}
</NavLink>
</Nav.Item>
)
}

export const NavbarLinkProcess: React.FC<
React.PropsWithChildren<{
handleClick?: any
Expand Down
Loading
Loading