feat: migrate changelogs

feat/collection
Arik Chakma 4 weeks ago
parent f75579806b
commit 3179c95e4e
  1. 16
      src/components/Changelog/ChangelogItem.astro
  2. 16
      src/content/changelog.ts
  3. 0
      src/content/changelogs/leaderboard-page.md
  4. 0
      src/content/changelogs/new-dashboard-page.md
  5. 2
      src/content/config.ts
  6. 51
      src/lib/changelog.ts

@ -1,37 +1,39 @@
--- ---
import type { ChangelogFileType } from '../../lib/changelog'; import type { ChangelogFileType } from '../../lib/changelog';
import { DateTime } from 'luxon'; import { DateTime } from 'luxon';
import MarkdownFile from '../MarkdownFile.astro';
interface Props { interface Props {
changelog: ChangelogFileType; changelog: ChangelogFileType;
} }
const { changelog } = Astro.props; const { changelog } = Astro.props;
const { frontmatter } = changelog; const { data: frontmatter } = changelog;
const { Content } = await changelog.render();
const formattedDate = DateTime.fromISO(frontmatter.date).toFormat( const formattedDate = DateTime.fromJSDate(frontmatter.date).toFormat(
'dd LLL, yyyy', 'dd LLL, yyyy',
); );
--- ---
<div class='relative'> <div class='relative'>
<span class='h-2 w-2 flex-shrink-0 rounded-full bg-gray-300 absolute top-2 -left-6'></span> <span
class='absolute -left-6 top-2 h-2 w-2 flex-shrink-0 rounded-full bg-gray-300'
></span>
<div class='mb-3 flex items-center gap-2'> <div class='mb-3 flex items-center gap-2'>
<span class='flex-shrink-0 text-xs tracking-wide text-gray-400'> <span class='flex-shrink-0 text-xs tracking-wide text-gray-400'>
{formattedDate} {formattedDate}
</span> </span>
<span class='truncate text-base font-medium'> <span class='truncate text-base font-medium'>
{changelog.frontmatter.title} {frontmatter.title}
</span> </span>
</div> </div>
<div class='rounded-xl border bg-white p-6'> <div class='rounded-xl border bg-white p-6'>
<div <div
class='prose prose-h2:text-lg prose-h2:font-medium prose-h2:mt-3 prose-sm prose-p:mb-0 prose-blockquote:font-normal prose-blockquote:text-gray-500 prose-ul:my-0 prose-img:mt-0 prose-img:rounded-lg [&>blockquote>p]:mt-0 prose-ul:bg-gray-100 prose-ul:rounded-lg prose-ul:px-4 prose-ul:py-4 prose-ul:pl-7 [&>ul>li]:my-0 [&>ul>li]:mb-1 [&>ul]:mt-3' class='prose prose-sm prose-h2:mt-3 prose-h2:text-lg prose-h2:font-medium prose-p:mb-0 prose-blockquote:font-normal prose-blockquote:text-gray-500 prose-ul:my-0 prose-ul:rounded-lg prose-ul:bg-gray-100 prose-ul:px-4 prose-ul:py-4 prose-ul:pl-7 prose-img:mt-0 prose-img:rounded-lg [&>blockquote>p]:mt-0 [&>ul>li]:my-0 [&>ul>li]:mb-1 [&>ul]:mt-3'
> >
<changelog.Content /> <Content />
</div> </div>
</div> </div>
</div> </div>

@ -0,0 +1,16 @@
import { defineCollection, z } from 'astro:content';
export const changelogCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
seo: z
.object({
title: z.string(),
description: z.string().optional(),
})
.optional(),
date: z.date(),
}),
});

@ -1,4 +1,5 @@
import { authorCollection } from './author'; import { authorCollection } from './author';
import { changelogCollection } from './changelog';
import { guideCollection } from './guide'; import { guideCollection } from './guide';
import { projectCollection } from './project'; import { projectCollection } from './project';
import { questionGroupCollection } from './question-group'; import { questionGroupCollection } from './question-group';
@ -10,4 +11,5 @@ export const collections = {
'question-groups': questionGroupCollection, 'question-groups': questionGroupCollection,
projects: projectCollection, projects: projectCollection,
videos: videoCollection, videos: videoCollection,
changelogs: changelogCollection,
}; };

@ -1,56 +1,15 @@
import type { MarkdownFileType } from './file'; import { getCollection, type CollectionEntry } from 'astro:content';
export interface ChangelogFrontmatter { export type ChangelogFileType = CollectionEntry<'changelogs'>;
title: string;
description: string;
seo: {
title: string;
description: string;
};
date: string;
}
export type ChangelogFileType = MarkdownFileType<ChangelogFrontmatter> & {
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 * Gets all the changelogs sorted by the publishing date
* @returns Promisifed guide files * @returns Promisifed guide files
*/ */
export async function getAllChangelogs(): Promise<ChangelogFileType[]> { export async function getAllChangelogs(): Promise<ChangelogFileType[]> {
// @ts-ignore const changelogEntries = await getCollection('changelogs');
const changelogs = import.meta.glob<ChangelogFileType>( return changelogEntries.sort(
'/src/data/changelogs/*.md', (a, b) => b.data.date.valueOf() - a.data.date.valueOf(),
{
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(),
); );
} }

Loading…
Cancel
Save