From 6a70d8d901b8a5b5bc3ec3f9f6407e9881bc8d2f Mon Sep 17 00:00:00 2001 From: krckyboy Date: Sun, 18 Feb 2024 21:06:05 +0100 Subject: [PATCH 1/3] #24 Adding the part for adding query string by clicking on a category and also removing it by clicking on the active category in /blog. Slight refactors regarding margin styles and also moved categories into its own component. --- next/src/app/about/styles.module.scss | 2 +- .../blog/[slug]/(blog-header)/BlogHeader.tsx | 9 ++---- .../[slug]/(blog-header)/styles.module.scss | 4 --- next/src/app/blog/page.tsx | 15 ++++++---- next/src/app/blog/styles.module.scss | 1 - next/src/components/blog-post-item/types.ts | 24 +--------------- next/src/components/categories/Categories.tsx | 28 +++++++++++++++++++ .../components/categories/CategoryLink.tsx | 22 +++++++++++++++ .../components/categories/styles.module.scss | 18 ++++++++++++ next/src/components/categories/types.ts | 22 +++++++++++++++ next/src/scripts/fetch.ts | 3 +- next/src/styles/global.module.scss | 10 ------- 12 files changed, 105 insertions(+), 53 deletions(-) create mode 100644 next/src/components/categories/Categories.tsx create mode 100644 next/src/components/categories/CategoryLink.tsx create mode 100644 next/src/components/categories/styles.module.scss create mode 100644 next/src/components/categories/types.ts diff --git a/next/src/app/about/styles.module.scss b/next/src/app/about/styles.module.scss index 9ab44bc..79e557b 100644 --- a/next/src/app/about/styles.module.scss +++ b/next/src/app/about/styles.module.scss @@ -20,6 +20,6 @@ } .mainContent { - margin-top: 3rem; + margin-top: 2rem; } } diff --git a/next/src/app/blog/[slug]/(blog-header)/BlogHeader.tsx b/next/src/app/blog/[slug]/(blog-header)/BlogHeader.tsx index c7823ab..4a0ea1a 100644 --- a/next/src/app/blog/[slug]/(blog-header)/BlogHeader.tsx +++ b/next/src/app/blog/[slug]/(blog-header)/BlogHeader.tsx @@ -2,6 +2,7 @@ import React, { FunctionComponent } from 'react'; import gStyles from '@/styles/global.module.scss'; import styles from './styles.module.scss'; import { Post } from '@/components/blog-post-item/types'; +import Categories from '@/components/categories/Categories'; interface Props { post: Post; @@ -13,13 +14,7 @@ const BlogHeader: FunctionComponent = ({ post }) => { return (

{post.attributes.title}

