started work on page footer
continuous-integration/drone/push Build is passing Details

pull/1/head
Guus van Meerveld 9 months ago
parent 789ddcf00c
commit 946bc5f6e6

@ -1,12 +1,13 @@
{
"owner": {
"fullName": "Guus van Meerveld",
"name": "guus",
"description": "AI student at Radboud University. Creating software as a hobby.",
"contact": {
"email": "contact@guusvanmeerveld.dev",
"git": "https://github.com/Guusvanmeerveld",
"linkedin": "https://linkedin.com/in/guus-van-meerveld-038357210"
}
}
}
"header": {
"fullName": "Guus van Meerveld",
"name": "guus",
"description": "AI student at Radboud University. Creating software as a hobby.",
"contact": {
"email": "contact@guusvanmeerveld.dev",
"git": "https://github.com/Guusvanmeerveld",
"linkedin": "https://linkedin.com/in/guus-van-meerveld-038357210"
}
},
"footer": {}
}

@ -10,45 +10,45 @@ import Link from "next/link";
import { useMemo } from "react";
import { FiGithub, FiMail, FiLinkedin } from "react-icons/fi";
import Owner from "@models/owner";
import HeaderProps from "@models/header";
export const Header: Component<{ owner: Owner }> = ({ owner }) => {
export const Header: Component<{ header: HeaderProps }> = ({ header }) => {
const socials = useMemo(
() => [
{
link: `mailto:${owner.contact.email}`,
link: `mailto:${header.contact.email}`,
name: "Email address",
icon: <FiMail />
},
{
link: owner.contact.git,
link: header.contact.git,
name: "Github",
icon: <FiGithub />
},
{
link: owner.contact.linkedin,
link: header.contact.linkedin,
name: "LinkedIn",
icon: <FiLinkedin />
}
],
[owner.contact]
[header.contact]
);
return (
<div className="container min-h-screen">
<div className="container mx-auto flex items-center min-h-screen">
<div>
{owner.avatar !== undefined && (
{header.avatar !== undefined && (
<Image
src={owner.avatar}
src={header.avatar}
width={300}
alt={`A picture of ${owner.fullName}`}
alt={`A picture of ${header.fullName}`}
/>
)}
<h1 className="text-4xl">{owner.fullName}</h1>
<h1 className="text-4xl">{header.fullName}</h1>
<Spacer y={4} />
<h2 className="text-2xl">{owner.description}</h2>
<h2 className="text-2xl">{header.description}</h2>
<Spacer y={4} />
{socials.map((social) => (

@ -1,3 +1,4 @@
import { Footer } from "../Footer";
import { Header } from "./Header";
import Landing from "@models/landing";
@ -15,7 +16,8 @@ export default async function Page() {
return (
<>
<Header owner={landing.owner} />
<Header header={landing.header} />
<Footer />
</>
);
}

@ -0,0 +1,12 @@
import { Component } from "@typings/component";
export const Footer: Component = () => {
return (
<div className="container mx-auto columns-4">
<div className="w-full">hi</div>
<div className="w-full">hi</div>
<div className="w-full">hi</div>
<div className="w-full">hi</div>
</div>
);
};

@ -0,0 +1,37 @@
"use client";
import { Switch } from "@nextui-org/react";
import { Component } from "@typings/component";
import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
import { FiMoon, FiSun } from "react-icons/fi";
export const ThemeSwitcher: Component = () => {
const [mounted, setMounted] = useState(false);
const { theme, setTheme } = useTheme();
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) return null;
return (
<div>
The current theme is: {theme}
<Switch
defaultSelected
size="lg"
color="primary"
onValueChange={(value) => {
value ? setTheme("dark") : setTheme("light");
}}
startContent={<FiSun />}
endContent={<FiMoon />}
>
Dark mode
</Switch>
</div>
);
};

@ -11,13 +11,15 @@ const MainErrorPage: ErrorPage = ({ error, reset }) => {
}, [error]);
return (
<div className="container min-h-screen text-center">
<p className="text-3xl">Something went loading the page!</p>
<p className="text-xl">{error.toString()}</p>
<div className="container mx-auto flex items-center justify-center min-h-screen text-center">
<div>
<Link href="#" onClick={() => reset()}>
Try again
</Link>
<p className="text-3xl">Something went loading the page!</p>
<p className="text-xl">{error.toString()}</p>
<div>
<Link href="#" onClick={() => reset()}>
Try again
</Link>
</div>
</div>
</div>
);

@ -1,5 +1,6 @@
import { Metadata } from "next";
import { Footer } from "./Footer";
import { Providers } from "./providers";
import "@styles/global.scss";
@ -10,7 +11,7 @@ export default function RootLayout({
children: React.ReactNode;
}) {
return (
<html lang="en" className="dark">
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>

@ -1,7 +1,15 @@
"use client";
import { NextUIProvider } from "@nextui-org/react";
import { Component } from "@typings/component";
import { ThemeProvider as NextThemesProvider } from "next-themes";
export function Providers({ children }: { children: React.ReactNode }) {
return <NextUIProvider>{children}</NextUIProvider>;
}
export const Providers: Component = ({ children }) => {
return (
<NextUIProvider>
<NextThemesProvider attribute="class" defaultTheme="dark">
{children}
</NextThemesProvider>
</NextUIProvider>
);
};

@ -0,0 +1,7 @@
import z from "zod";
export const FooterPropsModel = z.object({});
export type FooterProps = z.infer<typeof FooterPropsModel>;
export default FooterProps;

@ -1,6 +1,6 @@
import z from "zod";
export const OwnerModel = z.object({
export const HeaderPropsModel = z.object({
fullName: z.string(),
name: z.string(),
avatar: z.string().optional(),
@ -12,6 +12,6 @@ export const OwnerModel = z.object({
})
});
export type Owner = z.infer<typeof OwnerModel>;
export type HeaderProps = z.infer<typeof HeaderPropsModel>;
export default Owner;
export default HeaderProps;

@ -1,9 +1,11 @@
import z from "zod";
import { OwnerModel } from "./owner";
import { FooterPropsModel } from "./footer";
import { HeaderPropsModel } from "./header";
export const LandingModel = z.object({
owner: OwnerModel
header: HeaderPropsModel,
footer: FooterPropsModel
});
export type Landing = z.infer<typeof LandingModel>;

@ -1,23 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
.container {
display: flex;
min-width: 100%;
flex-direction: column;
justify-content: center;
padding-right: 1rem;
padding-left: 1rem;
@media screen and (width >=800px) {
padding-right: 4rem;
padding-left: 4rem;
}
@media screen and (width >=1200px) {
padding-right: 16rem;
padding-left: 16rem;
}
}

@ -1,3 +1,3 @@
import { FC, PropsWithChildren } from "react";
export type Component<P> = FC<PropsWithChildren<P>>;
export type Component<P = unknown> = FC<PropsWithChildren<P>>;

@ -1,3 +1 @@
import path from "path";
export const dataDirLocation = process.env.DATA_DIR ?? "/app/data";

Loading…
Cancel
Save