Skip to content

Commit

Permalink
Merge pull request #90 from ssss-sfu/brian/embed-sanity-blog
Browse files Browse the repository at this point in the history
Brian/embed sanity blog
  • Loading branch information
brianrahadi authored Nov 19, 2023
2 parents 6859707 + 78aab91 commit ac0f3bb
Show file tree
Hide file tree
Showing 40 changed files with 16,114 additions and 3,370 deletions.
78 changes: 78 additions & 0 deletions components/BlogPostPreview.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import Image from "next/image";
import clock from "@images/blog-page/clock.svg";
import person from "@images/blog-page/person.svg";
import { Helmet, HeaderNav } from "@components";
import Link from "next/link";

// TODO refactor to be used or remove this
export class BlogPost {
constructor(
style = "",
title,
date,
slug,
author = "Unknown",
coverImage,
excerpt,
category
) {
(this.style = style),
(this.title = title),
(this.date = date),
(this.slug = slug),
(this.author = author),
(this.coverImage = coverImage),
(this.excerpt = excerpt),
(this.category = category);
}

static fromObject(object) {
return new BlogPost(
object.style,
object.title,
object.date,
object.slug,
object.author,
object.coverImage,
object.excerpt,
object.category
);
}
}

/**
* @param {BlogPost} blogPost - blogPost class
* @returns Preview of the blog post
*/
export const BlogPostPreview = ({ post }) => {
return (
<div
className={`posts-list ${style === "wide" ? "wide" : ""}${
style === "regular" ? "regular" : ""
}${style === "featured" ? "featured" : ""}`}
>
<div className="post">
<Helmet />
<HeaderNav />
<Link as={`/blog/${slug}`} href="/blog/[slug]">
<article className="post">
<div className="thumbnail">
<Image src={coverImage} alt="thumbnail" layout="fill" />
<div className="overlay"></div>
</div>
<div className="text">
<div className="title">{title}</div>
<div className="meta-info">
<Image src={clock} height={16} width={16} alt="Clock" />
<div>{date.toString()}</div>
<Image src={person} height={16} width={16} alt="Person" />
<div>{author.name}</div>
</div>
<div className="summary">{excerpt}</div>
</div>
</article>
</Link>
</div>
</div>
);
};
11 changes: 11 additions & 0 deletions components/BlogPostPreviewList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { BlogPostPreview } from "./BlogPostPreview";

// TODO refactor to be used or remove this
export const BlogPostPreviewList = ({ blogPosts }) =>
blogPosts.length > 0 ? (
blogPosts.map((post) => (
<BlogPostPreview key={post.title} blogPost={post} />
))
) : (
<div>No blog post is listed at the moment</div>
);
33 changes: 33 additions & 0 deletions components/Card.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Image from "next/image";

import { urlForImage } from "../pages/api/sanity.image";
import { formatDate } from "utils/index";
import clock from "@images/blog-page/clock.svg";
import Link from "next/link";

export default function Card({ post }) {
return (
<div className="post">
<Link as={`/blog/${post.slug.current}`} href="/post/[slug]">
<article className="post">
<div className="thumbnail">
<Image
src={urlForImage(post.mainImage).width(500).height(300).url()}
alt="thumbnail"
layout="fill"
/>
<div className="overlay"></div>
</div>
<div className="text">
<div className="title">{post.title}</div>
<div className="meta-info">
<Image src={clock} height={16} width={16} alt="Clock" />
<div>{formatDate(post._createdAt)}</div>
</div>
<div className="summary">{post.excerpt}</div>
</div>
</article>
</Link>
</div>
);
}
3 changes: 3 additions & 0 deletions components/HeaderNav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export const HeaderNav = () => {
<Link href="/resources">
<a className="page-link">Resources</a>
</Link>
<Link href="/blog">
<a className="page-link">Blog</a>
</Link>
</nav>

<div className="socials">
Expand Down
42 changes: 42 additions & 0 deletions lib/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import fs from "fs";
import { join } from "path";
import matter from "gray-matter";

const postsDirectory = join(process.cwd(), "_posts");

//reads all post slugs from the _posts folder
export function getPostSlugs() {
return fs.readdirSync(postsDirectory);
}

export function getPostBySlug(slug, fields) {
const realSlug = slug.replace(/\.md$/, "");
const fullPath = join(postsDirectory, `${realSlug}.md`);
const fileContents = fs.readFileSync(fullPath, "utf8");
const { data, content } = matter(fileContents);
const items = {};
// Ensure only the minimal needed data is exposed
fields.forEach((field) => {
if (field === "slug") {
items[field] = realSlug;
}
if (field === "content") {
items[field] = content;
}

if (typeof data[field] !== "undefined") {
items[field] = data[field];
}
});

return items;
}

export function getAllPosts(fields) {
const slugs = getPostSlugs();
const posts = slugs
.map((slug) => getPostBySlug(slug, fields))
//descending order
.sort((post1, post2) => (post1.date > post2.date ? -1 : 1));
return posts;
}
16 changes: 15 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,18 @@ const nextConfig = {
swcMinify: true,
};

module.exports = nextConfig;
module.exports = {
images: {
domains: ["cdn.sanity.io"],
},
webpack: (config, { isServer }) => {
if (!isServer) {
// don't resolve 'fs' module on the client to prevent this error on build --> Error: Can't resolve 'fs'
config.resolve.fallback = {
fs: false,
};
}

return config;
},
};
Loading

0 comments on commit ac0f3bb

Please sign in to comment.