Skip to content

Commit

Permalink
Merge pull request #50 from now-u/dev
Browse files Browse the repository at this point in the history
Release blogs
  • Loading branch information
JElgar authored Sep 30, 2024
2 parents 3983f02 + 97a4ccd commit f82fd76
Show file tree
Hide file tree
Showing 30 changed files with 233 additions and 1,422 deletions.
72 changes: 45 additions & 27 deletions src/app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,83 @@
import React from "react";
import fs from "fs";
import md from "markdown-it";
import { getPostBySlug } from "../utils";
import { type BlogWriter } from "../writers";
import Image from "next/image";
import Link from "next/link";
import { notFound } from "next/navigation";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faUserCircle } from "@fortawesome/free-solid-svg-icons";

// NOTE: https://blog.openreplay.com/creating-a-markdown-blog-powered-by-next-js-in-under-an-hour

function AuthorTile(props: { author: BlogWriter }): JSX.Element {
const { author } = props;
function AuthorTile(props: {
name: string;
description: string;
profilePictureURL: string;
}): JSX.Element {
return (
<div className="flex flex-col md:flex-row">
<div className="h-32 w-32 mb-6 md:w-96 relative mr-5">
<Image
src={author.profile_picture_url}
alt="Blog Image"
className="object-cover w-full h-full rounded-full"
sizes="100vw"
fill
/>
<div className="flex flex-col mt-10 mb-6 gap-4 md:flex-row md:items-center">
<div className="aspect-square h-24 w-24 md:h-32 md:w-32 relative">
{props.profilePictureURL !== "" ? (
<Image
src={props.profilePictureURL}
alt="Blog Image"
className="object-cover object-center w-full h-full rounded-full m-0"
sizes="100vw"
fill
/>
) : (
<FontAwesomeIcon
className="object-cover object-center w-full h-full rounded-full m-0"
color="#DDD"
icon={faUserCircle}
/>
)}
</div>
<div>
<p className="mb-2 font-bold"> {author.full_name} </p>
<p className="mt-0"> {author.description} </p>
<p className="m-0 mb-2 font-bold"> {props.name} </p>
<p className="m-0"> {props.description} </p>
</div>
</div>
);
}

// TODO Type this properly
export async function generateStaticParams(): Promise<any> {
const postsFilePath = "src/app/blog/posts";
const fileNames = fs.readdirSync(postsFilePath);
return fileNames.map((fileName) => ({
slug: fileName.replace(".md", ""),
}));
}

export default async function Page({
params,
}: {
params: { slug: string };
}): Promise<JSX.Element> {
const blog = await getPostBySlug(params.slug);
if (blog === undefined) {
notFound();
}

return (
<>
<title>{`now-u | ${blog.title}`}</title>

<div className="w-full flex flex-col items-center lg:my-10">
<div className="flex-col prose mx-4">
<div className="flex-col prose prose-gray mx-4">
<Link className="underline text-orange font-bold" href={"/blog"}>
{" "}
{"< "} Back{" "}
</Link>
<div className="mt-4">
<h1 className="text-3xl">{blog.title}</h1>
{blog.subtitle !== "" && (
<p className="text-gray-500">{blog.subtitle}</p>
)}
</div>
<hr className="my-0"/>
<div
className="mt-2"
dangerouslySetInnerHTML={{ __html: md().render(blog.content) }}
/>
{blog.author !== null && <AuthorTile author={blog.author} />}
{blog.author !== null && (
<AuthorTile
name={blog.author.full_name}
description={blog.author.description}
profilePictureURL={blog.author.profile_picture_url}
/>
)}
</div>
</div>
</>
Expand Down
45 changes: 35 additions & 10 deletions src/app/blog/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
import React from "react";

import { HeaderSubtitle } from "@/components/Header";

import { getPosts } from "./utils";
import { BlogTile } from "@/components/BlogTile";
import { BlogTile, type BlogTileProps } from "@/components/BlogTile";
import { Newsletter } from "@/components/Newsletter";
import { getBlogPosts } from "@/services/api";

async function Blog(): Promise<JSX.Element> {
const blogs = await getPosts();
const remotePosts = await getBlogPosts();

const allBlogs: BlogTileProps[] = remotePosts.map((blog) => {
return {
id: `remote-blog-${blog.id.toString()}`,
href: `blog/${blog.slug}`,
headerImageURL: blog.header_image.url,
title: blog.title,
authors: blog.authors
.filter((author) => author.name)
.map((author) => author.name ?? ""),
readingTime: blog.reading_time.toString(),
};
});

return (
<>
<title>now-u | Blog</title>
Expand All @@ -16,13 +29,25 @@ async function Blog(): Promise<JSX.Element> {
title="Blog"
subtitle="Find all the latest blog articles from now-u below"
/>
<div className="flex flex-col items-center">
<div className="max-w-screen-2xl grid col-span-1 first:col-span-2 md:grid-cols-2 gap-5 m-5 sm:mx-32 sm:my-10">
{blogs.map((blog) => (
<BlogTile key={blog.slug} post={blog} />
))}

{allBlogs.length > 0 ? (
<div className="max-w-screen-2xl">
<div className="grid grid-cols-1 md:grid-cols-2 gap-5 m-5 sm:mx-32 sm:my-10">
{allBlogs.map((blog) => (
<BlogTile key={blog.id} {...blog} />
))}
</div>
</div>
</div>
) : (
<div className="mx-auto text-center my-8 gap-4 flex flex-col items-center">
<h2 className="font-bold text-3xl">Oops! Something went wrong.</h2>
<p className="text-lg">
Sorry, we couldn&apos;t load the blog articles at the moment. <br />
Please try again later.
</p>
</div>
)}

<div className="flex justify-center">
<Newsletter />
</div>
Expand Down
38 changes: 0 additions & 38 deletions src/app/blog/posts/advancing-economic-justice-for-women.md

This file was deleted.

32 changes: 0 additions & 32 deletions src/app/blog/posts/celebrating-one-year-of-now-u.md

This file was deleted.

45 changes: 0 additions & 45 deletions src/app/blog/posts/covid-19-and-waste.md

This file was deleted.

Loading

0 comments on commit f82fd76

Please sign in to comment.