feat: some shit

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

23
.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
astro_tmp_pages_*

54
README.md Normal file
View File

@ -0,0 +1,54 @@
# Astro Starter Kit: Basics
```sh
npm create astro@latest -- --template basics
```
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/basics)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/basics/devcontainer.json)
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
![just-the-basics](https://github.com/withastro/astro/assets/2244813/a0a5533c-a856-4198-8470-2d67b1d7c554)
## 🚀 Project Structure
Inside of your Astro project, you'll see the following folders and files:
```text
/
├── public/
│ └── favicon.svg
├── src/
│ ├── components/
│ │ └── Card.astro
│ ├── layouts/
│ │ └── Layout.astro
│ └── pages/
│ └── index.astro
└── package.json
```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
Any static assets, like images, can be placed in the `public/` directory.
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:4321` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).

36
astro.config.mjs Normal file
View File

@ -0,0 +1,36 @@
import { defineConfig } from 'astro/config';
import { i18n, filterSitemapByDefaultLocale } from "astro-i18n-aut/integration";
import sitemap from "@astrojs/sitemap";
import svelte from "@astrojs/svelte";
import tailwind from "@astrojs/tailwind";
const defaultLocale = "de";
const locales = {
en: "en", // the `defaultLocale` value must present in `locales` keys
de: "de",
};
// https://astro.build/config
export default defineConfig({
site: "https://max-richter.dev",
trailingSlash: "never",
build: {
format: "file",
},
integrations: [
svelte(),
i18n({
exclude: ["pages/**/*.json.ts", "pages/api/**/*",],
locales,
defaultLocale,
}),
sitemap({
i18n: {
locales,
defaultLocale,
},
filter: filterSitemapByDefaultLocale({ defaultLocale }),
}),
]
});

27
package.json Normal file
View File

@ -0,0 +1,27 @@
{
"name": "website",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.5.9",
"@astrojs/svelte": "^5.2.0",
"@astrojs/tailwind": "^5.1.0",
"astro": "^4.5.5",
"astro-i18n-aut": "^0.7.0",
"svelte": "^4.2.12",
"tailwindcss": "^3.4.1",
"typescript": "^5.4.2"
},
"devDependencies": {
"@astrojs/sitemap": "^3.1.1",
"prettier": "^3.2.5",
"prettier-plugin-astro": "^0.13.0"
}
}

4443
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

20
public/app.css Normal file
View File

@ -0,0 +1,20 @@
:root {
--neutral800: #16161E;
--neutral500: #252530;
--neutral400: #2C2C3A;
--neutral300: #414152;
--neutral100: #AAAABB;
--neutral000: #F1F1F4;
}
body {
--background-dark: var(--neutral800);
--background: var(--neutral500);
--background-light: var(--neutral400);
--outline: var(--neutral300);
--text: var(--neutral100);
background-color: var(--background-dark);
color: var(--text);
font-family: 'Roboto', sans-serif;
}

10
public/favicon.svg Executable file
View File

@ -0,0 +1,10 @@
<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 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"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

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>

5
svelte.config.js Normal file
View File

@ -0,0 +1,5 @@
import { vitePreprocess } from '@astrojs/svelte';
export default {
preprocess: vitePreprocess(),
}

8
tailwind.config.mjs Normal file
View File

@ -0,0 +1,8 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {},
},
plugins: [],
}

3
tsconfig.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "astro/tsconfigs/strict"
}