diff --git a/.astro/settings.json b/.astro/settings.json index 3c7258e30..b81828642 100644 --- a/.astro/settings.json +++ b/.astro/settings.json @@ -3,6 +3,6 @@ "enabled": false }, "_variables": { - "lastUpdateCheck": 1727087951727 + "lastUpdateCheck": 1727095669945 } } \ No newline at end of file diff --git a/package.json b/package.json index ae63dca90..9a226056d 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 ca43288d9..7f7d83e12 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 @@ -1246,6 +1252,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==} @@ -2174,6 +2183,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==} @@ -4238,6 +4251,8 @@ snapshots: '@types/js-cookie@3.0.6': {} + '@types/luxon@3.4.2': {} + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 @@ -5237,6 +5252,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..3d793724a --- /dev/null +++ b/src/components/Changelog/ChangelogItem.astro @@ -0,0 +1,37 @@ +--- +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 LLL, yyyy', +); +--- + +
+ + +
+ + {formattedDate} + + + {changelog.frontmatter.title} + +
+ +
+
+ +
+
+
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/data/changelogs/leaderboard-page.md b/src/data/changelogs/leaderboard-page.md new file mode 100644 index 000000000..d3fae968f --- /dev/null +++ b/src/data/changelogs/leaderboard-page.md @@ -0,0 +1,25 @@ +--- +title: 'New Dashboard, Leaderboards and Projects' +description: 'New leaderboard page showing the most active users' +seo: + title: 'Leaderboard Page - roadmap.sh' + description: '' +date: 2024-09-13 +--- + +TL;DR: new dashboard, leaderboard page and projects page. + +- New dashboard for logged-in users +- New leaderboard page +- Projects page listing all projects +- Ability to stop a started project +- Frontend and backend content improvements +- Bug fixes + +![Leaderboard Page](https://assets.roadmap.sh/guest/personal-dashboard.png) + +We just launched a dedicated dashboard for logged-in users to showing progress, projects, bookmarks and more. You can still access the old homepage by visiting [this page](https://roadmap.sh/home). + +We also launched a new [leaderboard page](/leaderboard) showing the most active users, users who completed most projects and more. + +There is also a [new projects page](/projects) where you can see all the projects you have been working on. You can also now stop a started project. \ No newline at end of file diff --git a/src/data/changelogs/new-dashboard-page.md b/src/data/changelogs/new-dashboard-page.md new file mode 100644 index 000000000..c0091731d --- /dev/null +++ b/src/data/changelogs/new-dashboard-page.md @@ -0,0 +1,12 @@ +--- +title: 'New Dashboard Page' +description: 'We have added a new dashboard page to help you track your progress' +seo: + title: 'New Dashboard Page - roadmap.sh' + description: 'We have added a new dashboard page to help you track your progress' +date: 2024-09-12 +--- + +We have revamped the dashboard page for logged-in users. The new dashboard page will help you track your progress and see your overall progress in a single view. We have also added a new progress bar to help you visualize your progress. + +If you want to access the guest homepage, you check check it out [here](/home). 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/changelog.astro b/src/pages/changelog.astro new file mode 100644 index 000000000..d7baac44a --- /dev/null +++ b/src/pages/changelog.astro @@ -0,0 +1,39 @@ +--- +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(); +--- + + +
+
+
+

Changelog

+

Here is everything we have been shipping recently

+
+
+ +
+
+
+
+ + { + allChangelogs.map((changelog) => ( + + )) + } +
+
+
+