- {Boolean(categories?.length) && categories && ( -
    - {categories.map((category) => ( -
  • #{category.attributes.name}
  • - ))} -
- )} +
); }; diff --git a/next/src/app/blog/[slug]/(blog-header)/styles.module.scss b/next/src/app/blog/[slug]/(blog-header)/styles.module.scss index dfda350..3c8aab5 100644 --- a/next/src/app/blog/[slug]/(blog-header)/styles.module.scss +++ b/next/src/app/blog/[slug]/(blog-header)/styles.module.scss @@ -1,7 +1,3 @@ .heading { text-transform: initial; -} - -.categories { - margin-bottom: 2rem; } \ No newline at end of file diff --git a/next/src/app/blog/page.tsx b/next/src/app/blog/page.tsx index e04a310..4650333 100644 --- a/next/src/app/blog/page.tsx +++ b/next/src/app/blog/page.tsx @@ -4,8 +4,15 @@ import styles from './styles.module.scss'; import BlogPostItem from '@/components/blog-post-item/BlogPostItem'; import React from 'react'; import { db } from '@/scripts/fetch'; +import Categories from '@/components/categories/Categories'; -const Page: NextPage = async () => { +interface Props { + searchParams: { + category?: string; + }; +} + +const Page: NextPage = async ({ searchParams: { category } }) => { const posts = await db.getPosts(); const categories = await db.getCategories(); @@ -13,11 +20,7 @@ const Page: NextPage = async () => {

Blog

-
    - {categories.data.map((category) => ( -
  • #{category.attributes.name}
  • - ))} -
+
{posts.data.map((post) => )}
diff --git a/next/src/app/blog/styles.module.scss b/next/src/app/blog/styles.module.scss index 9bf494e..6223f4c 100644 --- a/next/src/app/blog/styles.module.scss +++ b/next/src/app/blog/styles.module.scss @@ -1,6 +1,5 @@ @import '@/styles/vars'; .blogs { - margin-top: 3rem; gap: 3rem; } \ No newline at end of file diff --git a/next/src/components/blog-post-item/types.ts b/next/src/components/blog-post-item/types.ts index 3261287..fb42a5a 100644 --- a/next/src/components/blog-post-item/types.ts +++ b/next/src/components/blog-post-item/types.ts @@ -1,14 +1,4 @@ -interface Category { - id: number; - attributes: { - name: string; - color: string; - background: string; - createdAt: string, - updatedAt: string, - publishedAt: string, - }; -} +import { Category } from '@/components/categories/types'; export interface Post { id: number, @@ -35,16 +25,4 @@ export interface PostsFetchResponse { total: number } } -} - -export interface CategoriesFetchResponse { - data: Category[], - meta: { - pagination: { - page: number, - pageSize: number, - pageCount: number, - total: number - } - } } \ No newline at end of file diff --git a/next/src/components/categories/Categories.tsx b/next/src/components/categories/Categories.tsx new file mode 100644 index 0000000..678bb42 --- /dev/null +++ b/next/src/components/categories/Categories.tsx @@ -0,0 +1,28 @@ +import React, { FunctionComponent } from 'react'; +import styles from './styles.module.scss'; +import { Category } from '@/components/categories/types'; +import Link from 'next/link'; +import CategoryLink from '@/components/categories/CategoryLink'; + +interface Props { + categories: Category[] | undefined; + activeCategory?: Category['attributes']['name']; +} + +const Categories: FunctionComponent = ({ categories, activeCategory }) => { + if (!categories || !categories.length) { + return null; + } + + return ( +
    + {categories.map((category) => ( +
  • + +
  • + ))} +
+ ); +}; + +export default Categories; \ No newline at end of file diff --git a/next/src/components/categories/CategoryLink.tsx b/next/src/components/categories/CategoryLink.tsx new file mode 100644 index 0000000..e604177 --- /dev/null +++ b/next/src/components/categories/CategoryLink.tsx @@ -0,0 +1,22 @@ +import Link from 'next/link'; +import React, { FunctionComponent } from 'react'; +import styles from '@/components/categories/styles.module.scss'; +import { Category } from '@/components/categories/types'; + +interface Props { + name: string; + activeCategory?: Category['attributes']['name']; +} + +const CategoryLink: FunctionComponent = ({ activeCategory, name }) => { + const isActiveCategory = name === activeCategory; + + const setActiveCategory = isActiveCategory ? styles.active : ''; + const setHref = isActiveCategory ? '/blog' : `/blog?category=${name}`; + + return ( + #{name} + ); +}; + +export default CategoryLink; \ No newline at end of file diff --git a/next/src/components/categories/styles.module.scss b/next/src/components/categories/styles.module.scss new file mode 100644 index 0000000..702dbf0 --- /dev/null +++ b/next/src/components/categories/styles.module.scss @@ -0,0 +1,18 @@ +@import '@/styles/vars'; + +.categories { + margin-bottom: 3rem; + justify-content: flex-start; + display: flex; + gap: .5rem; + + li { + a { + color: darken($color-text, 40%); + + &.active { + color: $color-accent; + } + } + } +} \ No newline at end of file diff --git a/next/src/components/categories/types.ts b/next/src/components/categories/types.ts new file mode 100644 index 0000000..ea2616f --- /dev/null +++ b/next/src/components/categories/types.ts @@ -0,0 +1,22 @@ +export interface Category { + id: number; + attributes: { + name: string; + color: string; + background: string; + createdAt: string, + updatedAt: string, + publishedAt: string, + }; +} +export interface CategoriesFetchResponse { + data: Category[], + meta: { + pagination: { + page: number, + pageSize: number, + pageCount: number, + total: number + } + } +} \ No newline at end of file diff --git a/next/src/scripts/fetch.ts b/next/src/scripts/fetch.ts index 823c32b..76985c6 100644 --- a/next/src/scripts/fetch.ts +++ b/next/src/scripts/fetch.ts @@ -1,5 +1,6 @@ -import type { CategoriesFetchResponse, PostsFetchResponse } from '@/components/blog-post-item/types'; import qs from 'qs'; +import type { PostsFetchResponse } from '@/components/blog-post-item/types'; +import { CategoriesFetchResponse } from '@/components/categories/types'; export const fetchWrapper = async (url: string | URL) => { try { diff --git a/next/src/styles/global.module.scss b/next/src/styles/global.module.scss index 94b1f13..396fbbd 100644 --- a/next/src/styles/global.module.scss +++ b/next/src/styles/global.module.scss @@ -57,14 +57,4 @@ .tagsMini { @extend .tags; font-size: clamp(1rem, 1.1vw, 1.4rem); -} - -.categories { - justify-content: flex-start; - display: flex; - gap: .5rem; - - li { - color: darken($color-text, 40%); - } } \ No newline at end of file From 5f9a692397144565a2e3d1e7e67aa5a730aa6bcb Mon Sep 17 00:00:00 2001 From: krckyboy Date: Sun, 18 Feb 2024 21:11:35 +0100 Subject: [PATCH 2/3] #24 Moving things around to make it more maintainable. --- next/src/components/categories/Categories.tsx | 3 +-- .../categories/{ => category-link}/CategoryLink.tsx | 4 ++-- .../categories/category-link/styles.module.scss | 9 +++++++++ next/src/components/categories/styles.module.scss | 10 ---------- 4 files changed, 12 insertions(+), 14 deletions(-) rename next/src/components/categories/{ => category-link}/CategoryLink.tsx (80%) create mode 100644 next/src/components/categories/category-link/styles.module.scss diff --git a/next/src/components/categories/Categories.tsx b/next/src/components/categories/Categories.tsx index 678bb42..23810a8 100644 --- a/next/src/components/categories/Categories.tsx +++ b/next/src/components/categories/Categories.tsx @@ -1,8 +1,7 @@ import React, { FunctionComponent } from 'react'; import styles from './styles.module.scss'; import { Category } from '@/components/categories/types'; -import Link from 'next/link'; -import CategoryLink from '@/components/categories/CategoryLink'; +import CategoryLink from './category-link/CategoryLink'; interface Props { categories: Category[] | undefined; diff --git a/next/src/components/categories/CategoryLink.tsx b/next/src/components/categories/category-link/CategoryLink.tsx similarity index 80% rename from next/src/components/categories/CategoryLink.tsx rename to next/src/components/categories/category-link/CategoryLink.tsx index e604177..18d09bd 100644 --- a/next/src/components/categories/CategoryLink.tsx +++ b/next/src/components/categories/category-link/CategoryLink.tsx @@ -1,6 +1,6 @@ import Link from 'next/link'; import React, { FunctionComponent } from 'react'; -import styles from '@/components/categories/styles.module.scss'; +import styles from './styles.module.scss'; import { Category } from '@/components/categories/types'; interface Props { @@ -15,7 +15,7 @@ const CategoryLink: FunctionComponent = ({ activeCategory, name }) => { const setHref = isActiveCategory ? '/blog' : `/blog?category=${name}`; return ( - #{name} + #{name} ); }; diff --git a/next/src/components/categories/category-link/styles.module.scss b/next/src/components/categories/category-link/styles.module.scss new file mode 100644 index 0000000..8329331 --- /dev/null +++ b/next/src/components/categories/category-link/styles.module.scss @@ -0,0 +1,9 @@ +@import '@/styles/vars'; + +.link { + color: darken($color-text, 40%); + + &.active { + color: $color-accent; + } +} \ No newline at end of file diff --git a/next/src/components/categories/styles.module.scss b/next/src/components/categories/styles.module.scss index 702dbf0..e150921 100644 --- a/next/src/components/categories/styles.module.scss +++ b/next/src/components/categories/styles.module.scss @@ -5,14 +5,4 @@ justify-content: flex-start; display: flex; gap: .5rem; - - li { - a { - color: darken($color-text, 40%); - - &.active { - color: $color-accent; - } - } - } } \ No newline at end of file From baac646e94899850a697cb0491e6499ccf3fa7c7 Mon Sep 17 00:00:00 2001 From: krckyboy Date: Sun, 18 Feb 2024 21:36:52 +0100 Subject: [PATCH 3/3] #24 Added proper logic for showing all posts or filtered by category. --- next/src/app/blog/page.tsx | 2 +- next/src/scripts/fetch.ts | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/next/src/app/blog/page.tsx b/next/src/app/blog/page.tsx index 4650333..bb103b5 100644 --- a/next/src/app/blog/page.tsx +++ b/next/src/app/blog/page.tsx @@ -13,7 +13,7 @@ interface Props { } const Page: NextPage = async ({ searchParams: { category } }) => { - const posts = await db.getPosts(); + const posts = category ? await db.getPostsByCategory(category) : await db.getPosts(); const categories = await db.getCategories(); return ( diff --git a/next/src/scripts/fetch.ts b/next/src/scripts/fetch.ts index 76985c6..72113e1 100644 --- a/next/src/scripts/fetch.ts +++ b/next/src/scripts/fetch.ts @@ -36,6 +36,25 @@ export const db = { const queryString = qs.stringify(queryParams); return await fetchWrapper(`/posts?${queryString}`); }, + getPostsByCategory: async (category: string) => { + const queryParams = { + sort: ['publishedAt:desc'], + filters: { + categories: { + name: { + $eq: category + } + } + }, + pagination: { + pageSize: 10, + page: 1 + } + }; + + const queryString = qs.stringify(queryParams); + return await fetchWrapper(`/posts?${queryString}`); + }, getPostBySlug: async (slug: string) => { const queryParams = { filters: {