Added phtography section

This commit is contained in:
Anton Pogrebnjak
2026-04-06 22:56:12 +02:00
parent d03478f81a
commit da9d256b71
15 changed files with 266 additions and 13 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
public/images/photos/*.jpg filter=lfs diff=lfs merge=lfs -text

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

View File

@@ -0,0 +1,49 @@
---
import type { Photo } from '../models/Photo.ts';
const photos: Photo[] = Astro.props.photos;
const collection: string = Astro.props.collection;
const color = Astro.props.color || 'var(--text)';
---
<section>
{
photos.map((photo) => (
<a href={"photography/" + photo.id}>
<img src={photo.src} />
</a>
))
}
</section>
<style define:vars={{ color }}>
section {
width: 100%;
overflow: hidden;
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 2px;
}
a {
overflow: hidden;
min-height: 200px;
max-height: 12.5rem;
min-width: 200px;
max-width: 12.5rem;
flex: 1;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 0;
transition: transform .2s;
}
img:hover {
transform: scale(1.2);
cursor: pointer;
}
</style>

View File

@@ -10,9 +10,9 @@ import Socials from "./Socials.astro";
<img src="/logo.svg" alt="ಠ_ಠ" />
</a>
<div class="internal-links">
<HeaderLink href="/">Home</HeaderLink>
<HeaderLink href="/projects">Projects</HeaderLink>
<HeaderLink href="/blog">Blog</HeaderLink>
<HeaderLink href="/photography">Photography</HeaderLink>
<HeaderLink href="/blog">Blog</HeaderLink>
</div>
<Socials />
</nav>

View File

@@ -1,4 +1,4 @@
import { glob } from 'astro/loaders';
import { glob, file } from 'astro/loaders';
import { defineCollection, z } from 'astro:content';
const bachelor = defineCollection({
@@ -28,6 +28,22 @@ const blog = defineCollection({
updatedDate: z.coerce.date().optional(),
heroImage: z.string().optional(),
}),
}
);
const photography = defineCollection({
// Load Markdown and MDX files in the `src/content/projects/` directory.
loader: file(
'./src/content/photography/index.json'
),
// Type-check frontmatter using a schema
schema: z.object({
title: z.string(),
description: z.string(),
src: z.string(),
// Transform string to Date object
pubDate: z.coerce.date(),
}),
});
const projects = defineCollection({
@@ -46,4 +62,4 @@ const projects = defineCollection({
}),
});
export const collections = { bachelor, blog, projects };
export const collections = { bachelor, blog, photography, projects };

View File

@@ -0,0 +1,44 @@
[
{
"id": "DSC05932",
"src": "DSC05932.jpg",
"title": "DSC05932",
"pubDate": "2026-04-06",
"description": ""
},
{
"id": "DSC06124",
"src": "DSC06124.jpg",
"title": "DSC06124",
"pubDate": "2026-04-06",
"description": ""
},
{
"id": "DSC06196",
"src": "DSC06196.jpg",
"title": "DSC06196",
"pubDate": "2026-04-06",
"description": ""
},
{
"id": "UKN_Topo_01",
"src": "UKN_Topo_01.jpg",
"title": "UKN_Topo_01",
"pubDate": "2026-04-06",
"description": ""
},
{
"id": "UKN_Topo_02",
"src": "UKN_Topo_02.jpg",
"title": "UKN_Topo_02",
"pubDate": "2026-04-06",
"description": ""
},
{
"id": "UKN_Topo_03",
"src": "UKN_Topo_03.jpg",
"title": "UKN_Topo_03",
"pubDate": "2026-04-06",
"description": ""
}
]

View File

@@ -0,0 +1,103 @@
---
import type { CollectionEntry } from "astro:content";
import BaseHead from "../components/BaseHead.astro";
import Header from "../components/Header.astro";
import Main from "../components/Main.astro";
import Footer from "../components/Footer.astro";
import FormattedDate from "../components/FormattedDate.astro";
type Props = CollectionEntry<"photography">["data"];
const { title, description, pubDate, src } = Astro.props;
---
<html lang="en">
<head>
<BaseHead title={title} description={description} image={src} />
<style>
article {
width: 100%;
}
h1::after {
content: "";
display: block;
/* width: 100%; */
height: 2px;
background-color: var(--primary);
margin: 0.5rem auto;
}
h2::after {
content: "";
display: block;
/* width: 100%; */
height: 2px;
background-color: var(--primary);
margin: 0.5rem auto;
}
.hero-image {
width: 100%;
}
.hero-image img {
display: block;
margin: 0 auto;
border-radius: 12px;
}
.prose {
width: 720px;
max-width: 100%;
margin: auto;
padding: 1em;
color: var(--text);
}
.title {
margin-bottom: 1em;
padding: 1em 0;
text-align: center;
line-height: 1;
}
.title h1 {
margin: 0 0 0.5em 0;
}
.date {
margin-bottom: 0.5em;
color: var(--text);
}
</style>
</head>
<body>
<Header />
<Main>
<article>
<div class="hero-image">
<img
width={1020}
height={510}
src={src}
alt=""
/>
</div>
<div class="prose">
<div class="title">
<div class="date">
<FormattedDate date={pubDate} />
</div>
<h1>{title}</h1>
</div>
<p>
{description}
</p>
</div>
</article>
</Main>
<Footer />
</body>
</html>

View File

@@ -28,8 +28,9 @@ const posts: Post[] = (await getCollection("projects"))
</h2>
<h4 class="buttons">
<a href="/blog">Blog</a>
<a href="/projects">Projects</a>
<a href="/photography">Photography</a>
<a href="/blog">Blog</a>
<a href="/about">About</a>
</h4>
</section>
@@ -108,14 +109,6 @@ const posts: Post[] = (await getCollection("projects"))
section {
padding: 1rem;
}
#welcome h1 {
font-size: 1.5rem;
}
#welcome h2 {
font-size: 1rem;
}
}
</style>
</html>

View File

@@ -0,0 +1,18 @@
---
import { getCollection } from 'astro:content';
import { render } from 'astro:content';
import GalleryPhoto from '../../layouts/GalleryPhoto.astro';
import { convertCollectionPhoto, convertPhoto, type Photo } from '../../models/Photo';
export async function getStaticPaths() {
const photos: Photo[] = (await getCollection('photography')).map(convertPhoto);
return photos.map((photo) => ({
params: { slug: photo.id },
props: photo,
}));
}
type Props = Photo;
const photo: Photo = Astro.props;
---
<GalleryPhoto {...photo} />

View File

@@ -0,0 +1,29 @@
---
import BaseHead from '../../components/BaseHead.astro';
import Header from '../../components/Header.astro';
import Main from '../../components/Main.astro';
import Footer from '../../components/Footer.astro';
import { SITE_TITLE, SITE_DESCRIPTION } from '../../consts';
import { getCollection } from 'astro:content';
import Gallery from '../../components/Gallery.astro';
import { convertPhoto } from '../../models/Photo';
const photos: Photo[] = (await getCollection('photography')).map(convertPhoto).sort((a, b) => b.pubDate.valueOf() - a.pubDate.valueOf());
---
<!doctype html>
<html lang="en">
<head>
<BaseHead title={SITE_TITLE} description={SITE_DESCRIPTION} />
</head>
<body>
<Header />
<Main>
{photos.length === 0 ? (
<h1 style="opacity: .5; user-select: none;">No photos yet &#128539;</h1>
) : ( <Gallery photos={photos} /> )}
</Main>
<Footer />
</body>
</html>