Files
portfolio/src/pages/index.astro
Nathan Cummins 027c7b2abc
All checks were successful
Build and Deploy to Web Server / deploy (push) Successful in 13m6s
More space between projects on smaller screens
2025-08-12 13:16:31 +09:30

242 lines
8.8 KiB
Plaintext

---
import { getCollection } from "astro:content";
import ProjectCard from "@/components/ProjectCard.astro";
import TrackCard from "@/components/TrackCard.astro";
import { Content } from "@assets/bios/short.mdx";
import aboutImage from "@assets/img/about.jpg";
import AwardCard from "@components/AwardCard.astro";
import ImageCarousel from "@components/ImageCarousel.astro";
import Link from "@components/Link.astro";
import Paragraph from "@components/Paragraph.astro";
import SectionTitle from "@components/SectionTitle.astro";
import person from "@data/person";
import site from "@data/site";
import MainLayout from "@layouts/MainLayout.astro";
import { Image } from "astro:assets";
import { Icon } from "astro-icon/components";
import { convertEagerImagesImportGlobToArray } from "@lib/utils";
const heroImages = import.meta.glob<{ default: ImageMetadata; eager: true }>(
"../assets/img/hero/*"
);
const heroImagesArray = await convertEagerImagesImportGlobToArray(heroImages);
const imagesForCTA = import.meta.glob<{ default: ImageMetadata; eager: true }>([
"../assets/img/hero/*",
"../assets/img/project-heros/*",
"../assets/img/projects/*"
]);
const imagesForCTAArray =
await convertEagerImagesImportGlobToArray(imagesForCTA);
const projects = (
await getCollection("projects", ({ data }) => data.frontPage)
).sort(
(a, b) => (a.data.frontPage?.order || 0) - (b.data.frontPage?.order || 1)
);
const awards = (await getCollection("awards")).sort(
(a, b) => b.data.date.valueOf() - a.data.date.valueOf()
);
const awardsDoubled = [...awards, ...awards];
const tracks = (
await getCollection("tracks", ({ data }) => data.autoQueue)
).sort(
(a, b) => (a.data.autoQueue?.order || 0) - (b.data.autoQueue?.order || 1)
);
---
<MainLayout navbarDisplay="transparent">
<div class="h-screen w-full flex-row">
<div class="absolute inset-0 h-full w-full bg-black">
<ImageCarousel
images={heroImagesArray}
className="h-full w-full"
foreground={true}
/>
</div>
<div
class="absolute inset-0 flex h-full w-full flex-col justify-center px-8 py-36 text-center"
>
<h1
class="font-header pb-8 text-5xl font-medium text-white uppercase text-shadow-lg/75 md:text-7xl lg:text-9xl"
>
{person.names.first}
{person.names.last}
</h1>
<h2
class="font-header text-2xl font-medium text-gray-300 uppercase text-shadow-lg/75 md:text-2xl lg:text-4xl"
>
{site.tagline}
</h2>
<a
href="/contact/"
class="bg-primary text-md font-header hover:text-primary repeat hover:ring-primary mx-auto mt-8 inline-block rounded px-6 py-3 font-light text-white uppercase drop-shadow-lg/75 transition hover:bg-white hover:ring-2"
>
Get in touch!
</a>
</div>
</div>
<div class="w-full">
<section id="about" class="bg-white dark:bg-gray-950">
<div class="mx-auto max-w-4xl px-8 py-16 text-justify sm:text-center">
<SectionTitle>About</SectionTitle>
<Content components={{ p: Paragraph, a: Link }} />
<Image
src={aboutImage}
alt="Nathan conducting the Woodville Concert Band"
class="mx-auto mt-8 size-96 rounded-full object-cover drop-shadow-lg/75 transition ease-in-out md:hover:scale-150 md:hover:shadow-xl/50"
transition:name="aboutImage"
/>
<span class="block w-full text-center"
><a
href="/about/"
class="bg-primary text-md font-header hover:text-primary repeat hover:ring-primary mx-auto mt-8 inline-block rounded px-6 py-3 font-light text-white uppercase drop-shadow-lg/75 transition hover:bg-white hover:ring-2"
>
Find out more
</a></span
>
</div>
</section>
<section id="cta" class="text-white">
<div class="flex h-48 w-full items-center justify-center">
<ImageCarousel
images={imagesForCTAArray}
className="absolute -z-40 h-full w-full overflow-hidden"
foreground={true}
foregroundColour="bg-primary"
foregroundOpacity="opacity-75 dark:opacity-25"
interval={1000}
transitionDuration="duration-500"
quality={5}
height={192}
shuffle={true}
/>
<a
href="/contact/"
class="text-md font-header repeat text-primary hover:bg-primary mx-auto inline-block rounded bg-white px-6 py-3 font-light uppercase drop-shadow-lg/75 transition hover:text-white hover:ring-2 hover:ring-white"
>
Get in touch!
</a>
</div>
</section>
<section id="projects" class="overflow-hidden bg-white dark:bg-gray-950">
<div class="mx-auto max-w-4xl px-8 py-16 text-center">
<SectionTitle>What I've been working on</SectionTitle>
<Paragraph>
I've recently been working on a few different projects.</Paragraph
>
<div class="space-y-16 md:space-y-8">
{
projects.map((project, index) => {
return (
<ProjectCard
project={project}
textOn={index % 2 === 0 ? "left" : "right"}
quality={60}
/>
);
})
}
</div>
<a
href="/projects/"
class="bg-primary text-md font-header hover:text-primary repeat hover:ring-primary mx-auto mt-8 inline-block rounded px-6 py-3 font-light text-white uppercase drop-shadow-lg/75 transition hover:bg-white hover:ring-2"
>
Explore more projects
</a>
</div>
</section>
<section id="listen" class="bg-primary text-white dark:bg-gray-800">
<div class="w-full overflow-hidden">
<div class="pt-16 text-center">
<SectionTitle lineColour="text-white">Listen</SectionTitle>
<Paragraph
>Click or tap on an image below to listen to the work.</Paragraph
>
<div class="flex h-fit w-full flex-wrap gap-0">
{tracks.map((track, index) => <TrackCard {track} {index} />)}
</div>
</div>
</div>
</section>
<section id="recognition" class="bg-white dark:bg-gray-950">
<div class="mx-auto max-w-4xl px-8 py-16 text-center">
<SectionTitle>Recognition</SectionTitle>
<div class="grid grid-cols-1 md:grid-cols-2">
<div
class="col-span-1 flex h-48 w-full flex-col items-center justify-center"
>
<Paragraph
>I am very grateful to have been recognised and awarded for my
work.</Paragraph
>
<a
href="/recognition/"
class="bg-primary text-md font-header hover:text-primary repeat hover:ring-primary mx-auto inline-block rounded px-6 py-3 font-light text-white uppercase drop-shadow-lg/75 transition hover:bg-white hover:ring-2"
>
Click here for more information
</a>
</div>
<div
class="md-8 col-span-1 h-48 overflow-hidden scroll-smooth p-0 md:mt-0"
>
<div
class="animate-scrolling-awards m-0 mx-auto flex max-w-3xs flex-col space-y-8 p-0"
>
{
awardsDoubled.map((award, index) => {
return <AwardCard award={award} />;
})
}
</div>
</div>
</div>
</div>
</section>
<section id="fillerUntilServicesIsComplete" class="text-white">
<div class="flex h-64 w-full items-center justify-center">
<ImageCarousel
images={imagesForCTAArray}
className="absolute -z-40 h-full w-full overflow-hidden"
foreground={true}
foregroundColour="bg-primary"
foregroundOpacity="opacity-50 dark:opacity-25"
interval={1000}
transitionDuration="duration-500"
quality={5}
height={256}
shuffle={true}
/>
</div>
</section>
<section id="contact" class="bg-white dark:bg-gray-950">
<div class="mx-auto max-w-4xl px-8 py-16 text-center">
<SectionTitle>Let's get in touch!</SectionTitle>
<div class="grid grid-cols-1 text-lg md:grid-cols-2">
<div class="col-span-1 flex flex-col items-center justify-center p-4">
<Icon name="fa7-solid:at" class="text-4xl" />
<Link href="mailto:nathan@nathancummins.com.au" className="mt-4"
>nathan@nathancummins.com.au</Link
>
</div>
<div class="col-span-1 flex flex-col items-center justify-center p-4">
<Icon name="fa7-solid:envelope" class="text-4xl" />
<Paragraph className="my-0 mt-4"
>PO Box 2112 Regency Park SA 5942</Paragraph
>
</div>
</div>
</div>
</section>
</div>
</MainLayout>