Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added product-updates page #7200

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions website/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ export default withGuildDocs({
eslint: {
ignoreDuringBuilds: true,
},
webpack: (config, { webpack }) => {
config.externals['node:fs'] = 'commonjs node:fs';
config.externals['node:path'] = 'commonjs node:path';

config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
};
config.plugins.push(
new webpack.NormalModuleReplacementPlugin(/^node:/, resource => {
resource.request = resource.request.replace(/^node:/, '');
}),
);

return config;
},
redirects: () =>
Object.entries({
'/api': '/docs',
Expand Down
3 changes: 2 additions & 1 deletion website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
"start": "next start"
},
"dependencies": {
"@theguild/components": "^6.5.3",
"@theguild/components": "6.5.3",
"next": "^14.1.4",
"next-sitemap": "^4.2.3",
"react": "^18.2.0",
"react-avatar": "^5.0.3",
"react-dom": "^18.2.0",
"react-icons": "^5.0.0"
},
Expand Down
14 changes: 14 additions & 0 deletions website/src/authors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
type Author = {
name: string;
link: `https://${string}`;
github?: string;
twitter?: string;
};

export const authors: Record<string, Author> = {
tuvalsimha: {
name: 'Tuval Simha',
link: 'https://twitter.com/SimhaTuval',
github: 'TuvalSimha',
},
};
72 changes: 72 additions & 0 deletions website/src/components/product-update-blog-post-header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import type { ReactElement } from 'react';
import { format } from 'date-fns';
import { Anchor } from '@theguild/components';
import { authors } from '../authors';
import { SocialAvatar } from './social-avatar';

type Meta = {
authors: string[];
date: string;
title: string;
description: string;
};

const Authors = ({ meta }: { meta: Meta }): ReactElement => {
const date = meta.date ? new Date(meta.date) : new Date();

if (meta.authors.length === 1) {
const author = authors[meta.authors[0]];
return (
<div className="my-5 flex flex-row items-center justify-center">
<Anchor href={author.link} title={author.name}>
<SocialAvatar author={author} />
</Anchor>
<div className="ml-2.5 flex flex-col">
<Anchor href={author.link} title={author.name} className="font-semibold text-[#777]">
{author.name}
</Anchor>
<time
dateTime={date.toISOString()}
title={`Posted ${format(date, 'EEEE, LLL do y')}`}
className="text-xs text-[#777]"
>
{format(date, 'EEEE, LLL do y')}
</time>
</div>
</div>
);
}
return (
<>
<time
dateTime={date.toISOString()}
title={`Posted ${format(date, 'EEEE, LLL do y')}`}
className="mt-5 block text-center text-xs text-[#777]"
>
{format(date, 'EEEE, LLL do y')}
</time>
<div className="my-5 flex flex-wrap justify-center gap-5">
{meta.authors.map(authorId => {
const author = authors[authorId];
return (
<div key={authorId}>
<Anchor href={author.link} title={author.name} className="font-semibold text-[#777]">
<SocialAvatar author={author} />
<span className="ml-2.5 text-sm">{author.name}</span>
</Anchor>
</div>
);
})}
</div>
</>
);
};

export const ProductUpdateBlogPostHeader = ({ meta }: { meta: Meta }): ReactElement => {
return (
<>
<h1>{meta.title}</h1>
<Authors meta={meta} />
</>
);
};
90 changes: 90 additions & 0 deletions website/src/components/product-updates.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import fs from 'node:fs';
import path from 'node:path';
import { ReactElement } from 'react';
import type { GetStaticProps } from 'next';
import Link from 'next/link';
import { format } from 'date-fns';
import matter from 'gray-matter';

type Changelog = {
title: string;
date: string;
description: string;
route: string;
};

function ProductUpdateTeaser(props: Changelog) {
return (
<li className="mb-10 ml-4">
<div className="absolute -left-1.5 mt-1.5 size-3 rounded-full border border-white bg-gray-200 dark:border-gray-900 dark:bg-gray-700" />
<time
className="mb-1 text-sm font-normal leading-none text-gray-400 dark:text-gray-500"
dateTime={props.date}
>
{format(new Date(props.date), 'do MMMM yyyy')}
</time>
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
<Link href={props.route}>{props.title}</Link>
</h3>
<div className="mb-4 mt-1 max-w-[600px] text-base font-normal leading-6 text-gray-500 dark:text-gray-400">
{props.description}
</div>
</li>
);
}

export const ProductUpdates = (props: { changelogs: Changelog[] }): ReactElement => {
return (
<>
<div className="pb-12">
<h1 className="!m-0 !text-left">Product Updates</h1>
<p>The most recent developments from GraphQL Mesh.</p>
</div>
<ol className="relative border-l border-gray-200 dark:border-gray-700">
{props.changelogs.map(item => (
<ProductUpdateTeaser key={item.route} {...item} />
))}
</ol>
</>
);
};

export const getStaticProps: GetStaticProps<{ ssg: { changelogs: Changelog[] } }> = async () => {
const productUpdatesDirectory = path.join(process.cwd(), 'src', 'pages', 'product-updates');
const filenames = fs.readdirSync(productUpdatesDirectory);
const changelogs: Changelog[] = [];

for (const filename of filenames) {
if (filename.endsWith('.json') || filename.endsWith('index.mdx') || filename.endsWith('.ts')) {
continue;
}

const { data } = matter(
fs.readFileSync(path.join(productUpdatesDirectory, filename), 'utf8'),
{},
);

if (data.title && data.description && data.date) {
changelogs.push({
date: data.date.toISOString(),
title: data.title,
description: data.description,
route: `/product-updates/${filename.replace(/\.mdx$/, '')}`,
});
}
}

changelogs.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());

return {
props: {
__nextra_dynamic_opts: {
title: 'Product Updates',
frontMatter: {
description: 'The most recent developments from GraphQL Mesh.',
},
},
ssg: { changelogs },
},
};
};
19 changes: 19 additions & 0 deletions website/src/components/social-avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ReactElement } from 'react';
import ReactAvatar from 'react-avatar';

