parent
989f7ad5c1
commit
fb9031e939
6 changed files with 163 additions and 1 deletions
@ -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', |
||||||
|
); |
||||||
|
--- |
||||||
|
|
||||||
|
<div class='grid gap-4 py-10 sm:grid-cols-4'> |
||||||
|
<div class='sticky top-8 col-span-1 mt-1.5 hidden self-start sm:block'> |
||||||
|
<span class='text-sm text-gray-600'>{formattedDate}</span> |
||||||
|
</div> |
||||||
|
<div class='col-span-3'> |
||||||
|
<h2 class='text-3xl font-bold text-gray-900 sm:mb-4'> |
||||||
|
{changelog.frontmatter.title} |
||||||
|
</h2> |
||||||
|
<span class='mb-6 mt-3 block text-sm text-gray-600 sm:hidden' |
||||||
|
>{formattedDate}</span |
||||||
|
> |
||||||
|
|
||||||
|
<MarkdownFile class='p-0'> |
||||||
|
<changelog.Content /> |
||||||
|
</MarkdownFile> |
||||||
|
</div> |
||||||
|
</div> |
@ -1,5 +1,16 @@ |
|||||||
|
--- |
||||||
|
interface Props { |
||||||
|
class?: string; |
||||||
|
} |
||||||
|
|
||||||
|
const { class: className } = Astro.props; |
||||||
|
--- |
||||||
|
|
||||||
<div |
<div |
||||||
class='container prose-h2:text-balance prose-h3:text-balance prose-h4:text-balance prose-h5:text-balance prose prose-xl prose-h2:mb-3 prose-h2:mt-10 prose-h2:scroll-mt-5 prose-h2:text-3xl prose-h3:mt-2 prose-h3:scroll-mt-5 prose-h5:font-medium prose-blockquote:font-normal prose-code:bg-transparent prose-img:mt-1 prose-h2:sm:scroll-mt-10 prose-h3:sm:scroll-mt-10' |
class:list={[ |
||||||
|
'container prose prose-xl prose-h2:mb-3 prose-h2:mt-10 prose-h2:scroll-mt-5 prose-h2:text-balance prose-h2:text-3xl prose-h3:mt-2 prose-h3:scroll-mt-5 prose-h3:text-balance prose-h4:text-balance prose-h5:text-balance prose-h5:font-medium prose-blockquote:font-normal prose-code:bg-transparent prose-img:mt-1 prose-h2:sm:scroll-mt-10 prose-h3:sm:scroll-mt-10', |
||||||
|
className, |
||||||
|
]} |
||||||
> |
> |
||||||
<slot /> |
<slot /> |
||||||
</div> |
</div> |
||||||
|
@ -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<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 |
||||||
|
* @returns Promisifed guide files |
||||||
|
*/ |
||||||
|
export async function getAllChangelogs(): Promise<ChangelogFileType[]> { |
||||||
|
// @ts-ignore
|
||||||
|
const changelogs = import.meta.glob<ChangelogFileType>( |
||||||
|
'/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<ChangelogFileType | undefined> { |
||||||
|
const allChangelogs = await getAllChangelogs(); |
||||||
|
|
||||||
|
return allChangelogs.find((changelog) => changelog.id === id); |
||||||
|
} |
@ -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(); |
||||||
|
--- |
||||||
|
|
||||||
|
<BaseLayout |
||||||
|
title='Changelogs' |
||||||
|
description='Changelogs for the updates and changes in the website' |
||||||
|
permalink='/changelogs' |
||||||
|
> |
||||||
|
<SimplePageHeader |
||||||
|
title='Changelogs' |
||||||
|
description='Changelogs for the updates and changes in the website' |
||||||
|
/> |
||||||
|
|
||||||
|
<div class='bg-gray-100 pb-14 pt-4 sm:pb-16 sm:pt-8'> |
||||||
|
<div class='container divide-y divide-gray-300'> |
||||||
|
{ |
||||||
|
allChangelogs.map((changelog) => ( |
||||||
|
<ChangelogItem changelog={changelog} /> |
||||||
|
)) |
||||||
|
} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</BaseLayout> |
Loading…
Reference in new issue