Skip to content
Open
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
209 changes: 209 additions & 0 deletions components/InTheNews/InTheNews.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import { useState } from "react"
import { Col, Row, Container, Badge, Spinner } from "../bootstrap"
import Tab from "react-bootstrap/Tab"
import Nav from "react-bootstrap/Nav"
import Dropdown from "react-bootstrap/Dropdown"
import { useMediaQuery } from "usehooks-ts"
import { useTranslation } from "next-i18next"
import { NewsCard } from "./NewsCard"
import { NewsType, NewsItem, useNews } from "components/db/news"

type NewsFeedProps = {
type: NewsType
newsItems: NewsItem[]
}

type TabCounts = {
media: number
awards: number
books: number
}

const NewsFeed = ({ type, newsItems }: NewsFeedProps) => {
return (
<div className="d-flex flex-column align-items-left gap-1 w-100">
{newsItems
.filter(item => item.type === type)
.map((item, index) => (
<NewsCard key={index} newsItem={item} />
))}
</div>
)
}

export const InTheNews = () => {
const { t } = useTranslation("inTheNews")
const isMobile = useMediaQuery("(max-width: 768px)")
const { result: newsItems, loading } = useNews()

const counts: TabCounts | null = newsItems
? {
media: newsItems.filter(item => item.type === "article").length,
awards: newsItems.filter(item => item.type === "award").length,
books: newsItems.filter(item => item.type === "book").length
}
: null

return (
<Container className="ptx-4 pt-5 gap-4 min-vh-100">
<h1 className="fw-bold m-3" style={{ fontSize: "5rem" }}>
{t("title")}
</h1>
<div className="d-flex flex-column bg-white rounded-4 my-5 gap-4 p-4">
<Tab.Container defaultActiveKey="media">
{isMobile ? (
<TabDropdown counts={counts} />
) : (
<TabGroup counts={counts} />
)}
<Row className="g-0">
<Col>
{loading ? (
<div className="d-flex justify-content-center p-5">
<Spinner animation="border" role="status">
<span className="visually-hidden">Loading...</span>
</Spinner>
</div>
) : (
<Tab.Content>
<Tab.Pane eventKey="media">
<div className="d-flex flex-column align-items-center">
<NewsFeed type="article" newsItems={newsItems ?? []} />
</div>
</Tab.Pane>
<Tab.Pane eventKey="awards">
<div className="d-flex flex-column align-items-center">
<NewsFeed type="award" newsItems={newsItems ?? []} />
</div>
</Tab.Pane>
<Tab.Pane eventKey="books">
<div className="d-flex flex-column align-items-center">
<NewsFeed type="book" newsItems={newsItems ?? []} />
</div>
</Tab.Pane>
</Tab.Content>
)}
</Col>
</Row>
</Tab.Container>
</div>
</Container>
)
}

const TabGroup = ({ counts }: { counts: TabCounts | null }) => {
const { t } = useTranslation("inTheNews")
return (
<Row className="g-0 fs-4 fw-semibold">
<Col md={4} className="text-center">
<Nav className="in-the-news flex-column">
<Nav.Item>
<Nav.Link eventKey="media">
<div className="d-flex justify-content-center align-items-center gap-3 p-4">
{t("media.title")}
<Badge
bg="secondary"
className="rounded-pill px-4 fw-bold"
style={{
fontSize: "20px",
visibility: counts ? "visible" : "hidden"
}}
>
{counts ? counts.media : 0}
</Badge>
</div>
</Nav.Link>
</Nav.Item>
</Nav>
</Col>
<Col md={4} className="text-center">
<Nav className="in-the-news flex-column">
<Nav.Item>
<Nav.Link eventKey="awards">
<div className="d-flex justify-content-center align-items-center gap-3 p-4">
{t("awards.title")}
<Badge
bg="secondary"
className="rounded-pill px-4 fw-bold"
style={{
fontSize: "20px",
visibility: counts ? "visible" : "hidden"
}}
>
{counts ? counts.awards : 0}
</Badge>
</div>
</Nav.Link>
</Nav.Item>
</Nav>
</Col>
<Col md={4} className="text-center">
<Nav className="in-the-news flex-column">
<Nav.Item>
<Nav.Link eventKey="books">
<div className="d-flex justify-content-center align-items-center gap-3 p-4">
{t("books.title")}
<Badge
bg="secondary"
className="rounded-pill px-4 fw-bold"
style={{
fontSize: "20px",
visibility: counts ? "visible" : "hidden"
}}
>
{counts ? counts.books : 0}
</Badge>
</div>
</Nav.Link>
</Nav.Item>
</Nav>
</Col>
</Row>
)
}

const TabDropdown = ({ counts }: { counts: TabCounts | null }) => {
const { t } = useTranslation("inTheNews")
const [selectedTab, setSelectedTab] = useState<string>("Media")

const handleTabClick = (tabTitle: string) => {
setSelectedTab(tabTitle)
}

return (
<Row className="p-3 g-0">
<Col md={12}>
<Dropdown className="our-team-dropdown">
<Dropdown.Toggle className="our-team-dropdown-button">
<span style={{ float: "left" }}>{selectedTab}</span>
</Dropdown.Toggle>
<Dropdown.Menu className="p-2">
<Dropdown.Item
className="p-2"
eventKey="media"
onClick={() => handleTabClick("Media")}
>
{t("media.title")}
</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item
className="p-2"
eventKey="awards"
onClick={() => handleTabClick("Awards")}
>
{t("awards.title")}
</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item
className="p-2"
eventKey="books"
onClick={() => handleTabClick("Books")}
>
{t("books.title")}
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</Col>
</Row>
)
}
68 changes: 68 additions & 0 deletions components/InTheNews/NewsCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import ArrowForward from "@mui/icons-material/ArrowForward"
import { useTranslation } from "next-i18next"
import { NewsItem } from "components/db"

