added projects to landing page
continuous-integration/drone/pr Build is failing Details
continuous-integration/drone/push Build is passing Details

pull/1/head
Guus van Meerveld 2 months ago
parent 87cc453451
commit a16fca25d9

@ -9,6 +9,26 @@
"linkedin": "https://linkedin.com/in/guus-van-meerveld-038357210"
}
},
"projects": [
{
"name": "Dust-Mail",
"avatarUrl": "https://avatars.githubusercontent.com/u/130915639?s=200&v=4",
"description": "Dust-Mail is a free and open source project that aims to replace all desktop and web email clients by providing a fast and simple experience.",
"url": "https://github.com/Dust-Mail/"
},
{
"name": "Argo-Client",
"avatarUrl": "https://avatars.githubusercontent.com/u/71986232?s=200&v=4",
"description": "Argo is a modern client for Magister 6 that is available for Android and IOS.",
"url": "https://argo-magister.nl"
},
{
"name": "MaterialTube",
"avatarUrl": "https://raw.githubusercontent.com/Guusvanmeerveld/MaterialTube/master/src/svg/logo.svg",
"description": "MaterialTube is a beautiful and elegant web client for Invidious servers, built using Next.js and MUI.",
"url": "https://github.com/Guusvanmeerveld/MaterialTube"
}
],
"footer": {
"columns": [
{

@ -67,6 +67,7 @@ export const Header: Component<{ data: HeaderProps; avatar: string }> = ({
as={Link}
className="text-2xl mr-4"
color="primary"
variant="shadow"
isIconOnly
aria-label={social.name}
>

@ -0,0 +1,55 @@
"use client";
import { Card, CardHeader, CardBody, CardFooter } from "@nextui-org/card";
import { Divider } from "@nextui-org/divider";
import { Image } from "@nextui-org/image";
import { Link } from "@nextui-org/link";
import { Spacer } from "@nextui-org/spacer";
import { Component } from "@typings/component";
import ProjectProps from "@models/project";
export const Projects: Component<{ data: ProjectProps[] }> = ({ data }) => {
return (
<>
<div className="container mx-auto">
<h1 className="text-4xl text-center mb-8">Projects</h1>
<div className="grid gap-4 grid-cols-1 lg:grid-cols-2 xl:grid-cols-3">
{data.map((project) => {
const url = new URL(project.url);
return (
<Card key={project.name}>
<CardHeader className="flex gap-3">
<Image
alt={`${project.name} logo`}
height={40}
radius="sm"
src={project.avatarUrl}
width={40}
/>
<div className="flex flex-col">
<p className="text-md">{project.name}</p>
<p className="text-small text-default-500">{url.host}</p>
</div>
</CardHeader>
<Divider />
<CardBody>
<p>{project.description}</p>
</CardBody>
<Divider />
<CardFooter>
<Link isExternal showAnchorIcon href={project.url}>
Visit the project.
</Link>
</CardFooter>
</Card>
);
})}
</div>
</div>
<Spacer y={24} />
</>
);
};

@ -1,5 +1,6 @@
import { Footer } from "../Footer";
import { Header } from "./Header";
import { Projects } from "./Projects";
import { dataDirLocation } from "@utils/constants";
import { readAvatarFile, readLandingJson } from "@utils/landing";
@ -12,6 +13,7 @@ export default async function Page() {
return (
<>
<Header data={landing.header} avatar={avatar} />
<Projects data={landing.projects} />
<Footer data={landing.footer} />
</>
);

@ -1,6 +1,7 @@
"use client";
import { Divider, Link } from "@nextui-org/react";
import { Divider } from "@nextui-org/divider";
import { Link } from "@nextui-org/link";
import { Component } from "@typings/component";
import { ThemeSwitcher } from "./ThemeSwitcher";

@ -2,9 +2,11 @@ import z from "zod";
import { FooterPropsModel } from "./footer";
import { HeaderPropsModel } from "./header";
import { ProjectPropsModel } from "./project";
export const LandingModel = z.object({
header: HeaderPropsModel,
projects: ProjectPropsModel.array(),
footer: FooterPropsModel
});

@ -0,0 +1,12 @@
import z from "zod";
export const ProjectPropsModel = z.object({
name: z.string(),
avatarUrl: z.string().url(),
description: z.string(),
url: z.string().url()
});
export type ProjectProps = z.infer<typeof ProjectPropsModel>;
export default ProjectProps;
Loading…
Cancel
Save