Changelog (#399)

* feat: add changelog feature and update site navigation

- Introduced a new Changelog page with pagination and detailed entry views.
- Added components for displaying changelog entries, pagination, and entry details.
- Updated site navigation to include a link to the new Changelog page.
- Enhanced localization for changelog-related texts in marketing.json.

* refactor: enhance Changelog page layout and entry display

- Increased the number of changelog entries displayed per page from 2 to 20 for better visibility.
- Improved the layout of the Changelog page by adjusting the container styles and removing unnecessary divs.
- Updated the ChangelogEntry component to enhance the visual presentation of entries, including a new date badge with an icon.
- Refined the CSS styles for Markdoc headings to improve typography and spacing.

* refactor: enhance Changelog page functionality and layout

- Increased the number of changelog entries displayed per page from 20 to 50 for improved user experience.
- Updated ChangelogEntry component to make the highlight prop optional and refined the layout for better visual clarity.
- Adjusted styles in ChangelogHeader and ChangelogPagination components for a more cohesive design.
- Removed unnecessary order fields from changelog markdown files to streamline content management.

* feat: enhance Changelog entry navigation and data loading

- Refactored ChangelogEntry page to load previous and next entries for improved navigation.
- Introduced ChangelogNavigation component to facilitate navigation between changelog entries.
- Updated ChangelogDetail component to display navigation links and entry details.
- Enhanced data fetching logic to retrieve all changelog entries alongside the current entry.
- Added localization keys for navigation text in marketing.json.

* Update package dependencies and enhance documentation layout

- Upgraded various packages including @turbo/gen and turbo to version 2.6.0, and react-hook-form to version 7.66.0.
- Updated lucide-react to version 0.552.0 across multiple packages.
- Refactored documentation layout components for improved styling and structure.
- Removed deprecated loading components and adjusted navigation elements for better user experience.
- Added placeholder notes in changelog entries for clarity.
This commit is contained in:
Giancarlo Buomprisco
2025-11-01 11:59:52 +07:00
committed by GitHub
parent a920dea2b3
commit 116d41a284
73 changed files with 5638 additions and 558 deletions

View File

@@ -29,10 +29,10 @@
"@supabase/supabase-js": "2.78.0",
"@types/react": "catalog:",
"date-fns": "^4.1.0",
"lucide-react": "^0.548.0",
"lucide-react": "^0.552.0",
"next": "catalog:",
"react": "19.2.0",
"react-hook-form": "^7.65.0",
"react-hook-form": "^7.66.0",
"react-i18next": "^16.2.3",
"zod": "^3.25.74"
},

View File

