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

feat(blog): add blog functionalities & markdawn to html libraries and… #67

Merged
merged 5 commits into from
Oct 27, 2023
Merged
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
1,958 changes: 1,923 additions & 35 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"date-fns": "^2.30.0",
"eslint-plugin-jest": "^27.4.2",
"firebase": "^10.5.0",
"gray-matter": "^4.0.3",
"i18next": "^23.5.1",
"next": "^13.5.4",
"next-i18next": "^14.0.3",
Expand All @@ -32,12 +33,15 @@
"react-icons": "^4.11.0",
"react-router-dom": "^6.16.0",
"react-test-renderer": "^18.2.0",
"remark": "^15.0.1",
"remark-html": "^16.0.1",
"tailwind-merge": "^1.14.0"
},
"devDependencies": {
"@commitlint/cli": "^17.7.2",
"@commitlint/config-conventional": "^17.7.0",
"@svgr/webpack": "^8.1.0",
"@tailwindcss/typography": "^0.5.10",
"@testing-library/jest-dom": "^6.1.3",
"@testing-library/react": "^14.0.0",
"@types/react": "^18.2.28",
Expand Down
18 changes: 7 additions & 11 deletions src/components/articlecard/ArticleCard.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Image from "next/image";
import Link from "next/link";

import Button from "@/components/button/Button";
/*
textOnleft prop: is the order of content and image in the design.
In the card, we have content on the left and image on the right, and the reverse order in the following card.
Expand All @@ -15,28 +16,23 @@ const ArticleCard = ({
textOnleft = false,
}) => {
return (
<div className='my-8 flex flex-col w-full px-8 py-5 gap-4 md:flex-row md:gap-10 md:my-16 md:items-center lg:w-[90%] mx-auto'>
<div className='w-full md:w-1/2'>
<div className='my-8 h-fit flex flex-col w-full px-8 py-5 gap-4 md:flex-row md:gap-10 md:my-16 md:items-center lg:w-[90%] mx-auto'>
<div className='w-full md:w-1/2 h-[20rem]'>
<Image
src={imageUrl}
alt={title}
width={500}
height={500}
className='object-cover rounded-lg'
height={400}
className='object-cover rounded-lg h-full w-full'
/>
</div>
<div
className={`${textOnleft ? "md:order-first" : ""}
flex flex-col gap-6 text-center items-center md:text-left md:items-start md:w-1/2 `}
>
<h1 className='text-2xl text-black font-semibold'>{title}</h1>
<p className='text-black md:w-3/4'>{description}</p>
<Link
href={articleUrl}
className='bg-green px-4 py-2 text-white rounded-lg cursor-pointer w-1/2 md:w-fit md:px-6'
>
Read more
</Link>
<p className='text-black md:w-6/7'>{description}</p>
<Button href={articleUrl}>Read more</Button>
</div>
</div>
);
Expand Down
51 changes: 51 additions & 0 deletions src/lib/blogApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import fs from "fs";
import matter from "gray-matter";
import { join } from "path";
import { remark } from "remark";
import html from "remark-html";

// const postsDirectory = join(process.cwd(), '_posts')
const postsDirectory = "./src/pages/blog/_posts";

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))
// sort posts by date in descending order
.sort((post1, post2) => (post1.date > post2.date ? -1 : 1));
return posts;
}

export async function markdownToHtml(markdown) {
const result = await remark().use(html).process(markdown);
return result.toString();
}
95 changes: 95 additions & 0 deletions src/pages/blog/[slug].jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/* eslint-disable @next/next/no-img-element */
import ErrorPage from "next/error";
import { useRouter } from "next/router";

import { getAllPosts, getPostBySlug, markdownToHtml } from "@/lib/blogApi";

const PostHeader = ({ title, image, imageAlt, date, timeToRead }) => {
return (
<>
<div className='mb-20 text-center'>
<img
src={image}
alt={imageAlt}
className='w-full h-[35rem] object-cover rounded-lg'
/>
<h1 className='text-3xl my-8'>{title}</h1>
<p>{`Time to read ${timeToRead} min`} </p>
<p>{`publiched: ${new Date(date).toDateString()}`}</p>
</div>
</>
);
};
const PostBody = ({ content }) => {
return (
<div className='max-w-5xl mx-auto'>
<div
className='prose-p:w-full lg:prose-xl w-full lg:w-[58rem] prose prose-override-width text-black
prose-headings:text-black
prose-h4:text-[1.7rem]
prose-img:w-full '
dangerouslySetInnerHTML={{ __html: content }}
/>
</div>
);
};
export default function Post({ post }) {
const router = useRouter();
const { title, content, coverImage, date } = post;
if (!router.isFallback && !post?.slug) {
return <ErrorPage statusCode={404} />;
}
return (
<>
{router.isFallback ? (
<h1>Loading…</h1>
) : (
<>
<article className='mb-32'>
<PostHeader
title={title}
image={coverImage}
date={date}
/>
<PostBody content={content} />
</article>
</>
)}
</>
);
}

export async function getStaticProps({ params }) {
const post = getPostBySlug(params.slug, [
"title",
"description",
"slug",
"coverImage",
"date",
"content",
]);
const content = await markdownToHtml(post.content || "");
return {
props: {
post: {
...post,
content,
},
},
};
}

export async function getStaticPaths() {
const posts = getAllPosts(["slug"]);

return {
paths: posts.map((post) => {
return {
params: {
slug: post.slug,
},
};
}),
fallback: false,
};
}
39 changes: 39 additions & 0 deletions src/pages/blog/_posts/post1-copy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: "The Power of Sharing: How Students Can Help Each Other Succeed"
description: "In the world of education, students often find themselves in a race to acquire knowledge and skills. While individual efforts are crucial, the power of sharing and helping fellow students should not be underestimated."
coverImage: "https://images.unsplash.com/photo-1531545514256-b1400bc00f31?auto=format&fit=crop&q=60&w=500&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTF8fHN0dWRlbnRzfGVufDB8fDB8fHww"
date: "2023-10-26"
author:
name: Ismail Benlaredj
picture: "https://images.unsplash.com/photo-1633332755192-727a05c4013d?auto=format&fit=crop&q=60&w=500&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8OHx8YXZhdGFyfGVufDB8fDB8fHww"
ogImage:
url: "https://images.unsplash.com/photo-1531545514256-b1400bc00f31?auto=format&fit=crop&q=60&w=500&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTF8fHN0dWRlbnRzfGVufDB8fDB8fHww"
---

In the world of education, students often find themselves in a race to acquire knowledge and skills. While individual efforts are crucial, the power of sharing and helping fellow students should not be underestimated. This cooperative approach can lead to a more supportive and successful learning environment for everyone involved.

**Fostering a Culture of Collaboration**

Education is not a solitary journey; it's a collective effort where students can benefit from one another's experiences and insights. The creation of a culture of collaboration can greatly enhance the learning experience. When students actively engage with their peers, it creates an environment where knowledge flows freely, and everyone has the opportunity to learn from one another.

**Peer Tutoring and Mentoring**

One of the most effective ways students can assist each other is through peer tutoring and mentoring. If a student excels in a particular subject, they can help their peers who may be struggling. This not only provides assistance to those in need but also reinforces the tutor's own understanding of the topic. It's a win-win situation that promotes academic growth.

**Study Groups and Knowledge Sharing**

Study groups are another excellent way for students to share and learn together. By pooling their knowledge, students can cover a broader range of topics and address challenging questions collaboratively. These groups foster discussion, debate, and the exchange of ideas, resulting in a deeper understanding of the material.

**Online Platforms and Resources**

In today's digital age, online platforms and resources have made it easier than ever for students to share their knowledge. Discussion forums, social media groups, and educational websites provide spaces for students to ask questions, share insights, and access a wealth of information. These platforms break down the barriers of geography, connecting students from all over the world.

**Building Soft Skills**

Sharing knowledge and helping others also builds essential soft skills such as communication, leadership, and teamwork. These skills are not only valuable in an academic context but are also highly sought after by employers. By engaging in collaboration, students enhance their personal and professional development.

**Conclusion**

The power of sharing among students is a force that can transform the educational landscape. By fostering a culture of collaboration, engaging in peer tutoring, forming study groups, and utilizing online resources, students can collectively enhance their learning experiences. In this supportive environment, everyone has the opportunity to succeed, grow, and thrive.

So, the next time you come across a fellow student who needs assistance or have knowledge to share, remember the tremendous impact you can make by helping each other on this incredible academic journey.
39 changes: 39 additions & 0 deletions src/pages/blog/_posts/post1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: "The Power of Sharing: How Students Can Help Each Other Succeed"
description: "In the world of education, students often find themselves in a race to acquire knowledge and skills. While individual efforts are crucial, the power of sharing and helping fellow students should not be underestimated. This cooperative approach can lead to a more supportive and successful learning environment for everyone involved.."
coverImage: "https://images.unsplash.com/photo-1531545514256-b1400bc00f31?auto=format&fit=crop&q=60&w=500&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTF8fHN0dWRlbnRzfGVufDB8fDB8fHww"
date: "2023-10-26"
author:
name: Ismail Benlaredj
picture: "https://images.unsplash.com/photo-1633332755192-727a05c4013d?auto=format&fit=crop&q=60&w=500&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8OHx8YXZhdGFyfGVufDB8fDB8fHww"
ogImage:
url: "https://images.unsplash.com/photo-1531545514256-b1400bc00f31?auto=format&fit=crop&q=60&w=500&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTF8fHN0dWRlbnRzfGVufDB8fDB8fHww"
---

In the world of education, students often find themselves in a race to acquire knowledge and skills. While individual efforts are crucial, the power of sharing and helping fellow students should not be underestimated. This cooperative approach can lead to a more supportive and successful learning environment for everyone involved.

**Fostering a Culture of Collaboration**

Education is not a solitary journey; it's a collective effort where students can benefit from one another's experiences and insights. The creation of a culture of collaboration can greatly enhance the learning experience. When students actively engage with their peers, it creates an environment where knowledge flows freely, and everyone has the opportunity to learn from one another.

**Peer Tutoring and Mentoring**

One of the most effective ways students can assist each other is through peer tutoring and mentoring. If a student excels in a particular subject, they can help their peers who may be struggling. This not only provides assistance to those in need but also reinforces the tutor's own understanding of the topic. It's a win-win situation that promotes academic growth.

**Study Groups and Knowledge Sharing**

Study groups are another excellent way for students to share and learn together. By pooling their knowledge, students can cover a broader range of topics and address challenging questions collaboratively. These groups foster discussion, debate, and the exchange of ideas, resulting in a deeper understanding of the material.

**Online Platforms and Resources**

In today's digital age, online platforms and resources have made it easier than ever for students to share their knowledge. Discussion forums, social media groups, and educational websites provide spaces for students to ask questions, share insights, and access a wealth of information. These platforms break down the barriers of geography, connecting students from all over the world.

**Building Soft Skills**

Sharing knowledge and helping others also builds essential soft skills such as communication, leadership, and teamwork. These skills are not only valuable in an academic context but are also highly sought after by employers. By engaging in collaboration, students enhance their personal and professional development.

**Conclusion**

The power of sharing among students is a force that can transform the educational landscape. By fostering a culture of collaboration, engaging in peer tutoring, forming study groups, and utilizing online resources, students can collectively enhance their learning experiences. In this supportive environment, everyone has the opportunity to succeed, grow, and thrive.

So, the next time you come across a fellow student who needs assistance or have knowledge to share, remember the tremendous impact you can make by helping each other on this incredible academic journey.
36 changes: 36 additions & 0 deletions src/pages/blog/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { getAllPosts } from "@/lib/blogApi";

import ArticleCard from "@/components/articlecard/ArticleCard";
function Blog({ allPosts }) {
return (
<>
<h1 className='my-20 text-center text-6xl font-semibold'>Blog</h1>
<div className='my-12'>
{allPosts.map((post, index) => (
<ArticleCard
key={post.slug}
title={post.title}
description={post.description}
imageUrl={post.coverImage}
articleUrl={"/blog/" + post.slug}
textOnleft={index % 2 === 0 ? true : false}
/>
))}
</div>
</>
);
}

export default Blog;

export const getStaticProps = async () => {
const allPosts = getAllPosts([
"title",
"description",
"slug",
"coverImage",
]);
return {
props: { allPosts },
};
};
2 changes: 1 addition & 1 deletion tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ module.exports = {
},
},
},
plugins: [],
plugins: [require("@tailwindcss/typography")],
};
Loading