feat: some shit

This commit is contained in:
2024-03-26 16:36:18 +01:00
commit f0129ecc76
31 changed files with 5074 additions and 0 deletions

61
src/components/Card.astro Normal file
View File

@ -0,0 +1,61 @@
---
interface Props {
title: string;
body: string;
href: string;
}
const { href, title, body } = Astro.props;
---
<li class="link-card">
<a href={href}>
<h2>
{title}
<span>&rarr;</span>
</h2>
<p>
{body}
</p>
</a>
</li>
<style>
.link-card {
list-style: none;
display: flex;
padding: 1px;
background-color: #23262d;
background-image: none;
background-size: 400%;
border-radius: 7px;
background-position: 100%;
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
}
.link-card > a {
width: 100%;
text-decoration: none;
line-height: 1.4;
padding: calc(1.5rem - 1px);
border-radius: 8px;
color: white;
background-color: #23262d;
opacity: 0.8;
}
h2 {
margin: 0;
font-size: 1.25rem;
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
p {
margin-top: 0.5rem;
margin-bottom: 0;
}
.link-card:is(:hover, :focus-within) {
background-position: 0;
background-image: var(--accent-gradient);
}
.link-card:is(:hover, :focus-within) h2 {
color: rgb(var(--accent-light));
}
</style>

View File

@ -0,0 +1,24 @@
---
import { locales, defaultLocale, getLocale } from "astro-i18n-aut";
import { useTranslations } from "../i18n/utils";
const reg = new RegExp(`^\/(${Object.keys(locales).join("|")})\/`);
function translatePath(lang: string) {
const p = Astro.url.pathname.replace(reg, "").replace(/^\//, "");
if (lang === defaultLocale) return `/${p}`;
return `/${lang}/${p}`;
}
const locale = getLocale(Astro.url);
const t = useTranslations(locale);
---
<ul>
{
Object.entries(locales).map(([lang, label]) => (
<li>
<a href={translatePath(lang)}>{t(label as "de")}</a>
</li>
))
}
</ul>

28
src/components/Logo.astro Normal file
View File

@ -0,0 +1,28 @@
<svg
width="51"
height="51"
viewBox="0 0 51 51"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<style>
#l1 {
fill: var(--background-fill, white);
}
#l2 {
fill: var(--fill, black);
}
</style>
</defs>
<path
id="l1"
d="M1 1H30C41.0457 1 50 9.95431 50 21V50H21C9.9543 50 1 41.0457 1 30V1Z"
fill="#D9D9D9"></path>
<path
id="l2"
fill-rule="evenodd"
clip-rule="evenodd"
d="M32.1858 0H0V32.3483C0.00211949 37.2944 1.96787 42.0373 5.46525 45.5347C8.96263 49.0321 13.7055 50.9979 18.6515 51H51L50.9951 18.8068C50.9944 13.8187 49.0124 9.03512 45.485 5.50823C41.9577 1.98134 37.1739 0 32.1858 0ZM6.25226 24.0718V32.3266C7.58107 32.3026 8.90553 32.1632 10.2107 31.9098C11.926 31.5636 14.3415 30.7681 16.3608 29.4766C18.3114 28.2294 20.5948 25.9682 21.9972 23.2498C23.3186 20.6901 24.2262 16.9255 24.335 12.7292C24.3623 10.4781 24.3837 8.31912 24.3991 6.25232H16.1396C16.1244 8.28561 16.1034 10.4124 16.0768 12.6327C16.0967 15.8503 15.5564 17.7243 14.6577 19.4641C13.8422 21.0463 13.1354 21.7386 11.9127 22.5209C10.7588 23.2576 9.81681 23.5661 8.58412 23.8146C7.81609 23.9716 7.03552 24.0577 6.25226 24.0718ZM32.1461 6.25232V44.7477H40.4054V9.31633C38.1307 7.34663 35.2147 6.25232 32.1858 6.25232H32.1461Z"
fill="#CB5A5A"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

47
src/components/Nav.astro Normal file
View File

@ -0,0 +1,47 @@
---
import { getLocale } from "astro-i18n-aut";
import { useTranslations, useTranslatedPath } from "../i18n/utils";
import Logo from "./Logo.astro";
const lang = getLocale(Astro.url);
const t = useTranslations(lang);
const translatePath = useTranslatedPath(lang);
---
<style>
ul {
display: flex;
gap: 1rem;
list-style: none;
padding: 0;
}
li {
display: flex;
align-items: center;
}
a {
color: var(--text-color);
text-decoration: none;
}
</style>
<ul>
<li>
<a
href={translatePath("/")}
style="--fill: red; --background-fill: transparent;"
>
<Logo />
</a>
</li>
<li>
<a href={translatePath("/blog")}>
{t("nav.blog")}
</a>
</li>
<li>
<a href={translatePath("/about")}>
{t("nav.about")}
</a>
</li>
</ul>

View File

@ -0,0 +1,7 @@
---
date: 2021-01-01
author: MaxEN
title: "First Post"
---
# First Post

View File

@ -0,0 +1,7 @@
---
date: 2021-01-01
author: MaxDE
title: "Erster Post"
---
# Erster post

View File

@ -0,0 +1,7 @@
---
date: 2021-01-01
author: MaxEN
title: "Second Post"
---
# 2. post

View File

@ -0,0 +1,7 @@
---
date: 2021-01-01
author: MaxDE
title: "Zweiter Post"
---
# 2. post

View File

@ -0,0 +1,7 @@
---
date: 2021-01-01
author: MaxEN
title: "Third Post"
---
# Third Post

View File

@ -0,0 +1,7 @@
---
date: 2021-01-01
author: MaxDE
title: "Dritter Post"
---
# Dritter Post