@@ -290,7 +290,7 @@ class KeystaticClient implements CmsClient {
publishedAt: publishedAt.toISOString(),
content: html as string,
image: item.entry.image ?? undefined,
status: item.entry.status,
status: item.entry.status as Cms.ContentItemStatus,
collapsible: item.entry.collapsible,
collapsed: item.entry.collapsed,
categories:
@@ -344,7 +344,7 @@ class KeystaticClient implements CmsClient {
publishedAt: publishedAt.toISOString(),
content: html as string,
image: item.entry.image ?? undefined,
status: item.entry.status,
status: item.entry.status as Cms.ContentItemStatus,
categories:
(item.entry.categories ?? []).map((item) => {
return {

View File

@@ -43,6 +43,10 @@ export type DocumentationEntryProps = Entry<
(typeof keyStaticConfig)['collections']['documentation']
>;
export type ChangelogEntryProps = Entry<
(typeof keyStaticConfig)['collections']['changelog']
>;
function createKeyStaticConfig(path = '') {
if (path && !path.endsWith('/')) {
path += '/';
@@ -62,6 +66,19 @@ function createKeyStaticConfig(path = '') {
}
function getKeystaticCollections(path: string) {
const statusOptions = [
{ label: 'Draft', value: 'draft' },
{ label: 'Published', value: 'published' },
{ label: 'Review', value: 'review' },
{ label: 'Pending', value: 'pending' },
];
const imageField = fields.image({
label: 'Image',
directory: 'public/site/images',
publicPath: '/site/images',
});
return {
posts: collection({
label: 'Posts',
@@ -74,11 +91,7 @@ function getKeystaticCollections(path: string) {
label: 'Label',
validation: { isRequired: false },
}),
image: fields.image({
label: 'Image',
directory: 'public/site/images',
publicPath: '/site/images',
}),
image: imageField,
categories: fields.array(fields.text({ label: 'Category' })),
tags: fields.array(fields.text({ label: 'Tag' })),
description: fields.text({ label: 'Description' }),
@@ -93,12 +106,7 @@ function getKeystaticCollections(path: string) {
status: fields.select({
defaultValue: 'draft',
label: 'Status',
options: [
{ label: 'Draft', value: 'draft' },
{ label: 'Published', value: 'published' },
{ label: 'Review', value: 'review' },
{ label: 'Pending', value: 'pending' },
],
options: statusOptions,
}),
},
}),
@@ -114,11 +122,7 @@ function getKeystaticCollections(path: string) {
validation: { isRequired: false },
}),
content: getContentField(),
image: fields.image({
label: 'Image',
directory: 'public/site/images',
publicPath: '/site/images',
}),
image: imageField,
description: fields.text({ label: 'Description' }),
publishedAt: fields.date({ label: 'Published At' }),
order: fields.number({ label: 'Order' }),
@@ -132,12 +136,7 @@ function getKeystaticCollections(path: string) {
status: fields.select({
defaultValue: 'draft',
label: 'Status',
options: [
{ label: 'Draft', value: 'draft' },
{ label: 'Published', value: 'published' },
{ label: 'Review', value: 'review' },
{ label: 'Pending', value: 'pending' },
],
options: statusOptions,
}),
collapsible: fields.checkbox({
label: 'Collapsible',
@@ -149,5 +148,34 @@ function getKeystaticCollections(path: string) {
}),
},
}),
changelog: collection({
label: 'Changelog',
slugField: 'title',
path: `${path}changelog/*`,
format: { contentField: 'content' },
schema: {
title: fields.slug({ name: { label: 'Title' } }),
description: fields.text({
label: 'Description',
multiline: true,
}),
image: imageField,
categories: fields.array(fields.text({ label: 'Category' })),
tags: fields.array(fields.text({ label: 'Tag' })),
publishedAt: fields.date({ label: 'Published At' }),
parent: fields.relationship({
label: 'Parent',
collection: 'changelog',
}),
language: fields.text({ label: 'Language' }),
order: fields.number({ label: 'Order' }),
content: getContentField(),
status: fields.select({
defaultValue: 'draft',
label: 'Status',
options: statusOptions,
}),
},
}),
};
}

View File

@@ -38,12 +38,12 @@
"@tanstack/react-query": "5.90.5",
"@types/react": "catalog:",
"@types/react-dom": "19.2.2",
"lucide-react": "^0.548.0",
"lucide-react": "^0.552.0",
"next": "catalog:",
"next-themes": "0.4.6",
"react": "19.2.0",
"react-dom": "19.2.0",
"react-hook-form": "^7.65.0",
"react-hook-form": "^7.66.0",
"react-i18next": "^16.2.3",
"zod": "^3.25.74"
},

View File

@@ -24,11 +24,11 @@
"@tanstack/react-query": "5.90.5",
"@tanstack/react-table": "^8.21.3",
"@types/react": "catalog:",
"lucide-react": "^0.548.0",
"lucide-react": "^0.552.0",
"next": "catalog:",
"react": "19.2.0",
"react-dom": "19.2.0",
"react-hook-form": "^7.65.0",
"react-hook-form": "^7.66.0",
"zod": "^3.25.74"
},
"exports": {

View File

@@ -32,9 +32,9 @@
"@supabase/supabase-js": "2.78.0",
"@tanstack/react-query": "5.90.5",
"@types/react": "catalog:",
"lucide-react": "^0.548.0",
"lucide-react": "^0.552.0",
"next": "catalog:",
"react-hook-form": "^7.65.0",
"react-hook-form": "^7.66.0",
"react-i18next": "^16.2.3",
"sonner": "^2.0.7",
"zod": "^3.25.74"

View File

@@ -22,7 +22,7 @@
"@supabase/supabase-js": "2.78.0",
"@tanstack/react-query": "5.90.5",
"@types/react": "catalog:",
"lucide-react": "^0.548.0",
"lucide-react": "^0.552.0",
"react": "19.2.0",
"react-dom": "19.2.0",
"react-i18next": "^16.2.3"

View File

@@ -43,11 +43,11 @@
"@types/react-dom": "19.2.2",
"class-variance-authority": "^0.7.1",
"date-fns": "^4.1.0",
"lucide-react": "^0.548.0",
"lucide-react": "^0.552.0",
"next": "catalog:",
"react": "19.2.0",
"react-dom": "19.2.0",
"react-hook-form": "^7.65.0",
"react-hook-form": "^7.66.0",
"react-i18next": "^16.2.3",
"zod": "^3.25.74"
},

View File

@@ -30,7 +30,7 @@
"@types/react-dom": "19.2.2",
"react": "19.2.0",
"react-dom": "19.2.0",
"react-hook-form": "^7.65.0",
"react-hook-form": "^7.66.0",
"zod": "^3.25.74"
},
"typesVersions": {

View File

@@ -14,7 +14,7 @@
"clsx": "^2.1.1",
"cmdk": "1.1.1",
"input-otp": "1.4.2",
"lucide-react": "^0.548.0",
"lucide-react": "^0.552.0",
"radix-ui": "1.4.3",
"react-dropzone": "^14.3.8",
"react-top-loading-bar": "3.0.2",
@@ -32,12 +32,12 @@
"@types/react-dom": "19.2.2",
"class-variance-authority": "^0.7.1",
"date-fns": "^4.1.0",
"eslint": "^9.38.0",
"eslint": "^9.39.0",
"next": "catalog:",
"next-themes": "0.4.6",
"prettier": "^3.6.2",
"react-day-picker": "^9.11.1",
"react-hook-form": "^7.65.0",
"react-hook-form": "^7.66.0",
"react-i18next": "^16.2.3",
"sonner": "^2.0.7",
"tailwindcss": "4.1.16",