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

ft/Engineering Blog: Render a blog #868

Merged
merged 24 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
24fd71e
Render blog
kelvinkipruto Sep 2, 2024
4d31d0a
Working blog page
kelvinkipruto Sep 2, 2024
0b19771
Render single blog
kelvinkipruto Sep 2, 2024
7cc7ac1
Update blog content
kelvinkipruto Sep 3, 2024
be98b74
Fix mobile rendering
kelvinkipruto Sep 3, 2024
4671a41
Improve rendering of single blog
kelvinkipruto Sep 3, 2024
8558abd
Improve fetching blog function
kelvinkipruto Sep 3, 2024
ae2108a
Empty component
kelvinkipruto Sep 3, 2024
9f75323
Working syntax highlighting
kelvinkipruto Sep 3, 2024
b2121ba
Add syntax highlighting to code
kelvinkipruto Sep 3, 2024
3302d1e
Merge branch 'main' of https://github.com/CodeForAfrica/ui into ft/re…
kelvinkipruto Sep 3, 2024
4a395ee
Remove unused packages
kelvinkipruto Sep 3, 2024
f4d7c9e
Add languages we use
kelvinkipruto Sep 3, 2024
446b0e6
Add code copy btn
kelvinkipruto Sep 4, 2024
3f32190
Remove blog header image
kelvinkipruto Sep 4, 2024
97fc801
Merge branch 'main' of https://github.com/CodeForAfrica/ui into ft/re…
kelvinkipruto Sep 4, 2024
df05f0d
Use catalog dependencies
kelvinkipruto Sep 4, 2024
03be05d
Merge branch 'main' of https://github.com/CodeForAfrica/ui into ft/re…
kelvinkipruto Sep 5, 2024
a7d8db8
Rename Empty to NoPosts
kelvinkipruto Sep 5, 2024
fd6df1b
Review fix
kelvinkipruto Sep 5, 2024
f1b109b
Use next/link
kelvinkipruto Sep 6, 2024
122c850
Merge branch 'main' of https://github.com/CodeForAfrica/ui into ft/re…
kelvinkipruto Sep 6, 2024
1931f4c
use StyledLink
kelvinkipruto Sep 6, 2024
2276210
Review fixes
kelvinkipruto Sep 7, 2024
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
12 changes: 12 additions & 0 deletions apps/engineeringblog/app/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ArticleContent } from "@/engineeringblog/components/Article";
import { Box } from "@mui/material";
import { getContent } from "@/engineeringblog/utils";

export default async function Page({ params }: { params: { slug: string } }) {
const post = await getContent(params.slug);
return (
<Box component="article">
<ArticleContent article={post} />
</Box>
);
}
3 changes: 0 additions & 3 deletions apps/engineeringblog/app/articles/page.tsx

This file was deleted.

17 changes: 0 additions & 17 deletions apps/engineeringblog/app/articles/sample-1/demo-1.tsx

This file was deleted.

14 changes: 0 additions & 14 deletions apps/engineeringblog/app/articles/sample-1/page.mdx

This file was deleted.

22 changes: 18 additions & 4 deletions apps/engineeringblog/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import { Box, Container } from "@mui/material";
import { Container } from "@mui/material";
import { ArticleList } from "@/engineeringblog/components/Article";
import { getAllContents } from "@/engineeringblog/utils";
import NoPosts from "@/engineeringblog/components/NoPosts";