13
src/content/config.ts Normal file
View File

@ -0,0 +1,13 @@
import { defineCollection, z } from 'astro:content';
const blogCollection = defineCollection({
schema: z.object({
title: z.string(),
author: z.string(),
date: z.date()
})
});
export const collections = {
'blog': blogCollection
};

2
src/env.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />

26
src/i18n/ui.ts Normal file
View File

@ -0,0 +1,26 @@
export const languages = {
en: 'English',
de: 'Deutsch',
};
export const defaultLang = 'de';
export const ui = {
en: {
"en": "English",
"de": "Deutsch",
'nav.home': 'Home',
'nav.blog': 'Blog',
'nav.about': 'About',
},
de: {
"en": "English",
"de": "Deutsch",
'nav.home': 'Home',
'nav.blog': 'Blog',
'nav.about': 'Über',
},
} as const;
export const showDefaultLang = false;

28
src/i18n/utils.ts Normal file
View File

@ -0,0 +1,28 @@
import { defaultLocale } from 'astro-i18n-aut';
import { ui, defaultLang, showDefaultLang } from './ui';
export function useTranslatedPath(lang: string) {
return function translatePath(path: string, l: string = lang) {
return !showDefaultLang && l === defaultLang ? path : `/${l}${path}`.replace(/\/$/g, '');
}
}
export function useTranslations(lang: string) {
return function t(key: keyof typeof ui[typeof defaultLang]) {
return ui[lang as keyof typeof ui][key] || ui[defaultLang][key];
}
}
export function parseSlug(id: string) {
const splitPath = id.split('/');
const split = splitPath.pop()?.split('.');
const lang = split?.length === 2 ? defaultLocale : split?.[1];
return [splitPath.join("/"), lang]
}
export function filterCollection<T extends { id: string }>(collection: T[], locale: string) {
return collection.filter(post => {
const [_, lang] = parseSlug(post?.id);
return lang === locale;
});
}

41
src/layouts/Layout.astro Normal file
View File

@ -0,0 +1,41 @@
---
import LanguagePicker from "../components/LanguagePicker.astro";
import Nav from "../components/Nav.astro";
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="description" content="Astro description" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="stylesheet" href="/app.css" />
<meta name="generator" content={Astro.generator} />
<!-- <meta http-equiv="refresh" content="0;url=/" /> -->
<title>{title}</title>
<script>
(function () {
try {
var mode = localStorage.getItem("mode");
var supportDarkMode =
window.matchMedia("(prefers-color-scheme: dark)").matches === true;
if (!mode && supportDarkMode)
document.body.classList.add("theme-dark");
if (!mode) return;
document.body.classList.add("theme-" + mode);
} catch (e) {}
})();
</script>
</head>
<body>
<Nav />
<slot />
<LanguagePicker />
</body>
</html>

20
src/layouts/Post.astro Normal file
View File

@ -0,0 +1,20 @@
---
import type { CollectionEntry } from "astro:content";
import Layout from "./Layout.astro";
type Props = CollectionEntry<"blog">["data"];
const { title } = Astro.props;
---
<Layout title={title}>
<article>
<div class="prose">
<div class="title">
<h1>{title}</h1>
<hr />
</div>
<slot />
</div>
</article>
</Layout>

View File

@ -0,0 +1,5 @@
---
import Layout from "../../layouts/Layout.astro";
---
<Layout title="Home"> Sup people :) </Layout>

View File

@ -0,0 +1,26 @@
import { getCollection } from 'astro:content';
export async function GET({ params }: { params: { slug: string } }) {
const pages = await getCollection('blog');
return new Response(
JSON.stringify(pages.filter(post => {
return post.id.includes(params.slug)
})
))
}
export async function getStaticPaths() {
const pages = await getCollection('blog');
return pages.map(p => {
const [postId] = p.id.split('/');
return {
params: {
slug: postId
}
}
});
}

View File

@ -0,0 +1,39 @@
---
import { getCollection } from "astro:content";
import Post from "../../layouts/Post.astro";
import { getLocale } from "astro-i18n-aut";
import { filterCollection, parseSlug } from "../../i18n/utils";
const locale = getLocale(Astro.url);
export async function getStaticPaths() {
const pages = await getCollection("blog");
const paths = pages.map((page) => {
const [slug] = parseSlug(page.id);
return { params: { slug }, props: {...page} };
});
console.log("PATHS");
console.log(paths);
return paths;
}
const pages = await getCollection("blog");
const page = filterCollection(pages, locale).find((page) => {
const [slug] = parseSlug(page.id);
return slug === Astro.params.slug;
});
const formattedDate = page.data?.date?.toLocaleString(locale);
const { Content } = await page.render();
---
{locale}
{JSON.stringify(Astro.params)}
<Post {...page.data}>
<p>by {page.data.author} • {formattedDate}</p>
<Content />
</Post>

View File

@ -0,0 +1,30 @@
---
import { getCollection } from 'astro:content';
const pages = await getCollection('blog');
import Layout from '../../layouts/Layout.astro';
import { getLocale } from "astro-i18n-aut";
import { filterCollection } from '../../i18n/utils';
const locale = getLocale(Astro.url);
const posts = filterCollection(pages, locale);
console.log({posts, locale});
---
<Layout title="Dude">
<hr/>
{
posts.map((post) => (
<>
<a href={"blog/"+post.slug.split("/")[0]}>
{post.data.title}
</a><br/>
</>
))
}
<hr/>
</Layout>

13
src/pages/index.astro Normal file
View File

@ -0,0 +1,13 @@
---
import Layout from '../layouts/Layout.astro';
---
<Layout title="dude">
# Das ist mein Blog
</Layout>