From fb9031e939df98c1b55bab369520bd5455913a41 Mon Sep 17 00:00:00 2001 From: Arik Chakma Date: Fri, 13 Sep 2024 00:32:19 +0600 Subject: [PATCH] feat: implement leaderboard page --- package.json | 2 + pnpm-lock.yaml | 17 +++++ src/components/Changelog/ChangelogItem.astro | 34 ++++++++++ src/components/MarkdownFile.astro | 13 +++- src/lib/changelog.ts | 69 ++++++++++++++++++++ src/pages/changelogs.astro | 29 ++++++++ 6 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 src/components/Changelog/ChangelogItem.astro create mode 100644 src/lib/changelog.ts create mode 100644 src/pages/changelogs.astro diff --git a/package.json b/package.json index 253d1dea9..a8aba0dff 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "jose": "^5.6.3", "js-cookie": "^3.0.5", "lucide-react": "^0.419.0", + "luxon": "^3.5.0", "nanoid": "^5.0.7", "nanostores": "^0.10.3", "node-html-parser": "^6.1.13", @@ -80,6 +81,7 @@ "@tailwindcss/typography": "^0.5.13", "@types/dom-to-image": "^2.6.7", "@types/js-cookie": "^3.0.6", + "@types/luxon": "^3.4.2", "@types/prismjs": "^1.26.4", "@types/react-calendar-heatmap": "^1.6.7", "@types/turndown": "^5.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aad3451e7..d7422f259 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -71,6 +71,9 @@ importers: lucide-react: specifier: ^0.419.0 version: 0.419.0(react@18.3.1) + luxon: + specifier: ^3.5.0 + version: 3.5.0 nanoid: specifier: ^5.0.7 version: 5.0.7 @@ -156,6 +159,9 @@ importers: '@types/js-cookie': specifier: ^3.0.6 version: 3.0.6 + '@types/luxon': + specifier: ^3.4.2 + version: 3.4.2 '@types/prismjs': specifier: ^1.26.4 version: 1.26.4 @@ -1114,6 +1120,9 @@ packages: '@types/js-cookie@3.0.6': resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==} + '@types/luxon@3.4.2': + resolution: {integrity: sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -2055,6 +2064,10 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + luxon@3.5.0: + resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==} + engines: {node: '>=12'} + magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} @@ -4070,6 +4083,8 @@ snapshots: '@types/js-cookie@3.0.6': {} + '@types/luxon@3.4.2': {} + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.2 @@ -5074,6 +5089,8 @@ snapshots: dependencies: react: 18.3.1 + luxon@3.5.0: {} + magic-string@0.30.11: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 diff --git a/src/components/Changelog/ChangelogItem.astro b/src/components/Changelog/ChangelogItem.astro new file mode 100644 index 000000000..7f51dd921 --- /dev/null +++ b/src/components/Changelog/ChangelogItem.astro @@ -0,0 +1,34 @@ +--- +import type { ChangelogFileType } from '../../lib/changelog'; +import { DateTime } from 'luxon'; +import MarkdownFile from '../MarkdownFile.astro'; + +interface Props { + changelog: ChangelogFileType; +} + +const { changelog } = Astro.props; +const { frontmatter } = changelog; + +const formattedDate = DateTime.fromISO(frontmatter.date).toFormat( + 'dd LLLL, yyyy', +); +--- + +
+ +
+

+ {changelog.frontmatter.title} +

+ {formattedDate} + + + + +
+
diff --git a/src/components/MarkdownFile.astro b/src/components/MarkdownFile.astro index 4d8bae22b..b12c5cd1a 100644 --- a/src/components/MarkdownFile.astro +++ b/src/components/MarkdownFile.astro @@ -1,5 +1,16 @@ +--- +interface Props { + class?: string; +} + +const { class: className } = Astro.props; +--- +
diff --git a/src/lib/changelog.ts b/src/lib/changelog.ts new file mode 100644 index 000000000..038a03b6f --- /dev/null +++ b/src/lib/changelog.ts @@ -0,0 +1,69 @@ +import type { MarkdownFileType } from './file'; + +export interface ChangelogFrontmatter { + title: string; + description: string; + seo: { + title: string; + description: string; + }; + date: string; +} + +export type ChangelogFileType = MarkdownFileType & { + id: string; +}; + +/** + * Generates id from the given changelog file + * @param filePath Markdown file path + * + * @returns unique changelog identifier + */ +function changelogPathToId(filePath: string): string { + const fileName = filePath.split('/').pop() || ''; + + return fileName.replace('.md', ''); +} + +/** + * Gets all the changelogs sorted by the publishing date + * @returns Promisifed guide files + */ +export async function getAllChangelogs(): Promise { + // @ts-ignore + const changelogs = import.meta.glob( + '/src/data/changelogs/*.md', + { + eager: true, + }, + ); + + const changelogFiles = Object.values(changelogs) as ChangelogFileType[]; + const enrichedChangelogs: ChangelogFileType[] = changelogFiles.map( + (changelogFile) => ({ + ...changelogFile, + id: changelogPathToId(changelogFile.file), + }), + ); + + return enrichedChangelogs.sort( + (a, b) => + new Date(b.frontmatter.date).valueOf() - + new Date(a.frontmatter.date).valueOf(), + ); +} + +/** + * Gets the changelog by the given id + * @param id Changelog identifier + * @returns Promisified changelog file + */ + +export async function getChangelogById( + id: string, +): Promise { + const allChangelogs = await getAllChangelogs(); + + return allChangelogs.find((changelog) => changelog.id === id); +} diff --git a/src/pages/changelogs.astro b/src/pages/changelogs.astro new file mode 100644 index 000000000..c71c5decd --- /dev/null +++ b/src/pages/changelogs.astro @@ -0,0 +1,29 @@ +--- +import SimplePageHeader from '../components/SimplePageHeader.astro'; +import BaseLayout from '../layouts/BaseLayout.astro'; +import { getAllChangelogs } from '../lib/changelog'; +import ChangelogItem from '../components/Changelog/ChangelogItem.astro'; + +const allChangelogs = await getAllChangelogs(); +--- + + + + +
+
+ { + allChangelogs.map((changelog) => ( + + )) + } +
+
+