very basic header for landing page
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
parent
7c458c179f
commit
ca9737ff0d
@ -1,2 +1,2 @@
|
||||
DATABASE_URL=postgresql://portfolio:portfolio@localhost:5432/portfolio?schema=public
|
||||
LANDING_JSON_LOCATION=./landing.json
|
||||
DATA_DIR=./data
|
After Width: | Height: | Size: 31 KiB |
@ -0,0 +1,71 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@nextui-org/button";
|
||||
import { Image } from "@nextui-org/image";
|
||||
import { Spacer } from "@nextui-org/react";
|
||||
import { Tooltip } from "@nextui-org/tooltip";
|
||||
import { Component } from "@typings/component";
|
||||
import Link from "next/link";
|
||||
|
||||
import { useMemo } from "react";
|
||||
import { FiGithub, FiMail, FiLinkedin } from "react-icons/fi";
|
||||
|
||||
import Owner from "@models/owner";
|
||||
|
||||
export const Header: Component<{ owner: Owner }> = ({ owner }) => {
|
||||
const socials = useMemo(
|
||||
() => [
|
||||
{
|
||||
link: `mailto:${owner.contact.email}`,
|
||||
name: "Email address",
|
||||
icon: <FiMail />
|
||||
},
|
||||
{
|
||||
link: owner.contact.git,
|
||||
name: "Github",
|
||||
icon: <FiGithub />
|
||||
},
|
||||
{
|
||||
link: owner.contact.linkedin,
|
||||
name: "LinkedIn",
|
||||
icon: <FiLinkedin />
|
||||
}
|
||||
],
|
||||
[owner.contact]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="container min-h-screen">
|
||||
<div>
|
||||
{owner.avatar !== undefined && (
|
||||
<Image
|
||||
src={owner.avatar}
|
||||
width={300}
|
||||
alt={`A picture of ${owner.fullName}`}
|
||||
/>
|
||||
)}
|
||||
|
||||
<h1 className="text-4xl">{owner.fullName}</h1>
|
||||
<Spacer y={4} />
|
||||
|
||||
<h2 className="text-2xl">{owner.description}</h2>
|
||||
<Spacer y={4} />
|
||||
|
||||
{socials.map((social) => (
|
||||
<Link href={social.link}>
|
||||
<Tooltip content={social.name}>
|
||||
<Button
|
||||
className="text-2xl mr-4"
|
||||
color="primary"
|
||||
isIconOnly
|
||||
aria-label={social.name}
|
||||
>
|
||||
{social.icon}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,15 +1,23 @@
|
||||
import { Header } from "./Header";
|
||||
|
||||
import Landing from "@models/landing";
|
||||
|
||||
import { dataDirLocation } from "@utils/constants";
|
||||
import { readLandingJson } from "@utils/landing";
|
||||
|
||||
const getLanding = async (): Promise<Landing> => {
|
||||
return await readLandingJson();
|
||||
// Any error will get handled by the `error.tsx` file.
|
||||
return await readLandingJson(dataDirLocation);
|
||||
};
|
||||
|
||||
export default async function Page() {
|
||||
const landing = await getLanding();
|
||||
|
||||
return <div>{/* <Button color="primary">Click me</Button> */}</div>;
|
||||
return (
|
||||
<>
|
||||
<Header owner={landing.owner} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export const revalidate = 3600;
|
||||
|
@ -0,0 +1,3 @@
|
||||
import { FC, PropsWithChildren } from "react";
|
||||
|
||||
export type Component<P> = FC<PropsWithChildren<P>>;
|
@ -0,0 +1,6 @@
|
||||
import { Component } from "./component";
|
||||
|
||||
export type ErrorPage = Component<{
|
||||
error: Error & { digest?: string };
|
||||
reset: () => void;
|
||||
}>;
|
@ -1,2 +1,3 @@
|
||||
export const landingJsonLocation =
|
||||
process.env.LANDING_JSON_LOCATION ?? "/app/landing.json";
|
||||
import path from "path";
|
||||
|
||||
export const dataDirLocation = process.env.DATA_DIR ?? "/app/data";
|
||||
|
Loading…
Reference in new issue