export const SocialAvatar = ({
author,
}: {
author: { name: string; github?: string; twitter?: string };
}): ReactElement => {
return (
<ReactAvatar
round
githubHandle={author.github}
twitterHandle={author.twitter}
size="40"
title={author.name}
alt={author.name}
/>
);
};
10 changes: 10 additions & 0 deletions website/src/pages/_meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,14 @@ export default {
layout: 'raw',
},
},
'product-updates': {
type: 'page',
title: 'Product Updates',
theme: {
sidebar: false,
toc: true,
breadcrumb: false,
typesetting: 'article',
},
},
};
8 changes: 8 additions & 0 deletions website/src/pages/product-updates/2024-07-02-test-update.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: Test Product Update
description: Test product update description
date: 2024-07-02
authors: [tuvalsimha]
---

We are happy to announce the release of a new version of our product. This is a test update.
11 changes: 11 additions & 0 deletions website/src/pages/product-updates/_meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default {
index: {
title: 'Product Updates',
theme: {
sidebar: false,
toc: false,
breadcrumb: false,
typesetting: 'article',
},
},
};
11 changes: 11 additions & 0 deletions website/src/pages/product-updates/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useData } from '@theguild/components'
import { ProductUpdates } from '../../components/product-updates'

export { getStaticProps } from '../../components/product-updates'

export const ProductUpdatesPage = () => {
const { changelogs } = useData()
return <ProductUpdates changelogs={changelogs} />
}

<ProductUpdatesPage />
17 changes: 16 additions & 1 deletion website/theme.config.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint sort-keys: error */
import { useRouter } from 'next/router';
import { defineConfig, Giscus, PRODUCTS, useTheme } from '@theguild/components';
import { defineConfig, Giscus, PRODUCTS, useConfig, useTheme } from '@theguild/components';
import { ProductUpdateBlogPostHeader } from './src/components/product-update-blog-post-header';

export default defineConfig({
description: 'GraphQL Gateway Framework and anything-to-GraphQL',
Expand All @@ -9,6 +10,20 @@ export default defineConfig({
main: function Main({ children }) {
const { resolvedTheme } = useTheme();
const { route } = useRouter();
const config = useConfig();

if (route === '/product-updates') {
return <>{children}</>;
}

if (route.startsWith('/product-updates')) {
children = (
<>
<ProductUpdateBlogPostHeader meta={config.frontMatter as any} />
{children}
</>
);
}

const comments = route !== '/' && (
<Giscus
Expand Down
Loading
Loading