chore: add gray-matter dependency for markdown frontmatter parsing

This commit is contained in:
2025-10-17 16:56:52 +02:00
parent 7514df43f4
commit d76ebc305e
37 changed files with 697 additions and 208 deletions

View File

@@ -0,0 +1,90 @@
import { promises as fs } from 'fs';
import path from 'path';
import Image from 'next/image';
import matter from 'gray-matter';
interface Person {
name: string;
excerpt: string;
title: string;
imageUrl: string;
}
async function getPeople(): Promise<Person[]> {
const peopleDirectory = path.join(process.cwd(), 'public/images/people');
try {
const peopleFolders = await fs.readdir(peopleDirectory, { withFileTypes: true });
const people = await Promise.all(
peopleFolders
.filter(dirent => dirent.isDirectory())
.map(async (dirent) => {
const personDir = path.join(peopleDirectory, dirent.name);
const files = await fs.readdir(personDir);
const markdownFile = files.find(file => file.endsWith('.md') || file.endsWith('.mdx'));
if (!markdownFile) {
return null;
}
const markdownFilePath = path.join(personDir, markdownFile);
const fileContents = await fs.readFile(markdownFilePath, 'utf8');
const { data } = matter(fileContents);
if (!data.name || !data.title || !data.image) {
return null;
}
const imageUrl = `/images/people/${dirent.name}/${data.image.replace('./', '')}`;
return {
name: data.name,
excerpt: data.excerpt || '',
title: data.title,
imageUrl,
};
})
);
return people.filter((p): p is Person => p !== null);
} catch (error) {
console.error('Error reading people directory:', error);
return [];
}
}
export default async function PeoplePage() {
const people = await getPeople();
return (
<div className=" py-24 sm:py-32">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-2xl lg:mx-0">
<h2 className="text-4xl font-semibold tracking-tight text-pretty text-white sm:text-5xl">Our Team</h2>
<p className="mt-6 text-lg/8 text-gray-400">
Were a dynamic group of individuals who are passionate about what we do and dedicated to delivering the
best results for our clients.
</p>
</div>
<ul
role="list"
className="mx-auto mt-20 grid max-w-2xl grid-cols-1 gap-x-8 gap-y-14 sm:grid-cols-2 lg:mx-0 lg:max-w-none xl:grid-cols-4"
>
{people.map((person, index) => (
<li key={index}>
<Image
alt={person.name}
src={person.imageUrl}
className="aspect-square w-full rounded-2xl object-cover outline-1 -outline-offset-1 outline-white/10"
width={400}
height={400}
/>
<h3 className="mt-6 text-lg/8 font-semibold tracking-tight text-white">{person.name}</h3>
<p className="text-base/7 text-gray-300">{person.title}</p>
</li>
))}
</ul>
</div>
</div>
);
}