From 273c6904401efc4e1aac2a1c1fe6d81276dec738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateus=20Felipe=20Gon=C3=A7alves?= Date: Mon, 18 Dec 2023 22:58:43 -0300 Subject: [PATCH] feat(ui): add blog statistics --- .../cards/most-used-category.tsx | 72 +++++++++++++++ .../writing-dashboard/cards/posts.tsx | 14 +++ .../writing-dashboard/cards/tag-cloud.tsx | 92 +++++++++++++++++++ .../writing-dashboard/cards/tils.tsx | 14 +++ .../components/writing-dashboard/index.tsx | 21 +++++ src/app/about/statistics/page.tsx | 14 ++- 6 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 src/app/about/statistics/components/writing-dashboard/cards/most-used-category.tsx create mode 100644 src/app/about/statistics/components/writing-dashboard/cards/posts.tsx create mode 100644 src/app/about/statistics/components/writing-dashboard/cards/tag-cloud.tsx create mode 100644 src/app/about/statistics/components/writing-dashboard/cards/tils.tsx create mode 100644 src/app/about/statistics/components/writing-dashboard/index.tsx diff --git a/src/app/about/statistics/components/writing-dashboard/cards/most-used-category.tsx b/src/app/about/statistics/components/writing-dashboard/cards/most-used-category.tsx new file mode 100644 index 00000000..94f0c06a --- /dev/null +++ b/src/app/about/statistics/components/writing-dashboard/cards/most-used-category.tsx @@ -0,0 +1,72 @@ +import { + Icon as PhosphorIcon, + FolderOpen, + TextAlignLeft, + CompassTool, + NoteBlank, + ListBullets +} from '@/shared/wrappers/phosphor-icons' +import { allPosts } from 'contentlayer/generated' + +type RowProps = { + Icon: PhosphorIcon + title: string + quantity: number +} +const Row = ({ Icon, quantity, title }: RowProps) => ( +
+
+ + {title} +
+ {quantity} +
+) + +function getQuantity(category: string) { + return allPosts.filter(post => post.category === category).length +} + +export async function MostUsedCategories() { + const categories = [ + { + title: 'How To', + icon: CompassTool, + number: getQuantity('How To') + }, + { + title: 'Article', + icon: TextAlignLeft, + number: getQuantity('Article') + }, + { + title: 'List', + icon: ListBullets, + number: getQuantity('List') + }, + { + title: 'Notes', + icon: NoteBlank, + number: getQuantity('Notes') + } + ].sort((a, b) => b.number - a.number) + + return ( +
+ + Most Used Categories + + +
+ {categories.map(category => ( + + ))} +
+
+ ) +} diff --git a/src/app/about/statistics/components/writing-dashboard/cards/posts.tsx b/src/app/about/statistics/components/writing-dashboard/cards/posts.tsx new file mode 100644 index 00000000..9a99ff2f --- /dev/null +++ b/src/app/about/statistics/components/writing-dashboard/cards/posts.tsx @@ -0,0 +1,14 @@ +import { allPosts } from 'contentlayer/generated' +import { Article } from '@/shared/wrappers/phosphor-icons' + +export async function Posts() { + return ( +
+ + Posts +
+ +
{allPosts.length}
+
+ ) +} diff --git a/src/app/about/statistics/components/writing-dashboard/cards/tag-cloud.tsx b/src/app/about/statistics/components/writing-dashboard/cards/tag-cloud.tsx new file mode 100644 index 00000000..3615a5e7 --- /dev/null +++ b/src/app/about/statistics/components/writing-dashboard/cards/tag-cloud.tsx @@ -0,0 +1,92 @@ +'use client' + +import ReactWordcloud, { Word, Options, defaultOptions } from 'react-wordcloud' +import { Tag } from '@/shared/wrappers/phosphor-icons' +import { getTagsAndNumberOfPosts } from '@/shared/lib/tags' + +export async function TagCloud() { + // const words: Word[] = [ + // { + // text: 'mateus', + // value: 10 + // }, + // { + // text: 'rust', + // value: 10 + // }, + // { + // text: 'deno', + // value: 6 + // }, + // { + // text: 'bun', + // value: 6 + // }, + // { + // text: 'node', + // value: 6 + // }, + // { + // text: 'next.js', + // value: 6 + // }, + // { + // text: 'felipe', + // value: 4 + // }, + // { + // text: 'svelte', + // value: 4 + // }, + // { + // text: 'vue', + // value: 4 + // }, + // { + // text: 'nest.js', + // value: 2 + // }, + // { + // text: 'python', + // value: 2 + // } + // ] + + const words: Word[] = getTagsAndNumberOfPosts().map(value => ({ + text: value.tag, + value: value.numberOfPosts + })) + + return ( +
+ + Most Used Tags + + +
+
+ +
+
+ +
+
+
+ ) +} diff --git a/src/app/about/statistics/components/writing-dashboard/cards/tils.tsx b/src/app/about/statistics/components/writing-dashboard/cards/tils.tsx new file mode 100644 index 00000000..80f6cf42 --- /dev/null +++ b/src/app/about/statistics/components/writing-dashboard/cards/tils.tsx @@ -0,0 +1,14 @@ +import { allTILs } from 'contentlayer/generated' +import { Notebook } from '@/shared/wrappers/phosphor-icons' + +export async function TILs() { + return ( +
+ + TILs + + +
{allTILs.length}
+
+ ) +} diff --git a/src/app/about/statistics/components/writing-dashboard/index.tsx b/src/app/about/statistics/components/writing-dashboard/index.tsx new file mode 100644 index 00000000..574f2ff3 --- /dev/null +++ b/src/app/about/statistics/components/writing-dashboard/index.tsx @@ -0,0 +1,21 @@ +import { MostUsedCategories } from './cards/most-used-category' +import { Posts } from './cards/posts' +import { TagCloud } from './cards/tag-cloud' +import { TILs } from './cards/tils' + +export function WritingDashboard() { + return ( +
+ + + +
+ +
+ +
+ +
+
+ ) +} diff --git a/src/app/about/statistics/page.tsx b/src/app/about/statistics/page.tsx index b5c66bb8..588b4d2b 100644 --- a/src/app/about/statistics/page.tsx +++ b/src/app/about/statistics/page.tsx @@ -1,9 +1,14 @@ import { Metadata } from 'next' -import { GithubLogo, SpotifyLogo } from '@/shared/wrappers/phosphor-icons' +import { + GithubLogo, + PencilLine, + SpotifyLogo +} from '@/shared/wrappers/phosphor-icons' import { Title } from '@/shared/components/title' import { GithubDashboard } from './components/github-dashboard' import { SpotifyDashboard } from './components/spotify-dashboard' +import { WritingDashboard } from './components/writing-dashboard' import { RenderDate } from './components/date' export const metadata: Metadata = { @@ -21,6 +26,13 @@ export default function Page() { return (
} /> + <div className="space-y-5"> + <div className="flex w-full items-center justify-center gap-2 text-3xl font-semibold text-[#333] dark:text-[#f5f5f5] md:justify-start"> + <h2>Writing</h2> + <PencilLine weight="duotone" /> + </div> + <WritingDashboard /> + </div> <div className="space-y-5"> <div className="flex w-full items-center justify-center gap-2 text-3xl font-semibold text-[#333] dark:text-[#f5f5f5] md:justify-start"> <h2>Github</h2>