feat: add ci

This commit is contained in:
2024-04-03 16:18:30 +02:00
parent 195d7dab5d
commit a301e71e95
13 changed files with 274 additions and 23 deletions

48
.github/workflows/default.yaml vendored Normal file
View File

@@ -0,0 +1,48 @@
name: Deploy to GitHub Pages
on:
push:
branches: [ main ]
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
steps:
- name: Checkout your repository using git
uses: actions/checkout@v4
- name: 🗳️ Setup pnpm cache
uses: https://github.com/actions/cache@v3
with:
path: ${{ env.PNPM_STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ env.PNPM_CACHE_ID }}
restore-keys: |
${{ runner.os }}-pnpm-store
- name: Install, build, and upload your site
uses: withastro/action@v2
# with:
# path: . # The root location of your Astro project inside the repository. (optional)
# node-version: 20 # The specific version of Node that should be used to build your site. Defaults to 20. (optional)
# package-manager: pnpm@latest # The Node package manager that should be used to install dependencies and build your site. Automatically detected based on your lockfile. (optional)
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: 🚀 Deploy files via SFTP
uses: https://github.com/pressidium/lftp-mirror-action@v1
with:
host: ${{ secrets.FTP_HOST }}
port: ${{ secrets.FTP_PORT || 21 }}
user: ${{ secrets.FTP_USERNAME }}
pass: ${{ secrets.FTP_PASSWORD }}
onlyNewer: true
parallel: '4'
settings: 'sftp:auto-confirm=yes'
localDir: 'public'
remoteDir: '/share'
options: '--verbose'

View File

