diff --git a/apps/codeforafrica/src/components/Opportunities/Opportunities.js b/apps/codeforafrica/src/components/Opportunities/Opportunities.js index 36e98c6d9..324433d0e 100644 --- a/apps/codeforafrica/src/components/Opportunities/Opportunities.js +++ b/apps/codeforafrica/src/components/Opportunities/Opportunities.js @@ -15,20 +15,23 @@ import equalsIgnoreCase from "@/codeforafrica/utils/equalsIgnoreCase"; const Opportunities = React.forwardRef(function Opportunities( { tags, - opportunities: { - pagination: { count: countProp, page: pageProp = 1 }, - results: resultsProp, - }, + opportunities: opportunitiesList, + pagination: { count: countProp, page: pageProp = 1 }, sx, + slug, + labels: { search, readMore }, }, ref, ) { const [count, setCount] = useState(countProp); const [page, setPage] = useState(pageProp); - const [opportunities, setOpportunities] = useState(resultsProp); + const [opportunities, setOpportunities] = useState(opportunitiesList); const [q, setQ] = useState(); - const [tag, setTag] = useState(ALL_TAG); - const queryParams = useFilterQuery({ page, q, tag }); + const [tag, setTag] = useState({ + name: ALL_TAG, + slug: ALL_TAG, + }); + const queryParams = useFilterQuery({ page, q, tag: tag.slug }); const router = useRouter(); const handleChangePage = (_, value) => { @@ -40,23 +43,28 @@ const Opportunities = React.forwardRef(function Opportunities( }; const handleChangeTag = (_, value) => { - const newValue = - (value && tags.find((t) => equalsIgnoreCase(value, t))) || ALL_TAG; + const newValue = (value && + tags.find((t) => equalsIgnoreCase(value, t.slug))) || { + name: ALL_TAG, + slug: ALL_TAG, + }; setTag(newValue); setPage(1); }; - const { data } = useOpportunities({ page, q, tag }); + const { data } = useOpportunities({ page, q, tag: tag.slug }); useEffect(() => { if (data) { - const { results, pagination } = data; + const { posts: results, pagination } = data; setCount(pagination.count); setOpportunities([...results]); } }, [data]); useEffect(() => { - router.push(queryParams, undefined, { + const [pathname] = router.asPath.split("?"); + const url = pathname ? `${pathname}${queryParams}` : queryParams; + router.push(url, undefined, { scroll: true, shallow: true, }); @@ -83,13 +91,15 @@ const Opportunities = React.forwardRef(function Opportunities( onChangeTag={handleChangeTag} q={q} tag={tag} - tags={tags} + tags={[{ name: ALL_TAG, slug: ALL_TAG }, ...tags]} + slug={slug} SearchInputProps={{ - placeholder: "Search opportunities", + placeholder: search, }} /> diff --git a/apps/codeforafrica/src/components/Opportunities/useOpportunities.js b/apps/codeforafrica/src/components/Opportunities/useOpportunities.js index 144f05651..35d444cf6 100644 --- a/apps/codeforafrica/src/components/Opportunities/useOpportunities.js +++ b/apps/codeforafrica/src/components/Opportunities/useOpportunities.js @@ -6,7 +6,14 @@ const fetcher = (url) => fetch(url).then((res) => res.json()); function useOpportunities(query) { const queryParams = useFilterQuery(query); - const { data, error } = useSWR(`/api/opportunities${queryParams}`, fetcher); + const path = "opportunities"; + const queryParamsWithPath = queryParams + ? `${queryParams}&path=${path}` + : `?path=${path}`; + const { data, error } = useSWR( + `/api/v1/posts${queryParamsWithPath}`, + fetcher, + ); return { data, diff --git a/apps/codeforafrica/src/components/OpportunityCard/OpportunityCard.js b/apps/codeforafrica/src/components/OpportunityCard/OpportunityCard.js index dce522304..0088467e7 100644 --- a/apps/codeforafrica/src/components/OpportunityCard/OpportunityCard.js +++ b/apps/codeforafrica/src/components/OpportunityCard/OpportunityCard.js @@ -12,15 +12,24 @@ import { import React from "react"; const OpportunityCard = React.forwardRef(function OpportunityCard(props, ref) { - const { featureImage, html, href, publishedAt, sx, tags, title } = props; + const { + image: { src, alt }, + excerpt, + href, + publishedAt, + sx, + tags, + title, + readMore, + } = props; - if (!(title && html)) { + if (!(title && excerpt)) { return null; } return ( - + {title} @@ -42,15 +51,15 @@ const OpportunityCard = React.forwardRef(function OpportunityCard(props, ref) { WebkitLineClamp: "3", WebkitBoxOrient: "vertical", overflow: "hidden", - maxHeight: 28 * 3, + maxHeight: 28 * 3.5, }} > - {html} + {excerpt} diff --git a/apps/codeforafrica/src/components/OpportunityCardList/OpportunityCardList.js b/apps/codeforafrica/src/components/OpportunityCardList/OpportunityCardList.js index 6de32a0fd..1456852f8 100644 --- a/apps/codeforafrica/src/components/OpportunityCardList/OpportunityCardList.js +++ b/apps/codeforafrica/src/components/OpportunityCardList/OpportunityCardList.js @@ -5,7 +5,7 @@ import OpportunityCard from "@/codeforafrica/components/OpportunityCard"; const OpportunityCardList = React.forwardRef( function OpportunityCardList(props, ref) { - const { opportunities, ...other } = props; + const { opportunities, readMore, ...other } = props; if (!opportunities?.length) { return null; @@ -13,7 +13,11 @@ const OpportunityCardList = React.forwardRef( return ( {opportunities.map((opportunity) => ( - + ))} ); diff --git a/apps/codeforafrica/src/lib/data/blockify/index.js b/apps/codeforafrica/src/lib/data/blockify/index.js index 7f14bbee2..fa65dcea7 100644 --- a/apps/codeforafrica/src/lib/data/blockify/index.js +++ b/apps/codeforafrica/src/lib/data/blockify/index.js @@ -1,6 +1,7 @@ import getInvolved from "./get-involved"; import hero from "./hero"; import meetOurTeam from "./meetOurTeam"; +import opportunities from "./opportunities"; import ourImpact from "./our-impact"; import ourTeam from "./ourTeam"; import stories from "./stories"; @@ -9,9 +10,10 @@ const propsifyBlockBySlug = { "get-involved": getInvolved, hero, "meet-our-team": meetOurTeam, + opportunities, "our-impact": ourImpact, - stories, "our-team": ourTeam, + stories, }; async function blockify(blocks, api, context) { diff --git a/apps/codeforafrica/src/lib/data/blockify/opportunities.js b/apps/codeforafrica/src/lib/data/blockify/opportunities.js new file mode 100644 index 000000000..ec700f3de --- /dev/null +++ b/apps/codeforafrica/src/lib/data/blockify/opportunities.js @@ -0,0 +1,38 @@ +import { getPosts, formatTags } from "@/codeforafrica/lib/data/utils/posts"; + +async function opportunities(block, api, context) { + const { query } = context; + const { labels } = block; + + const options = { + ...query, + }; + + const { posts, pagination } = await getPosts(api, options, "opportunities"); + + const { docs: allOpportunities } = await api.getCollection("posts", { + limit: 0, + where: { + "tags.name": { + like: "opportunities", + }, + }, + }); + + const allTags = allOpportunities.reduce((acc, story) => { + const { tags = [] } = story; + return [...acc, ...tags.map(({ name, slug }) => ({ name, slug }))]; + }, []); + + const tags = formatTags(allTags); + + return { + labels, + tags, + opportunities: posts, + pagination, + slug: "opportunities", + }; +} + +export default opportunities; diff --git a/apps/codeforafrica/src/pages/[...slugs].page.js b/apps/codeforafrica/src/pages/[...slugs].page.js index 1b781a8b2..d3d7ba9d8 100644 --- a/apps/codeforafrica/src/pages/[...slugs].page.js +++ b/apps/codeforafrica/src/pages/[...slugs].page.js @@ -14,6 +14,7 @@ import Hero from "@/codeforafrica/components/Hero"; import JoinOurSlack from "@/codeforafrica/components/JoinOurSlack"; import MeetOurTeam from "@/codeforafrica/components/MeetOurTeam"; import NewsAndStories from "@/codeforafrica/components/NewsAndStories"; +import Opportunities from "@/codeforafrica/components/Opportunities"; import OurImpact from "@/codeforafrica/components/OurImpact"; import OurMission from "@/codeforafrica/components/OurMission"; import OurPartners from "@/codeforafrica/components/OurPartners"; @@ -33,12 +34,13 @@ const componentsBySlugs = { "join-our-slack": JoinOurSlack, "meet-our-team": MeetOurTeam, "news-stories": NewsAndStories, + opportunities: Opportunities, "our-guiding-principles": GuidingPrinciplesCardList, "our-impact": OurImpact, "our-mission": OurMission, "our-partners": OurPartners, - "page-header": PageHeader, "our-team": OurTeam, + "page-header": PageHeader, projects: FeaturedProjects, };