export default async function index() {
const posts = await getAllContents();

if (!posts.length) {
return <NoPosts />;
}

export default function index() {
return (
<Container>
<Box minHeight="1000px">Homepage</Box>
<Container
sx={{
kelvinkipruto marked this conversation as resolved.
Show resolved Hide resolved
px: { xs: 2.5, sm: 0 },
py: { xs: 2.5, sm: 5 },
}}
>
<ArticleList articles={posts} />
</Container>
);
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 57 additions & 0 deletions apps/engineeringblog/components/Article/ArticleCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"use client";
import { StyledLink } from "@/commons-ui/next/Link";
import { ArticleWithoutContent } from "@/engineeringblog/utils";
import {
Card,
CardActionArea,
CardContent,
CardMedia,
Typography,
} from "@mui/material";
import React from "react";

const ArticleCard = React.forwardRef(function ArticleCard(
{ title, publishDate, featuredImage, slug }: ArticleWithoutContent,
ref: React.Ref<HTMLDivElement>,
) {
return (
<Card
elevation={0}
square={true}
variant="outlined"
sx={{
"&:hover": {
border: `1px solid "#ED1C24"`,
img: {
filter: "none",
},
},
border: "1px solid #DAD5D5",
filter: "drop-shadow(0px 4px 8px rgba(0, 0, 0, 0.1))",
}}
>
<CardActionArea component={slug ? StyledLink : "div"} href={slug}>
<CardMedia
component="img"
src={featuredImage}
sx={{
height: "217.64px",
filter:
"contrast(60%) sepia(100%) hue-rotate(190deg) saturate(500%)",
}}
/>
<CardContent>
<Typography variant="subtitle1">{title}</Typography>
<Typography
sx={{ color: "#9F9494", display: "block", mt: 2 }}
variant="caption"
>
{publishDate}
</Typography>
</CardContent>
</CardActionArea>
</Card>
);
});

export default ArticleCard;
40 changes: 40 additions & 0 deletions apps/engineeringblog/components/Article/ArticleContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"use client";
import { Section } from "@commons-ui/core";
import React from "react";
import { Figure } from "@commons-ui/next";
import { Box } from "@mui/material";
import ArticleHeader from "./ArticleHeader";
import { Article } from "@/engineeringblog/utils";
import Markdown from "@/engineeringblog/components/Markdown";
const ArticleContent = React.forwardRef(function ArticleContent(
{
article,
}: {
article: Article;
},
ref: React.Ref<HTMLDivElement>,
) {
const { title, description, featuredImage, date, content } = article;

return (
<Box ref={ref}>
<ArticleHeader date={date} excerpt={description} title={title} sx={{}} />
<Section
component="header"
sx={{
px: { xs: 2.5, sm: 0 },
py: 2.5,
maxWidth: {
sm: "648px",
md: "912px",
},
}}
ref={ref}
>
<Markdown markdown={content} />
</Section>
</Box>
);
});

export default ArticleContent;
54 changes: 54 additions & 0 deletions apps/engineeringblog/components/Article/ArticleHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"use client";

import { Section } from "@commons-ui/core";
import { Typography } from "@mui/material";
import React from "react";

const ArticleHeader = React.forwardRef(function ArticleHeader(
{
date,
excerpt,
sx,
title,
}: { date: string; excerpt: string; sx: any; title: string },
ref,
) {
return (
<Section
component="header"
sx={{
px: { xs: 2.5, sm: 0 },
maxWidth: {
sm: "648px",
md: "912px",
},
...sx,
}}
ref={ref}
>
<Typography
component="div"
variant="body2"
sx={{ mt: { xs: 2.5, md: 7.5 } }}
>
{date}
</Typography>
<Typography component="div" variant="h1" sx={{ mt: { xs: 2.5, md: 5 } }}>
{title}
</Typography>
<Typography
component="div"
variant="body1"
sx={{
color: "primary.main",
mt: { xs: 2.5, md: 5 },
typography: { md: "subheading" },
}}
>
{excerpt}
</Typography>
</Section>
);
});

export default ArticleHeader;
34 changes: 34 additions & 0 deletions apps/engineeringblog/components/Article/ArticleList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use client";

import { Section } from "@commons-ui/core";
import { Grid } from "@mui/material";
import React from "react";
import ArticleCard from "./ArticleCard";
import { ArticleWithoutContent } from "@/engineeringblog/utils";

const ArticleList = React.forwardRef(function ArtilceList(
{
articles,
}: {
articles: ArticleWithoutContent[];
},
ref: React.Ref<HTMLDivElement>,
) {
return (
<Section ref={ref}>
<Grid
container
rowSpacing={{ xs: "28px", md: 5 }}
columnSpacing={{ xs: 0, sm: "18px", lg: "28px" }}
>
{articles?.map((article) => (
<Grid item xs={12} sm={4} key={article.slug}>
<ArticleCard {...article} />
</Grid>
))}
</Grid>
</Section>
);
});

export default ArticleList;
5 changes: 5 additions & 0 deletions apps/engineeringblog/components/Article/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import ArticleList from "./ArticleList";
import ArticleCard from "./ArticleCard";
import ArticleContent from "./ArticleContent";

export { ArticleList, ArticleCard, ArticleContent };
48 changes: 48 additions & 0 deletions apps/engineeringblog/components/Markdown/CopyCodeButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from "react";
import { IconButton } from "@mui/material";
import CopyIcon from "@/engineeringblog/assets/icons/Type=copy, Size=24, Color=White.svg";
import CheckIcon from "@/engineeringblog/assets/icons/Type=check-circle, Size=24, Color=White.svg";

export default function CopyCodeButton({
children,
}: {
children: JSX.Element;
}) {
const [copyOk, setCopyOk] = React.useState(false);

const handleClick = (_e: React.MouseEvent) => {
navigator.clipboard.writeText(children.props.children);

setCopyOk(true);
setTimeout(() => {
setCopyOk(false);
}, 500);
};

return (
<IconButton
sx={{
color: "white",
position: "absolute",
top: "10px",
right: "10px",
fontSize: "1.5em",
cursor: "pointer",
transition: "all 0.3s ease -in -out",
}}
>
{copyOk ? (
<CheckIcon />
) : (
<CopyIcon
sx={{
"&:hover": {
color: "#fff",
},
}}
onClick={handleClick}
/>
)}
</IconButton>
);
}
Loading
Loading