@@ -9,16 +9,21 @@ h3 {
font-family: 'Roboto', sans-serif;
}
article h2 {
article>h2 {
font-size: 24px;
margin-top: 20px;
}
article h3 {
article>h3 {
font-size: 20px;
margin-top: 16px;
}
article>p>a,
article a {
color: var(--fill) !important;
}
:root {
--neutral-1000: #000000;
--neutral-800: #16161E;

View File

@@ -92,8 +92,7 @@
<div
class="googley-eyes"
on:click={() => ($visible = !$visible)}
role="button"
tabindex="0"
role="img"
aria-label="Toggle Googley Eyes"
aria-hidden="true"
on:keydown={(ev) => (ev.key === "Enter" ? ($visible = !$visible) : "")}

View File

@@ -1,7 +1,7 @@
---
import markdownToText from "@helpers/markdownToText";
import { Card } from "./card";
import { useTranslatedPath } from "@i18n/utils";
import { useTranslatedPath, useTranslations } from "@i18n/utils";
import Image from "@components/Image.astro";
interface Props {
@@ -25,6 +25,7 @@ const {
} = Astro.props.post;
const translatePath = useTranslatedPath(Astro);
const t = useTranslations(Astro);
const imagePath = `../content/${collection}/${slug.split("/")[0]}/${headerImg}`;
@@ -44,7 +45,7 @@ const link = translatePath(`/${collection}/${slug.split("/")[0]}`);
<Card.Description>
{markdownToText(body).slice(0, 200)}
</Card.Description>
<Card.ReadMoreButton link={link} />
<Card.ReadMoreButton link={link} text={t("read-more")} />
</Card.Content>
{
image?.format && (

View File

@@ -11,8 +11,6 @@ interface Props {
const { src: image, alt, maxWidth } = Astro.props;
console.log({ image, alt, maxWidth });
const sizes = [
{
width: 240,

View File

@@ -1,6 +1,7 @@
---
import { useTranslations, useTranslatedPath } from "../i18n/utils";
import Logo from "./Logo.astro";
import ToggleTheme from "@components/ThemeToggle.svelte";
function isActive(path: string) {
return Astro.url.pathname === path ? "active" : "";
@@ -10,10 +11,6 @@ const t = useTranslations(Astro);
const translatePath = useTranslatedPath(Astro);
const paths = [
{
link: translatePath("/"),
component: Logo,
},
{
link: translatePath("/blog"),
text: t("nav.blog"),
@@ -33,16 +30,26 @@ const paths = [
];
---
<ul class="flex my-4 divide-x divide-x-1 divide-x-neutral">
<ul class="flex my-4 h-12">
<li><a href="#main-content" class="skip-link">Skip to main content</a></li>
<li
class="border-none bg-transparent my-2 mr-4 logo grid place-content-center"
>
<a
href={translatePath("/")}
class="text-neutral h-9 flex items-center justify-center lowercase"
>
<Logo />
</a>
</li>
{
paths.map(({ link, text, component }, i) => (
paths.map(({ link, text }, i) => (
<li
class={`
flex items-center flex-1 border-t-1 border-b-1 border-neutral
${isActive(link) ? "bg-light" : "bg"}
${i === 1 ? "rounded-bl-md" : ""}
${i === 0 ? "rounded-bl-md border-l-1" : "border-l-1"}
${i === paths.length - 1 ? "rounded-tr-md !border-r-1" : ""}
${component ? "border-none bg-transparent my-2 mr-4 logo" : ""}
`}
>
<a
@@ -50,20 +57,40 @@ const paths = [
href={link}
data-astro-prefetch
>
{component ? <Logo /> : text}
{text}
</a>
</li>
))
}
<li class="w-8 h-6 flex justify-right items-center h-full">
<ToggleTheme client:load />
</li>
</ul>
<style>
ul > li.logo {
background: none;
flex: 0;
height: 34px;
margin-left: 0px;
--fill: #cb5a5a;
--background-fill: none;
}
/* Visually hide the jump to content button while making it accessible */
.skip-link {
position: absolute;
left: -9999px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
/* Make the jump to content button visible when focused */
.skip-link:focus {
position: absolute;
left: 0;
width: auto;
height: auto;
overflow: visible;
}
</style>

View File

@@ -0,0 +1,59 @@
<script lang="ts">
import { onMount } from "svelte";
import { writable } from "svelte/store";
let theme = writable("light");
onMount(() => {
theme.set(localStorage.getItem("theme") || "light");
});
$: if ($theme && "document" in globalThis) {
document.documentElement.classList.remove("light", "dark");
document.documentElement.classList.add($theme);
localStorage.setItem("theme", $theme);
}
function toggleTheme() {
console.log($theme);
theme.update((t) => (t === "light" ? "dark" : "light"));
}
</script>
<button class="block w-6 h-6" on:click={toggleTheme} title="toggle dark mode">
{#if $theme === "dark"}
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
class="icon icon-tabler icons-tabler-outline icon-tabler-sun"
><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path
d="M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0"
/><path
d="M3 12h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7"
/></svg
>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.25"
stroke-linecap="round"
stroke-linejoin="round"
class="icon icon-tabler icons-tabler-outline icon-tabler-moon"
><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path
d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"
/></svg
>
{/if}
</button>

Binary file not shown.

View File

@@ -72,7 +72,7 @@ const { title, width = "compact" } = Astro.props;
<header>
<Nav />
</header>
<main class="flex flex-col mt-4xl gap-y-2xl">
<main id="main-content" class="flex flex-col mt-4xl gap-y-2xl">
<slot />
</main>
<LanguagePicker />

View File

@@ -7,7 +7,9 @@ import HeroCard from "@components/HeroCard.astro";
const locale = getLocale(Astro.url);
const pages = await getCollection("projects");
const posts = filterCollection(pages, locale);
const posts = filterCollection(pages, locale)
.sort((a, b) => b.data.date - a.data.date)
.sort((a) => (a.data.featured ? -1 : 1));
---
<Layout title="Dude">

71
src/pages/tag/[tag].astro Normal file
View File

@@ -0,0 +1,71 @@
---
import Layout from "@layouts/Layout.astro";
import { getCollection } from "astro:content";
import { useTranslatedPath } from "@i18n/utils";
const collections = ["blog", "photos", "projects"];
const tp = useTranslatedPath(Astro);
export async function getStaticPaths() {
const collections = ["blog", "photos", "projects"];
const posts = await Promise.all(
collections.map((collection) => {
return getCollection(collection, {
fields: ["slug", "title", "date", "tags"],
});
}),
);
const tags = new Set();
posts.flat().forEach((post) => {
if (!post.data?.tags) return;
post.data.tags.forEach((tag) => {
tags.add(tag.toLowerCase());
});
});
return [...tags.values()].map((tag) => {
return {
params: {
tag,
},
};
});
}
const { tag } = Astro.params;
const allPosts = (await Promise.all(
collections.map((collection) => {
return getCollection(collection, {
fields: ["slug", "title", "date", "tags"],
});
}),
)).flat();
const posts = allPosts.filter((post) => {
return post.data?.tags?.find(t => t.toLowerCase() === tag);
});
---
<Layout title="Max Richter">
<article>
<h1>Tags</h1>
{posts.length}
<div class="flex flex-col gap-2">
{
posts.map((post) => {
return <a href={tp("/"+post.collection+"/" + post.slug)}>{post.slug}</a>;
})
}
</div>
</article>
</Layout>

41
src/pages/tag/index.astro Normal file
View File

@@ -0,0 +1,41 @@
---
import Layout from "@layouts/Layout.astro";
import { getCollection } from "astro:content";
import { useTranslatedPath } from "@i18n/utils";
const tp = useTranslatedPath(Astro);
const collections = ["blog", "photos", "projects"];
const posts = await Promise.all(
collections.map((collection) => {
return getCollection(collection, {
fields: ["slug", "title", "date", "tags"],
});
}),
);
const tags = new Set();
posts.flat().forEach((post) => {
if (!post.data?.tags) return;
post.data.tags.forEach((tag) => {
tags.add(tag.toLowerCase());
});
});
const _tags = [...tags.values()];
---
<Layout title="Max Richter">
<article>
<h1>Tags</h1>
<div class="flex flex-col gap-2">
{
_tags.map((t) => {
return <a href={tp("/tag/" + t)}>{t}</a>;
})
}
</div>
</article>
</Layout>

View File

@@ -15,7 +15,7 @@ export default defineConfig({
"border-neutral": "border-neutral-300 dark:border-neutral-1000",
"border-light": "border-neutral-100 dark:border-neutral-500",
"divide-x-neutral": ['divide-x-neutral-300', "dark:divide-x-neutral-1000"],
"gradient": "bg-gradient-to-br from-neutral-000 dark:from-neutral-500 to-neutral-200 dark:to-neutral-800",
"gradient": "bg-gradient-to-br from-neutral-000 to-neutral-000 dark:from-neutral-500 dark:to-neutral-800",
},
theme: {
borderRadius: {