initial commit

This commit is contained in:
2025-08-29 12:03:04 +10:00
commit 672960840e
50 changed files with 10067 additions and 0 deletions

34
src/app/(app)/layout.tsx Normal file
View File

@@ -0,0 +1,34 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "../globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Liam Pietralla",
description: "Enthusiastic Software Developer & DevOps Engineer",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}

40
src/app/(app)/page.tsx Normal file
View File

@@ -0,0 +1,40 @@
export const dynamic = 'force-dynamic'
import IndexLink from "@/components/home-page-link";
import Rule from "@/components/horizontal-rule";
import { getHome } from "@/services/home-service";
import { Mail } from "lucide-react";
import Image from "next/image";
const IndexPage = async () => {
const home = await getHome();
return (
<div className="flex flex-col gap-4 justify-center items-center h-screen">
<Image className="rounded-full" src="/images/liam_pietralla.jpg" width={200} height={200} alt="Liam Pietralla" />
<h1 className="text-5xl font-bold">Liam Pietralla</h1>
<h2 className="text-xl">Enthusiastic Software Developer & DevOps Engineer</h2>
<Rule className="w-[300px]" />
<div className="flex flex-row gap-4">
{home.mainLinks.map(link => (
<IndexLink key={link.id} {...link} />
))}
</div>
<div className="flex flex-row gap-4">
{home.popoverLinks.map(link => (
<IndexLink key={link.id} {...link} isPopover={true} />
))}
</div>
<Rule className="w-[300px]" />
<a href="mailto:me@liampietralla.com" className="group leading-relaxed">
<span className="flex flex-row gap-2">
<Mail />
me@liampietralla.com
</span>
<span className="block max-w-0 group-hover:max-w-full transition-all duration-500 h-0.5 bg-white"></span>
</a>
</div>
);
}
export default IndexPage;

View File

@@ -0,0 +1,35 @@
export const dynamic = 'force-dynamic'
import ProjectCard from "@/components/project-card";
import Rule from "@/components/horizontal-rule";
import { getProjects } from "@/services/projects-service";
import Image from "next/image";
import Link from "next/link";
import { Fragment } from "react";
const ProjectsPage = async () => {
const projects = await getProjects();
return (
<div className="flex flex-col gap-4 justify-center items-center my-15">
<div className="flex flex-row items-center gap-2 my-2">
<Image src="/images/liam_pietralla.jpg" width={50} height={50} alt="Liam Pietralla" className="rounded-full" />
<Link href="/" className="group leading-relaxed font-semi-bold">
Liam Pietralla
<span className="block max-w-0 group-hover:max-w-full transition-all duration-500 h-0.5 bg-white"></span>
</Link>
</div>
<h1 className="text-5xl font-bold">Projects</h1>
<h2>A collection of interesting projects that I am working on currently or have worked on in the past.</h2>
<div className="flex flex-col gap-4">
{projects.docs.map((project, index) => (
<Fragment key={index}>
<ProjectCard {...project} />
{index < projects.docs.length - 1 && <Rule />}
</Fragment>
))}
</div>
</div>
)
}
export default ProjectsPage;

View File

@@ -0,0 +1,24 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import type { Metadata } from 'next'
import config from '@payload-config'
import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'
import { importMap } from '../importMap'
type Args = {
params: Promise<{
segments: string[]
}>
searchParams: Promise<{
[key: string]: string | string[]
}>
}
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
generatePageMetadata({ config, params, searchParams })
const NotFound = ({ params, searchParams }: Args) =>
NotFoundPage({ config, params, searchParams, importMap })
export default NotFound

View File

@@ -0,0 +1,24 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import type { Metadata } from 'next'
import config from '@payload-config'
import { RootPage, generatePageMetadata } from '@payloadcms/next/views'
import { importMap } from '../importMap'
type Args = {
params: Promise<{
segments: string[]
}>
searchParams: Promise<{
[key: string]: string | string[]
}>
}
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
generatePageMetadata({ config, params, searchParams })
const Page = ({ params, searchParams }: Args) =>
RootPage({ config, params, searchParams, importMap })
export default Page

View File

@@ -0,0 +1,5 @@
export const importMap = {
}

View File

@@ -0,0 +1,43 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import config from '@payload-config'
import '@payloadcms/next/css'
import {
REST_DELETE,
REST_GET,
REST_OPTIONS,
REST_PATCH,
REST_POST,
REST_PUT,
} from '@payloadcms/next/routes'
type NextCtx = { params: Promise<{ slug?: string[] }> }
type PayloadCtx = { params: Promise<{ slug: string[] }> }
const coerceCtx = (ctx: NextCtx): PayloadCtx => ({
params: ctx.params.then(p => ({ slug: p?.slug ?? [] })),
})
export function GET(req: Request, ctx: NextCtx) {
return REST_GET(config)(req, coerceCtx(ctx))
}
export function POST(req: Request, ctx: NextCtx) {
return REST_POST(config)(req, coerceCtx(ctx))
}
export function DELETE(req: Request, ctx: NextCtx) {
return REST_DELETE(config)(req, coerceCtx(ctx))
}
export function PATCH(req: Request, ctx: NextCtx) {
return REST_PATCH(config)(req, coerceCtx(ctx))
}
export function PUT(req: Request, ctx: NextCtx) {
return REST_PUT(config)(req, coerceCtx(ctx))
}
export function OPTIONS(req: Request, ctx: NextCtx) {
return REST_OPTIONS(config)(req, coerceCtx(ctx))
}

View File

@@ -0,0 +1,9 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import config from '@payload-config'
import '@payloadcms/next/css'
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
export async function GET(req: Request): Promise<Response> {
return GRAPHQL_PLAYGROUND_GET(config)(req)
}

View File

@@ -0,0 +1,19 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import config from '@payload-config'
import { GRAPHQL_POST, REST_OPTIONS } from '@payloadcms/next/routes'
type NextCtx = { params: Promise<{ slug?: string[] }> }
type PayloadCtx = { params: Promise<{ slug: string[] }> }
const coerceCtx = (ctx: NextCtx): PayloadCtx => ({
params: ctx.params.then(p => ({ slug: p?.slug ?? [] })),
})
export function POST(req: Request) {
return GRAPHQL_POST(config)(req)
}
export function OPTIONS(req: Request, ctx: NextCtx) {
return REST_OPTIONS(config)(req, coerceCtx(ctx))
}

View File

View File

@@ -0,0 +1,31 @@
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
import config from '@payload-config'
import '@payloadcms/next/css'
import type { ServerFunctionClient } from 'payload'
import { handleServerFunctions, RootLayout } from '@payloadcms/next/layouts'
import React from 'react'
import { importMap } from './admin/importMap.js'
import './custom.scss'
type Args = {
children: React.ReactNode
}
const serverFunction: ServerFunctionClient = async function (args) {
'use server'
return handleServerFunctions({
...args,
config,
importMap,
})
}
const Layout = ({ children }: Args) => (
<RootLayout config={config} importMap={importMap} serverFunction={serverFunction}>
{children}
</RootLayout>
)
export default Layout

View File

@@ -0,0 +1,13 @@
export async function GET() {
const json = require("../../../../package.json");
const response = {
"status": "Healthy",
"version": json.version
}
return new Response(JSON.stringify(response), {
status: 200,
headers: {
"Content-Type": "application/json"
}
});
}

BIN
src/app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

19
src/app/globals.css Normal file
View File

@@ -0,0 +1,19 @@
@import "tailwindcss";
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}