Move projects to index, games from index to /vinge

Also move games, badges from config.ts and projects from project page
defintion to /src/lib/data
This commit is contained in:
Mihkel Martin Kasterpalu 2025-01-31 18:38:44 +02:00
parent 7de8638796
commit ba34242475
15 changed files with 235 additions and 217 deletions

View file

@ -1,34 +1,16 @@
import type { GamesObj, TagsObj } from './types';
export const site = {
name: 'Stuff.Kasterpalu',
name: 'Mihkel Martin Kasterpalu',
author: 'Mihkel Martin Kasterpalu',
description: 'Minimängud ja muud huvitavat.',
description: 'Portfoolio - Arendaja, Disainer, Muusik, DJ, Ettevõtja.',
image: '/web-app-manifest-512x512.png'
};
export const baseURL = 'https://stuff.kasterpalu.ee';
export const games: GamesObj = {
'/epochalypse': {
name: 'Epochalypse',
image: '',
description: 'Varsti veel üks Y2K. Kui nostalgiline!'
},
'/pakubiiti': {
name: 'Paku biiti',
image: '',
description: 'Sorteeri kolme suvalise muusika albumi pealkiri, artistid ja pilt.'
},
'': {
name: 'Rohkem mänge soon™',
image: '',
description: ''
}
export const stuffSite = {
name: 'Kasterpalu Stuff',
author: 'Mihkel Martin Kasterpalu',
description:
'Minimängud ja muud huvitavat. Kui mul tekkis lahe idee ja suutsin sellest midagi lahedat arendada siis näed seda ka siin.',
image: '/web-app-manifest-512x512.png'
};
export const badges: TagsObj = {
muusika: { name: 'Muusika', description: 'Tegelen siin muusikaga' },
veeb: { name: 'Veebileht', description: 'Disainisin/kirjutasin veebilehe' },
asutaja: { name: 'Asutaja', description: 'Olin osa selle loomisest' }
};
export const baseURL = 'https://kasterpalu.ee';

9
src/lib/data/badges.ts Normal file
View file

@ -0,0 +1,9 @@
import type { TagsObj } from '$lib/types';
const badges: TagsObj = {
muusika: { name: 'Muusika', description: 'Tegelen siin muusikaga' },
veeb: { name: 'Veebileht', description: 'Disainisin/kirjutasin veebilehe' },
asutaja: { name: 'Asutaja', description: 'Olin osa selle loomisest' }
};
export default badges;

21
src/lib/data/games.ts Normal file
View file

@ -0,0 +1,21 @@
import type { GamesObj } from '$lib/types';
const games: GamesObj = {
epochalypse: {
name: 'Epochalypse',
image: '',
description: 'Varsti veel üks Y2K. Kui nostalgiline!'
},
pakubiiti: {
name: 'Paku biiti',
image: '',
description: 'Sorteeri kolme suvalise muusika albumi pealkiri, artistid ja pilt.'
},
'': {
name: 'Rohkem mänge soon™',
image: '',
description: ''
}
};
export default games;

82
src/lib/data/projects.ts Normal file
View file

@ -0,0 +1,82 @@
import type { Project } from '$lib/types';
import badges from './badges';
import skpImg from '$lib/assets/skp.jpg?enhanced';
import dysasterImg from '$lib/assets/dysaster.jpg?enhanced';
import monospaceeImg from '$lib/assets/monospacee.jpg?enhanced';
import saueauguImg from '$lib/assets/saueaugu.jpg?enhanced';
const projects: Project[] = [
{
name: 'SUPIKÖÖGIPOSID',
image: {
src: skpImg,
credit: {
type: 'instagram',
author: 'Mimmu',
href: 'https://www.instagram.com/musamimmu/'
},
alt: 'Pilt neljaliikmeliseslt räpibändist SUPIKÖÖGIPOISID. Pilt on tehtud pilves ilmaga õues. Pildil on 4 mees valgete triiksärkide, mustade lipsude ja mustade tagidega.'
},
description: 'Räpikollektiiv. Alustasime 2019.',
link: 'https://skpoisid.bandcamp.com/',
tags: [badges['muusika']]
},
{
name: 'Dysaster Collective',
image: {
src: dysasterImg,
credit: {
type: 'instagram',
author: 'Mattias Mägi',
href: 'https://www.instagram.com/mattias.mix/'
},
alt: 'Sinakas digitaalne kollaž Dysaster Collective liigetest.'
},
description: '2022 asutatud mitmekülgne loomekollektiiv.',
link: 'https://dysaster.ee',
tags: [badges['asutaja'], badges['veeb']]
},
{
name: 'monospac.ee',
image: {
src: monospaceeImg,
credit: {
type: 'instagram',
author: 'Liisa Jõhvik',
href: 'https://www.instagram.com/liisajohvik.photo/'
},
alt: 'DJ duo monospacee nende Silent Disco setil Tartu Uus Teater saalis aastal 2024. Pilt on külje pealt, esiplaanil DJ Mimmu ja ta tagant paistab DJ Rx. Nad on valgustatud punasesega, taustal häguselt näha siniselt valgustatud kolmandat DJd.'
},
description: 'DJ duo kaasliikmega Rx.',
link: 'https://monospac.ee',
tags: [badges['muusika'], badges['veeb']]
},
{
name: 'Saueagu Teatritalu',
image: {
src: saueauguImg,
alt: 'Suvine Saueaugu teatrihoone. All paistab roheline muru ja katuse tagant paistab paari pilvega sinine taevas.'
},
description: 'Taluteater Läänemaal. Tegin veebilehe.',
link: 'https://saueaugu.ee',
tags: [badges['veeb']]
},
{
name: 'Tartu Häkkerikoda',
image: {
src: '/assets/hakkerikoda.svg',
credit: {
type: 'web',
author: 'treierxyz',
href: 'https://treier.xyz'
},
alt: 'Tartu Häkkerikoda logo'
},
description: 'Makerspace Tartus. Liige ning osa veebilehe loojatest.',
link: 'https://hakkerikoda.ee',
tags: [badges['veeb']]
}
];
export default projects;

View file

@ -1,23 +0,0 @@
<script lang="ts">
import { baseURL, site } from '$lib/config.js';
let { children, data } = $props();
const title = data?.name ? `${data.name} | ${site.name}` : site.name;
</script>
<svelte:head>
<title>{title}</title>
<meta property="og:title" content={title} />
{#if data?.description}
<meta name="description" content={data.description} />
<meta property="og:description" content={data.description} />
{/if}
{#if data?.image}
<meta property="og:image" content={baseURL + data.image} />
{/if}
</svelte:head>
{@render children()}

View file

@ -40,6 +40,9 @@
<a href="/">
<img src="/favicon.svg" alt="Mihkel Martin Kasterpalu logo" class="h-9" />
</a>
<a class="font-mono font-medium underline underline-offset-4" href="/vinge"> vinge värk </a>
<Button onclick={() => cycleTheme()} variant="ghost" size="icon" class="h-12 w-12">
{#if theme === 'dark'}
<Moon class="!h-6 !w-6" />
@ -53,7 +56,7 @@
</Button>
</header>
<div class="container relative flex flex-col items-center">
<div class="container relative mt-8 flex flex-col items-center">
{@render children()}
</div>

View file

@ -1,7 +1,35 @@
<script lang="ts">
import { site, baseURL, games } from '$lib/config';
import type { EnhancedImage, Tag } from '$lib/types';
import { site, baseURL } from '$lib/config';
import SquareArrowOutUpRight from 'lucide-svelte/icons/square-arrow-out-up-right';
import { Button } from '$lib/components/ui/button/index.js';
import Image from '$lib/components/Image.svelte';
import projects from '$lib/data/projects';
</script>
{#snippet projectCard(
name: string,
description: string,
image: EnhancedImage,
tags: Tag[],
link: string
)}
<div class="mb-16 w-80 space-y-3 md:w-64">
<Image {image} {tags} class="aspect-[4/5] object-cover" />
<div class="grid grid-cols-[1fr_auto] items-center text-sm">
<div class="mt-1 pr-4">
<h3 class="text-lg font-medium leading-none">{name}</h3>
<p class="mt-1.5 text-sm leading-5 text-muted-foreground">{description}</p>
</div>
<Button target="_blank" href={link} variant="secondary" size="icon">
<SquareArrowOutUpRight />
</Button>
</div>
</div>
{/snippet}
<svelte:head>
<title>{site.name}</title>
<meta property="og:title" content={site.name} />
@ -16,31 +44,13 @@
<h1 class="mb-1 scroll-m-20 text-5xl font-extrabold tracking-tight lg:text-6xl">
Hei! Mina olen Mihkel
</h1>
<p class="text-xl font-semibold text-muted-foreground">
Siin saidil on mu loodud minimängud ja muud huvitavat. Aitäh <a
href="https://neal.fun"
class="font-medium underline underline-offset-4">neal.fun</a
> inspo eest :]
</p>
<p class="text-xl font-semibold text-muted-foreground">
Vaata ka mu
<a href="/projektid" class="text-primary underline underline-offset-4">teisi projekte</a>.
<p class="font-sans text-base text-muted-foreground">
Peale selle toreda saidi on mul veel palju hobisid
</p>
</header>
<main class="grid w-full max-w-4xl justify-items-center gap-y-8 lg:grid-cols-2">
{#each Object.entries(games) as [href, { image, name }]}
<a
class="shadow-sharp flex aspect-[4/1] w-full max-w-sm items-center justify-center rounded-xl border-2 border-current bg-contain bg-no-repeat transition-all {href ===
''
? 'pressed pointer-events-none'
: ''}"
style="background-image: url('{image}')"
draggable="false"
{href}
>
<span class="relative block select-none rounded font-mono text-2xl font-semibold lg:text-3xl">
{name}
</span>
</a>
<main class="flex w-full flex-wrap justify-center gap-x-8">
{#each projects as { name, description, image, tags, link }}
{@render projectCard(name, description, image, tags, link)}
{/each}
</main>

View file

@ -1,139 +0,0 @@
<script lang="ts">
import type { EnhancedImage, Project, Tag } from '$lib/types';
import { site, baseURL, badges } from '$lib/config';
import SquareArrowOutUpRight from 'lucide-svelte/icons/square-arrow-out-up-right';
import { Button } from '$lib/components/ui/button/index.js';
import Image from '$lib/components/Image.svelte';
import skpImg from '$lib/assets/skp.jpg?enhanced';
import dysasterImg from '$lib/assets/dysaster.jpg?enhanced';
import monospaceeImg from '$lib/assets/monospacee.jpg?enhanced';
import saueauguImg from '$lib/assets/saueaugu.jpg?enhanced';
export const projects: Project[] = [
{
name: 'SUPIKÖÖGIPOSID',
image: {
src: skpImg,
credit: {
type: 'instagram',
author: 'Mimmu',
href: 'https://www.instagram.com/musamimmu/'
},
alt: 'Pilt neljaliikmeliseslt räpibändist SUPIKÖÖGIPOISID. Pilt on tehtud pilves ilmaga õues. Pildil on 4 mees valgete triiksärkide, mustade lipsude ja mustade tagidega.'
},
description: 'Räpikollektiiv. Alustasime 2019.',
link: 'https://skpoisid.bandcamp.com/',
tags: [badges['muusika']]
},
{
name: 'Dysaster Collective',
image: {
src: dysasterImg,
credit: {
type: 'instagram',
author: 'Mattias Mägi',
href: 'https://www.instagram.com/mattias.mix/'
},
alt: 'Sinakas digitaalne kollaž Dysaster Collective liigetest.'
},
description: '2022 asutatud mitmekülgne loomekollektiiv.',
link: 'https://dysaster.ee',
tags: [badges['asutaja'], badges['veeb']]
},
{
name: 'monospac.ee',
image: {
src: monospaceeImg,
credit: {
type: 'instagram',
author: 'Liisa Jõhvik',
href: 'https://www.instagram.com/liisajohvik.photo/'
},
alt: 'DJ duo monospacee nende Silent Disco setil Tartu Uus Teater saalis aastal 2024. Pilt on külje pealt, esiplaanil DJ Mimmu ja ta tagant paistab DJ Rx. Nad on valgustatud punasesega, taustal häguselt näha siniselt valgustatud kolmandat DJd.'
},
description: 'DJ duo kaasliikmega Rx.',
link: 'https://monospac.ee',
tags: [badges['muusika'], badges['veeb']]
},
{
name: 'Saueagu Teatritalu',
image: {
src: saueauguImg,
alt: 'Suvine Saueaugu teatrihoone. All paistab roheline muru ja katuse tagant paistab paari pilvega sinine taevas.'
},
description: 'Taluteater Läänemaal. Tegin veebilehe.',
link: 'https://saueaugu.ee',
tags: [badges['veeb']]
},
{
name: 'Tartu Häkkerikoda',
image: {
src: '/assets/hakkerikoda.svg',
credit: {
type: 'web',
author: 'treierxyz',
href: 'https://treier.xyz'
},
alt: 'Tartu Häkkerikoda logo'
},
description: 'Makerspace Tartus. Liige ning osa veebilehe loojatest.',
link: 'https://hakkerikoda.ee',
tags: [badges['veeb']]
}
];
</script>
{#snippet projectCard(
name: string,
description: string,
image: EnhancedImage,
tags: Tag[],
link: string
)}
<div class="mb-16 w-80 space-y-3 md:w-64">
<Image {image} {tags} class="aspect-[4/5] object-cover" />
<div class="grid grid-cols-[1fr_auto] items-center text-sm">
<div class="mt-2 pr-4">
<h3 class="font-medium leading-none">{name}</h3>
<p class="mt-2 text-xs leading-5 text-muted-foreground">{description}</p>
</div>
<Button target="_blank" href={link} variant="secondary" size="icon">
<SquareArrowOutUpRight />
</Button>
</div>
</div>
{/snippet}
<svelte:head>
<title>Projektid | {site.name}</title>
<meta property="og:title" content={'Projektid | ' + site.name} />
<meta
name="description"
content="Projektid millega tegelenud, asjad mida teinud - tule uudista."
/>
<meta
property="og:description"
content="Projektid millega tegelenud, asjad mida teinud - tule uudista."
/>
<meta property="og:image" content={baseURL + site.image} />
</svelte:head>
<header class="mb-24 flex flex-col items-center text-center font-title">
<h1 class="mb-1 scroll-m-20 text-5xl font-extrabold tracking-tight lg:text-6xl">
Muud projektid
</h1>
<p class="text-xl font-semibold text-muted-foreground">
Peale selle toreda saidi on mul veel palju hobisid
</p>
</header>
<main class="flex w-full max-w-4xl flex-wrap justify-center gap-x-8">
{#each projects as { name, description, image, tags, link }}
{@render projectCard(name, description, image, tags, link)}
{/each}
</main>

View file

@ -1,12 +1,15 @@
import type { LayoutServerData } from './$types';
import { games, site } from '$lib/config';
import { site } from '$lib/config';
import games from '$lib/data/games';
export const load: LayoutServerData = async ({ url }) => {
if (!url?.pathname) {
return;
}
const game = games[url.pathname];
const gameSlug = url.pathname.split('/').at(-1);
const game = games[gameSlug];
if (!game) {
return;

View file

@ -0,0 +1,21 @@
<script lang="ts">
import { baseURL, stuffSite } from '$lib/config.js';
let { children, data } = $props();
const title = data?.name ? `${data.name} | ${stuffSite.name}` : stuffSite.name;
const description = data?.description || stuffSite.description;
const ogImage = data?.image || stuffSite.image;
</script>
<svelte:head>
<title>{title}</title>
<meta property="og:title" content={title} />
<meta name="description" content={description} />
<meta property="og:description" content={description} />
<meta property="og:image" content={baseURL + ogImage} />
</svelte:head>
{@render children()}

View file

@ -0,0 +1,49 @@
<script lang="ts">
import { site, baseURL } from '$lib/config';
import games from '$lib/data/games';
let { data } = $props();
$inspect(data);
</script>
<svelte:head>
<title>{site.name}</title>
<meta property="og:title" content={site.name} />
<meta name="description" content={site.description} />
<meta property="og:description" content={site.description} />
<meta property="og:image" content={baseURL + site.image} />
</svelte:head>
<header class="mb-24 flex flex-col items-center text-center font-title">
<h1 class="mb-1 scroll-m-20 text-5xl font-extrabold tracking-tight lg:text-6xl">Vinge värk</h1>
<p class="font-sans text-base leading-7 text-muted-foreground">
Minu loodud minimängud ja muud huvitavat.
</p>
<p class="font-sans text-base leading-7 text-muted-foreground">
Aitäh
<a href="https://neal.fun" class="font-medium underline underline-offset-4">neal.fun</a> inspo eest
:)
</p>
</header>
<div
class="mx-auto mb-24 flex w-full flex-wrap items-center justify-center justify-items-center gap-4 gap-x-8 gap-y-8 lg:grid-cols-2"
>
{#each Object.entries(games) as [href, { image, name }]}
<a
class="shadow-sharp flex aspect-[4/1] min-h-20 max-w-sm items-center justify-center rounded-xl border-2 border-current bg-contain bg-no-repeat transition-all {href ===
''
? 'pressed pointer-events-none'
: ''}"
style="background-image: url('{image}')"
draggable="false"
href="/vinge/{href}"
>
<span class="relative block select-none rounded font-mono text-lg font-semibold lg:text-xl">
{name}
</span>
</a>
{/each}
</div>