type NewsCardProps = {
newsItem: NewsItem
}

export const NewsCard = ({ newsItem }: NewsCardProps) => {
const { t } = useTranslation("inTheNews")
return (
<div
className="d-flex flex-row flex-fill gap-5 p-4"
style={{
backgroundColor: "#F6F7FF",
borderTop: "6px solid var(--bs-secondary)"
}}
>
<div
className="d-flex flex-fill flex-column gap-2"
style={{ minWidth: 0 }}
>
<div className="d-flex flex-row align-items-center gap-4 mb-1">
<p className="m-0 fw-medium">
{new Date(newsItem.publishDate).toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
timeZone: "UTC"
})}
</p>
<div
style={{
width: "1px",
height: "1em",
backgroundColor: "black",
alignSelf: "center"
}}
/>
<p className="m-0">{newsItem.author}</p>
</div>
<div className="">
<a
className="fw-bold fs-4 lh-1 tracking-tight text-decoration-underline"
href={newsItem.url}
target="_blank"
rel="noopener noreferrer"
>
{newsItem.title}
</a>
</div>
<div className="text-truncate">{newsItem.description}</div>
</div>
<div className="align-self-end flex-shrink-0">
<a
className="d-flex gap-1 text-decoration-none hover-underline"
href={newsItem.url}
target="_blank"
rel="noopener noreferrer"
style={{ color: "#1587D3", fontWeight: 800 }}
>
{t("readMoreButton")}
<ArrowForward />
</a>
</div>
</div>
)
}
3 changes: 3 additions & 0 deletions components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
NavbarLinkEffective,
NavbarLinkFAQ,
NavbarLinkGoals,
NavbarLinkInTheNews,
NavbarLinkLogo,
NavbarLinkNewsfeed,
NavbarLinkProcess,
Expand Down Expand Up @@ -92,6 +93,7 @@ const MobileNav: React.FC<React.PropsWithChildren<unknown>> = () => {
<NavbarLinkSupport handleClick={closeNav} />
<NavbarLinkFAQ handleClick={closeNav} />
<NavbarLinkAI handleClick={closeNav} />
<NavbarLinkInTheNews handleClick={closeNav} />
</NavDropdown>

<NavDropdown className={"navLink-primary"} title={t("learn")}>
Expand Down Expand Up @@ -228,6 +230,7 @@ const DesktopNav: React.FC<React.PropsWithChildren<unknown>> = () => {
<NavbarLinkSupport />
<NavbarLinkFAQ />
<NavbarLinkAI />
<NavbarLinkInTheNews />
</Dropdown.Menu>
</Dropdown>
</div>
Expand Down
21 changes: 21 additions & 0 deletions components/NavbarComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -378,3 +378,24 @@ export const NavbarLinkWhyUse: React.FC<
</NavDropdown.Item>
)
}

export const NavbarLinkInTheNews: React.FC<
React.PropsWithChildren<{
handleClick?: any
other?: any
}>
> = ({ handleClick, other }) => {
const isMobile = useMediaQuery("(max-width: 768px)")
const { t } = useTranslation(["common", "auth"])
return (
<NavDropdown.Item onClick={handleClick}>
<NavLink
className={isMobile ? "navLink-primary" : ""}
href="/about/in-the-news"
{...other}
>
{t("navigation.inTheNews")}
</NavLink>
</NavDropdown.Item>
)
}
5 changes: 3 additions & 2 deletions components/db/news.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { collection, getDocs, orderBy, Timestamp } from "firebase/firestore"
import { collection, getDocs, orderBy, query, Timestamp } from "firebase/firestore"
import { useAsync } from "react-async-hook"
import { firestore } from "../firebase"

Expand All @@ -17,7 +17,8 @@ export type NewsItem = {

export async function listNews(): Promise<NewsItem[]> {
const newsRef = collection(firestore, "news")
const result = await getDocs(newsRef)
const q = query(newsRef, orderBy("publishDate", "desc"))
const result = await getDocs(q)
return result.docs.map(d => ({ id: d.id, ...d.data() } as NewsItem))
}

Expand Down
17 changes: 17 additions & 0 deletions pages/about/in-the-news.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { createPage } from "../../components/page"
import { InTheNews } from "../../components/InTheNews/InTheNews"
import { createGetStaticTranslationProps } from "components/translations"

export default createPage({
titleI18nKey: "titles.in_the_news",
Page: () => {
return <InTheNews />
}
})

export const getStaticProps = createGetStaticTranslationProps([
"auth",
"common",
"footer",
"inTheNews"
])
2 changes: 2 additions & 0 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
"aboutTestimony": "About Testimony",
"viewProfile": "View Profile",
"whyUseMaple": "Why Use MAPLE",
"inTheNews": "In The News",
"login": "Login"
},
"new_feature": "*NEW*",
Expand Down Expand Up @@ -180,6 +181,7 @@
"legislative_process": "How To Have Impact Through Legislative Testimony",
"submit_testimony": "Submit Testimony",
"support_maple": "How to Support MAPLE",
"in_the_news": "In The News",
"testimony": "Testimony",
"policies": "Policies",
"unsubscribe": "Unsubscribe",
Expand Down
13 changes: 13 additions & 0 deletions public/locales/en/inTheNews.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"title": "Media, Articles & Insights",
"readMoreButton": "READ MORE",
"media": {
"title": "Media"
},
"awards": {
"title": "Awards"
},
"books": {
"title": "Books"
}
}
Loading
Loading