Merge branch 'master' into deploy

This commit is contained in:
Saibotk 2022-10-23 12:40:06 +02:00
commit dca93ba228
Signed by: saibotk
GPG key ID: 67585F0065E261D5
63 changed files with 6225 additions and 414 deletions

7
.docker/Dockerfile Normal file
View file

@ -0,0 +1,7 @@
FROM docker.io/library/nginx:1.23.1-alpine
COPY ./dist/ /usr/share/nginx/html/
COPY ./.docker/default.conf /etc/nginx/conf.d/
HEALTHCHECK CMD wget -O- http://127.0.0.1/status.txt | grep -q 'OK'

View file

@ -1,4 +1,4 @@
# Nginx config # Nginx config
# Inspired by https://git.shivering-isles.com/shivering-isles/blog/blob/deploy/_docker/default.conf # Inspired by https://git.shivering-isles.com/shivering-isles/blog/blob/deploy/_docker/default.conf
# Expires map # Expires map

View file

@ -1,3 +1,3 @@
* *
!public !dist
!_docker !.docker

18
.editorconfig Normal file
View file

@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
[docker-compose.yml]
indent_size = 4

22
.eslintrc.cjs Normal file
View file

@ -0,0 +1,22 @@
module.exports = {
extends: ['@clickbar/typescript', 'plugin:astro/recommended'],
overrides: [
{
// Define the configuration for `.astro` file.
files: ['*.astro'],
// Allows Astro components to be parsed.
parser: 'astro-eslint-parser',
// Parse the script in `.astro` as TypeScript by adding the following configuration.
// It's the setting you need when using TypeScript.
parserOptions: {
parser: '@typescript-eslint/parser',
extraFileExtensions: ['.astro'],
},
rules: {
// override/add rules settings here, such as:
// Does not work well with typescript
'no-undef': 'off',
},
},
],
}

27
.gitignore vendored
View file

@ -1,14 +1,19 @@
# Created by https://www.gitignore.io/api/hugo # build output
# Edit at https://www.gitignore.io/?templates=hugo dist/
### Hugo ### # dependencies
# Generated files by hugo node_modules/
/public/
/resources/_gen/
# Executable may be added to repository # logs
hugo.exe npm-debug.log*
hugo.darwin yarn-debug.log*
hugo.linux yarn-error.log*
pnpm-debug.log*
# End of https://www.gitignore.io/api/hugo
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store

View file

@ -7,34 +7,30 @@ variables:
GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_STRATEGY: recursive
stages: stages:
- orthography
- build - build
- package - package
- test - test
- deploy - deploy
spellcheck:
stage: orthography
image: docker.io/library/node:17.6
before_script:
- npm i -g markdown-spellcheck
script:
- mdspell -r -n -a --en-gb "content/posts/*.md" "content/posts/*.markdown"
build: build:
image: docker.io/cibuilds/hugo:0.93 image: docker.io/library/node:18.4
stage: build stage: build
variables:
HUGO_ENV: production
LANG: C.UTF-8
before_script: before_script:
- hugo --minify --enableGitInfo - npm install -g pnpm@7
- pnpm config set store-dir .pnpm-store
script: script:
- htmlproofer ./public --allow-hash-href --check-html --empty-alt-ignore --disable-external - pnpm install # install dependencies
- pnpm run build
cache:
key:
files:
- pnpm-lock.yaml
paths:
- .pnpm-store
artifacts: artifacts:
untracked: true untracked: true
paths: paths:
- public - dist
expire_in: 1 week expire_in: 1 week
package: package:
@ -47,7 +43,7 @@ package:
before_script: before_script:
- podman login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY - podman login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script: script:
- podman build --pull -f _docker/Dockerfile -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" . - podman build --pull -f .docker/Dockerfile -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" .
- podman push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" - podman push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
except: except:
- deploy - deploy
@ -62,7 +58,7 @@ package-deploy:
before_script: before_script:
- podman login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY - podman login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script: script:
- podman build --pull -f _docker/Dockerfile -t "$CI_REGISTRY_IMAGE" . - podman build --pull -f .docker/Dockerfile -t "$CI_REGISTRY_IMAGE" .
- podman push "$CI_REGISTRY_IMAGE" - podman push "$CI_REGISTRY_IMAGE"
only: only:
- deploy - deploy

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "themes/hermit"]
path = themes/hermit
url = https://github.com/Track3/hermit.git

2
.npmrc Normal file
View file

@ -0,0 +1,2 @@
# Expose Astro dependencies for `pnpm` users
shamefully-hoist=true

11
.prettierrc.cjs Normal file
View file

@ -0,0 +1,11 @@
module.exports = {
plugins: [require.resolve('prettier-plugin-astro')],
overrides: [
{
files: '*.astro',
options: {
parser: 'astro',
},
},
],
};

View file

@ -1,6 +0,0 @@
# markdown-spellcheck spelling configuration file
# Format - lines begining # are comments
# global dictionary is at the start, file overrides afterwards
# one word per line, to define a file override use ' - filename'
# where filename is relative to this configuration file
saibotk

4
.vscode/extensions.json vendored Normal file
View file

@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

11
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

View file

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2020 Saibotk Copyright (c) 2022 Saibotk
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,2 +1,64 @@
# saiblog # Astro Starter Kit: Blog
```
npm create astro@latest -- --template blog
```
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/blog)
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
![blog](https://user-images.githubusercontent.com/4677417/186189140-4ef17aac-c3c9-4918-a8c2-ce86ba1bb394.png)
Features:
- ✅ Minimal styling (make it your own!)
- ✅ 100/100 Lighthouse performance
- ✅ SEO-friendly with canonical URLs and OpenGraph data
- ✅ Sitemap support
- ✅ RSS Feed support
- ✅ Markdown & MDX support
## 🚀 Project Structure
Inside of your Astro project, you'll see the following folders and files:
```
├── public/
├── src/
│   ├── components/
│   ├── layouts/
│   └── pages/
├── astro.config.mjs
├── README.md
├── package.json
└── tsconfig.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:3000` |
| `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?
Check out [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
## Credit
This theme is based off of the lovely [Bear Blog](https://github.com/HermanMartinus/bearblog/).

View file

@ -1,7 +0,0 @@
FROM docker.io/library/nginx:1.21.6-alpine
COPY ./public/ /usr/share/nginx/html/
COPY ./_docker/default.conf /etc/nginx/conf.d/
HEALTHCHECK CMD wget -O- http://127.0.0.1/status.txt | grep -q 'OK'

View file

@ -1,6 +0,0 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

View file

@ -1,106 +0,0 @@
/**
* Utils
*
* From https://github.com/Track3/hermit/blob/master/assets/js/main.js
*
* MIT licensed
*/
// Throttle
//
const throttle = (callback, limit) => {
let timeoutHandler = null;
return () => {
if (timeoutHandler == null) {
timeoutHandler = setTimeout(() => {
callback();
timeoutHandler = null;
}, limit);
}
};
};
// addEventListener Helper
//
const listen = (ele, e, callback) => {
if (document.querySelector(ele) !== null) {
document.querySelector(ele).addEventListener(e, callback);
}
}
/**
* Functions
*/
// Auto Hide Header
//
let header = document.getElementById('site-header');
let lastScrollPosition = window.pageYOffset;
const autoHideHeader = () => {
let currentScrollPosition = Math.max(window.pageYOffset, 0);
if (currentScrollPosition > lastScrollPosition && document.documentElement.clientHeight + currentScrollPosition < document.documentElement.offsetHeight) {
header.classList.remove('slideInUp');
header.classList.add('slideOutDown');
} else {
header.classList.remove('slideOutDown');
header.classList.add('slideInUp');
}
lastScrollPosition = currentScrollPosition;
}
// Mobile Menu Toggle
//
let mobileMenuVisible = false;
const toggleMobileMenu = () => {
let mobileMenu = document.getElementById('mobile-menu');
if (mobileMenuVisible == false) {
mobileMenu.style.animationName = 'bounceInRight';
mobileMenu.style.webkitAnimationName = 'bounceInRight';
mobileMenu.style.display = 'block';
mobileMenuVisible = true;
} else {
mobileMenu.style.animationName = 'bounceOutRight';
mobileMenu.style.webkitAnimationName = 'bounceOutRight'
mobileMenuVisible = false;
}
}
// Featured Image Toggle
//
const showImg = () => {
document.querySelector('.bg-img').classList.add('show-bg-img');
}
const hideImg = () => {
document.querySelector('.bg-img').classList.remove('show-bg-img');
}
// ToC Toggle
//
const toggleToc = () => {
document.getElementById('toc').classList.toggle('show-toc');
}
if (header !== null) {
listen('#menu-btn', "click", toggleMobileMenu);
listen('#toc-btn', "click", toggleToc);
listen('#img-btn', "click", showImg);
listen('.bg-img', "click", hideImg);
document.querySelectorAll('.post-year').forEach((ele)=> {
ele.addEventListener('click', () => {
window.location.hash = '#' + ele.id;
});
});
window.addEventListener('scroll', throttle(() => {
autoHideHeader();
if (mobileMenuVisible == true) {
toggleMobileMenu();
}
}, 450));
}

16
astro.config.mjs Normal file
View file

@ -0,0 +1,16 @@
import { defineConfig } from 'astro/config'
import mdx from '@astrojs/mdx'
import sitemap from '@astrojs/sitemap'
import tailwind from '@astrojs/tailwind'
// https://astro.build/config
export default defineConfig({
site: 'https://saibotk.de',
integrations: [mdx(), sitemap(), tailwind()],
markdown: {
shikiConfig: {
theme: 'rose-pine-moon',
},
},
})

View file

@ -1,81 +0,0 @@
baseURL = "https://saibotk.de"
languageCode = "en-us"
defaultContentLanguage = "en"
title = "Saiblog"
theme = "hermit"
enableGitInfo = true
pygmentsCodefences = true
pygmentsUseClasses = true
# hasCJKLanguage = true # If Chinese/Japanese/Korean is your main content language, enable this to make wordCount works right.
rssLimit = 10 # Maximum number of items in the RSS feed.
copyright = "This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License." # This message is only used by the RSS template.
enableEmoji = true # Shorthand emojis in content files - https://gohugo.io/functions/emojify/
# googleAnalytics = "UA-123-45"
# disqusShortname = "yourdiscussshortname"
enableRobotsTXT=true
[author]
name = "saibotk"
[blackfriday]
# hrefTargetBlank = true
# noreferrerLinks = true
# nofollowLinks = true
[taxonomies]
tag = "tags"
# Categories are disabled by default.
[params]
dateform = "Jan 2, 2006"
dateformShort = "Jan 2"
dateformNum = "2006-01-02"
dateformNumTime = "2006-01-02 15:04 -0700"
# Metadata mostly used in document's head
description = "My personal blog about various code / devops related things."
# images = [""]
themeColor = "#494f5c"
homeSubtitle = "My personal blog about various code / devops related things."
footerCopyright = ' &#183; <a href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank" rel="noopener">CC BY-NC 4.0</a>'
# bgImg = "" # Homepage background-image URL
# Prefix of link to the git commit detail page. GitInfo must be enabled.
gitUrl = "https://git.saibotk.de/saibotk.de/saiblog/commit/"
# Toggling this option needs to rebuild SCSS, requires Hugo extended version
justifyContent = false # Set "text-align: justify" to `.content`.
relatedPosts = true # Add a related content section to all single posts page
code_copy_button = true # Turn on/off the code-copy-button for code-fields
# Add custom css
# customCSS = ["css/foo.css", "css/bar.css"]
# Social Icons
# Check https://github.com/Track3/hermit#social-icons for more info.
#[[params.social]]
# name = "email"
# url = "mailto:info (a t) saibotk.de"
[[params.social]]
name = "github"
url = "https://github.com/saibotk"
[[params.social]]
name = "gitlab"
url = "https://git.saibotk.de/saibotk"
[[params.social]]
name = "mastodon"
url = "https://flausch.social/@saibotk"
[menu]
[[menu.main]]
name = "Posts"
url = "posts/"
weight = 10

View file

@ -1,33 +0,0 @@
{{ define "header" }}
{{ partialCached "header.html" . }}
{{ end }}
{{ define "main" }}
<main class="site-main section-inner thin animated fadeIn faster">
<h1>#{{ .Title }}</h1>
{{- if .Content }}
<div class="content">
{{ .Content }}
</div>
{{- end }}
{{- range .Data.Pages.GroupByDate "2006" }}
<div class="posts-group">
<div class="post-year" id="{{ .Key }}">{{ .Key }}</div>
<ul class="posts-list">
{{- range .Pages }}
<li class="post-item">
<a href="{{.Permalink}}">
<span class="post-title">{{.Title}}</span>
<span class="post-day">{{ .Date.Format .Site.Params.dateformShort }}</span>
</a>
</li>
{{- end }}
</ul>
</div>
{{- end }}
</main>
{{ end }}
{{ define "footer" }}
{{ partialCached "footer.html" . }}
{{ end }}

View file

@ -1,37 +0,0 @@
{{ define "head" }}
{{ if .Site.Params.bgImg -}}
<style>.bg-img {background-image: url('{{.Site.Params.bgImg}}');}</style>
{{- else if .Site.Params.images -}}
{{- range first 1 .Site.Params.images -}}
<style>.bg-img {background-image: url('{{. | absURL}}');}</style>
{{- end -}}
{{- end -}}
{{ end }}
{{ define "main" }}
{{- if (or .Site.Params.images .Site.Params.bgImg) }}
<div class="bg-img"></div>
{{- end }}
<div id="spotlight" class="animated fadeIn">
<div id="home-center">
<h1 id="home-title">{{ .Site.Title }}</h1>
{{- with .Site.Params.homeSubtitle }}
<p id="home-subtitle">{{.}}</p>
{{- end }}
{{- with .Site.Params.social }}
<div id="home-social">
{{ partialCached "social-icons.html" . }}
</div>
{{- end }}
<nav id="home-nav" class="site-nav">
{{ partialCached "menu.html" . }}
</nav>
</div>
<div id="home-footer">
<p>
&copy; {{ now.Format "2006" }} <a href="{{ .Site.BaseURL }}">{{ .Site.Author.name }}</a>{{ .Site.Params.footerCopyright | safeHTML }} &#183; <a href="https://git.saibotk.de/saibotk.de/saiblog" target="_blank">Source Code</a>
{{- with (not (in (.Site.Language.Get "disableKinds") "RSS")) }} &#183; <a href="{{ "posts/index.xml" | absLangURL }}" target="_blank" title="rss"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-rss"><path d="M4 11a9 9 0 0 1 9 9"></path><path d="M4 4a16 16 0 0 1 16 16"></path><circle cx="5" cy="19" r="1"></circle></svg></a>{{ end }}
</p>
</div>
</div>
{{ end }}

View file

@ -1,7 +0,0 @@
<footer id="site-footer" class="section-inner thin animated fadeIn faster">
<p>&copy; {{ now.Format "2006" }} <a href="{{ .Site.BaseURL }}">{{ .Site.Author.name }}</a>{{ .Site.Params.footerCopyright | safeHTML }}</p>
<p>
Made with <a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a> &#183; Theme <a href="https://github.com/Track3/hermit" target="_blank" rel="noopener">Hermit</a> &#183; <a href="https://git.saibotk.de/saibotk.de/saiblog" target="_blank">Source Code</a>
{{- with (not (in (.Site.Language.Get "disableKinds") "RSS")) }} &#183; <a href="{{ "posts/index.xml" | absLangURL }}" target="_blank" title="rss"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-rss"><path d="M4 11a9 9 0 0 1 9 9"></path><path d="M4 4a16 16 0 0 1 16 16"></path><circle cx="5" cy="19" r="1"></circle></svg></a>{{ end }}
</p>
</footer>

View file

@ -1,31 +0,0 @@
<header id="site-header" class="animated">
<div class="hdr-wrapper section-inner">
<div class="hdr-left">
<div class="site-branding">
<a href="{{.Site.BaseURL}}">{{ .Site.Title }}</a>
</div>
<nav class="site-nav hide-in-mobile">
{{ partialCached "menu.html" . }}
</nav>
</div>
<div class="hdr-right hdr-icons">
{{ if (or .Params.images .Params.featuredImg) -}}
<button id="img-btn" class="hdr-btn" title="{{i18n "featuredImage"}}"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-image"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg></button>
{{- end }}
{{- with .Params.toc -}}
<button id="toc-btn" class="hdr-btn desktop-only-ib" title="{{i18n "tableOfContents"}}"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-list"><line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><line x1="3" y1="6" x2="3" y2="6"></line><line x1="3" y1="12" x2="3" y2="12"></line><line x1="3" y1="18" x2="3" y2="18"></line></svg></button>
{{- end }}
{{- with .Site.Params.social -}}
<span class="hdr-social hide-in-mobile">{{ partialCached "social-icons.html" . }}</span>
{{- end -}}
<button id="menu-btn" class="hdr-btn" title="{{i18n "menu"}}"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg></button>
</div>
</div>
</header>
<div id="mobile-menu" class="animated fast">
<ul>
{{- range .Site.Menus.main }}
<li><a href="{{ .URL | absLangURL }}">{{ .Name }}</a></li>
{{- end }}
</ul>
</div>

View file

@ -1,49 +0,0 @@
{{- if (eq .name "codepen") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2"></polygon><line x1="12" y1="22" x2="12" y2="15.5"></line><polyline points="22 8.5 12 15.5 2 8.5"></polyline><polyline points="2 15.5 12 8.5 22 15.5"></polyline><line x1="12" y1="2" x2="12" y2="8.5"></line></svg>
{{- else if (eq .name "facebook") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path></svg>
{{- else if (eq .name "github") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path></svg>
{{- else if (eq .name "gitlab") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22.65 14.39L12 22.13 1.35 14.39a.84.84 0 0 1-.3-.94l1.22-3.78 2.44-7.51A.42.42 0 0 1 4.82 2a.43.43 0 0 1 .58 0 .42.42 0 0 1 .11.18l2.44 7.49h8.1l2.44-7.51A.42.42 0 0 1 18.6 2a.43.43 0 0 1 .58 0 .42.42 0 0 1 .11.18l2.44 7.51L23 13.45a.84.84 0 0 1-.35.94z"></path></svg>
{{- else if (eq .name "instagram") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path><line x1="17.5" y1="6.5" x2="17.5" y2="6.5"></line></svg>
{{- else if (eq .name "linkedin") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"></path><rect x="2" y="9" width="4" height="12"></rect><circle cx="4" cy="4" r="2"></circle></svg>
{{- else if (eq .name "slack") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22.08 9C19.81 1.41 16.54-.35 9 1.92S-.35 7.46 1.92 15 7.46 24.35 15 22.08 24.35 16.54 22.08 9z"></path><line x1="12.57" y1="5.99" x2="16.15" y2="16.39"></line><line x1="7.85" y1="7.61" x2="11.43" y2="18.01"></line><line x1="16.39" y1="7.85" x2="5.99" y2="11.43"></line><line x1="18.01" y1="12.57" x2="7.61" y2="16.15"></line></svg>
{{- else if (eq .name "stackoverflow") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2.913 16.041v6.848h17.599v-6.848M7.16 18.696h8.925M7.65 13.937l8.675 1.8M9.214 9.124l8.058 3.758M12.086 4.65l6.849 5.66M15.774 1.111l5.313 7.162"/></svg>
{{- else if (eq .name "telegram") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.198 2.433a2.242 2.242 0 0 0-1.022.215l-8.609 3.33c-2.068.8-4.133 1.598-5.724 2.21a405.15 405.15 0 0 1-2.849 1.09c-.42.147-.99.332-1.473.901-.728.968.193 1.798.919 2.286 1.61.516 3.275 1.009 4.654 1.472.509 1.793.997 3.592 1.48 5.388.16.36.506.494.864.498l-.002.018s.281.028.555-.038a2.1 2.1 0 0 0 .933-.517c.345-.324 1.28-1.244 1.811-1.764l3.999 2.952.032.018s.442.311 1.09.355c.324.022.75-.04 1.116-.308.37-.27.613-.702.728-1.196.342-1.492 2.61-12.285 2.997-14.072l-.01.042c.27-1.006.17-1.928-.455-2.474a1.654 1.654 0 0 0-1.034-.407z"/></svg>
{{- else if (eq .name "twitch") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2H3v16h5v4l4-4h5l4-4V2zm-10 9V7m5 4V7"></path></svg>
{{- else if (eq .name "twitter") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path></svg>
{{- else if (eq .name "youtube") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22.54 6.42a2.78 2.78 0 0 0-1.94-2C18.88 4 12 4 12 4s-6.88 0-8.6.46a2.78 2.78 0 0 0-1.94 2A29 29 0 0 0 1 11.75a29 29 0 0 0 .46 5.33A2.78 2.78 0 0 0 3.4 19c1.72.46 8.6.46 8.6.46s6.88 0 8.6-.46a2.78 2.78 0 0 0 1.94-2 29 29 0 0 0 .46-5.25 29 29 0 0 0-.46-5.33z"></path><polygon points="9.75 15.02 15.5 11.75 9.75 8.48 9.75 15.02"></polygon></svg>
{{- else if (eq .name "email") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>
{{- else if (eq .name "dribbble") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle style="font-variation-settings:normal" cx="12.004" cy="12" r="9.39" paint-order="stroke fill markers"/><path style="font-variation-settings:normal" d="M5.858 19.136s2.343-5.79 8.161-6.422c5.818-.633 7.442.479 7.442.479M2.68 10.839s4.91.752 10.112-1.11c5.202-1.863 5.887-4.601 5.887-4.601"/><path style="font-variation-settings:normal" d="M8.533 3.208s2.888 2.73 5.339 9.235c2.451 6.505 2.344 8.4 2.344 8.4"/></svg>
{{- else if (eq .name "behance") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path paint-order="stroke fill markers" stroke-linejoin="miter" stroke-width="2" style="font-variation-settings:normal" d="M1.774 18.063V5.466h5.51c1.978 0 3.116 1.326 3.055 2.806-.043 1.049-.711 2.988-2.643 2.988h-5.93H7.73c1.224 0 3.532 1.13 3.532 3.532 0 2.4-1.873 3.27-3.318 3.27zm12.57-4.459h7.89s.012-4.18-4.167-4.18c-5.237 0-5.277 9.11-.3 9.11 3.06 0 3.935-1.806 3.935-1.806M15.526 5.823h4.987"/></svg>
{{- else if (eq .name "freepik") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5.737 17.28s3.423.84 7.61.162c4.188-.676 6.862-2.57 6.862-2.57s.28 3.943-4.967 5.33c-5.248 1.388-8.543.657-9.506-2.923zm-.62-3.104s4.491 1.361 8.728.344c4.237-1.016 5.94-2.568 5.94-2.568s-1.81-6.448-7.405-5.648c-5.597.8-8.061 4.414-7.263 7.872z" style="font-variation-settings:normal" stroke-linejoin="round"/><path d="M1.265 12.607c.159-1.98.561-3.898 2.08-5.701m5.148-3.29c2.006-.66 3.968-1.157 6.446-.844m5.202 2.98c1.192 1.275 1.963 2.163 2.594 3.815" style="font-variation-settings:normal" stroke="currentColor" stroke-linejoin="round"/><circle r=".989" cy="10.404" cx="14.746" fill="currentColor" stroke="none"/><circle cx="9.637" cy="11.305" r="1.477" fill="currentColor" stroke="none"/></svg>
{{- else if (eq .name "adobestock") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path style="font-variation-settings:normal" d="M2.235 2.235h19.53v19.53H2.235z"/><path style="font-variation-settings:normal" d="M6.165 16.659s3.16 1.2 4.602-.17c1.37-1.3.787-3.163-.754-4.05-1.68-.969-3.284-1.788-3.036-3.536.446-3.138 4.386-1.851 4.386-1.851M15.792 7.794v7.774c0 1.023.635 1.766 2.043 1.624M17.826 10.04h-3.582"/></svg>
{{- else if (eq .name "shutterstock") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect ry="5" rx="5" height="20" width="20" y="2" x="2"/><path d="M7.728 11.725V9.032c0-1.025.824-1.85 1.849-1.85h2.815m3.88 5.093v2.693a1.845 1.845 0 0 1-1.849 1.85h-2.815" stroke-linecap="square" stroke-linejoin="miter"/></svg>
{{- else if (eq .name "123rf") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path style="font-variation-settings:normal" d="M7.48 3.826c-.702 0-1.345.388-1.675 1.008l-.711 1.334a4.214 4.214 0 0 1-1.614 1.67l-.388.224a2.207 2.207 0 0 0-1.104 1.913v8.607c0 .878.712 1.592 1.59 1.592h1.186c.468 0 .916-.19 1.244-.524l1.478-1.504c.266-.27.628-.421 1.006-.421h7.04c.378 0 .74.151 1.005.421l1.478 1.504c.329.334.778.524 1.247.524h1.183c.879 0 1.592-.714 1.592-1.592V9.975c0-.79-.422-1.518-1.106-1.912l-.388-.225a4.214 4.214 0 0 1-1.613-1.67l-.711-1.334a1.899 1.899 0 0 0-1.676-1.008z" stroke-linejoin="miter"/><circle cx="12" cy="12.467" r="2.723"/></svg>
{{- else if (eq .name "dreamstime") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19.834 20.994s4.824-4.08 2.044-12.03C19.252 1.456 6.822-1.223 2.508 7.566c-3.936 8.023 2.18 14.46 7.88 14.374 4.889-.075 8.475-3.226 7.813-8.604-.76-6.18-6.73-6.816-9.275-4.184-2.256 2.334-1.816 7.034.873 7.823 2.241.844 4.661-1.265 3.161-3.215" style="font-variation-settings:normal" stroke="currentColor" stroke-linejoin="bevel" paint-order="stroke fill markers"/></svg>
{{- else if (eq .name "paypal") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.144 19.532l1.049-5.751c.11-.606.691-1.002 1.304-.948 2.155.192 6.877.1 8.818-4.002 2.554-5.397-.59-7.769-6.295-7.769H7.43a1.97 1.97 0 0 0-1.944 1.655L2.77 19.507a.857.857 0 0 0 .846.994h2.368a1.18 1.18 0 0 0 1.161-.969zM7.967 22.522a.74.74 0 0 0 .666.416h2.313c.492 0 .923-.351 1.003-.837l.759-4.601c.095-.523.597-.866 1.127-.819 1.86.166 5.567-.118 6.85-3.821.554-1.6.705-2.954.408-4.018" style="font-variation-settings:normal" stroke="currentColor" stroke-linejoin="miter"/></svg>
{{- else if (eq .name "qq") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path transform="scale(0.04) translate(75 40)" stroke-width="50" d="M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z"></path></svg>
{{- else if (eq .name "mastodon") -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather" width="24" height="24" viewBox="0 0 216.4144 232.00976"><path fill-rule="evenodd" fill="currentColor" d="M211.80734 139.0875c-3.18125 16.36625-28.4925 34.2775-57.5625 37.74875-15.15875 1.80875-30.08375 3.47125-45.99875 2.74125-26.0275-1.1925-46.565-6.2125-46.565-6.2125 0 2.53375.15625 4.94625.46875 7.2025 3.38375 25.68625 25.47 27.225 46.39125 27.9425 21.11625.7225 39.91875-5.20625 39.91875-5.20625l.8675 19.09s-14.77 7.93125-41.08125 9.39c-14.50875.7975-32.52375-.365-53.50625-5.91875C9.23234 213.82 1.40609 165.31125.20859 116.09125c-.365-14.61375-.14-28.39375-.14-39.91875 0-50.33 32.97625-65.0825 32.97625-65.0825C49.67234 3.45375 78.20359.2425 107.86484 0h.72875c29.66125.2425 58.21125 3.45375 74.8375 11.09 0 0 32.975 14.7525 32.975 65.0825 0 0 .41375 37.13375-4.59875 62.915 Z M177.50984 80.077v60.94125h-24.14375v-59.15c0-12.46875-5.24625-18.7975-15.74-18.7975-11.6025 0-17.4175 7.5075-17.4175 22.3525v32.37625H96.20734V85.42325c0-14.845-5.81625-22.3525-17.41875-22.3525-10.49375 0-15.74 6.32875-15.74 18.7975v59.15H38.90484V80.077c0-12.455 3.17125-22.3525 9.54125-29.675 6.56875-7.3225 15.17125-11.07625 25.85-11.07625 12.355 0 21.71125 4.74875 27.8975 14.2475l6.01375 10.08125 6.015-10.08125c6.185-9.49875 15.54125-14.2475 27.8975-14.2475 10.6775 0 19.28 3.75375 25.85 11.07625 6.36875 7.3225 9.54 17.22 9.54 29.675 Z"/></svg>
{{- else -}}
<svg xmlns="http://www.w3.org/2000/svg" class="feather feather-link" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
{{- end -}}

View file

@ -1,2 +0,0 @@
User-agent: *

31
package.json Normal file
View file

@ -0,0 +1,31 @@
{
"name": "@saibotk/saiblog",
"type": "module",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"lint": "eslint --ext .js,.cjs,.mjs,.ts,.cts,.mts,.tsx,.astro .",
"fix": "eslint --fix --ext .js,.cjs,.mjs,.ts,.cts,.mts,.tsx,.astro .",
"astro": "astro"
},
"dependencies": {
"@astrojs/mdx": "^0.11.4",
"@astrojs/rss": "^1.0.2",
"@astrojs/sitemap": "^1.0.0",
"@astrojs/tailwind": "^2.1.1",
"@clickbar/eslint-config-typescript": "^4.0.10",
"@fontsource/fira-code": "^4.5.12",
"@fontsource/inter": "^4.5.14",
"@tailwindcss/typography": "^0.5.7",
"astro": "^1.5.2",
"eslint": "^8.26.0",
"eslint-plugin-astro": "^0.20.0",
"prettier-plugin-astro": "^0.6.0",
"tailwindcss": "^3.2.1",
"typescript": "^4.8.4"
}
}

5604
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load diff

View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 636 B

After

Width:  |  Height:  |  Size: 636 B

View file

Before

Width:  |  Height:  |  Size: 911 B

After

Width:  |  Height:  |  Size: 911 B

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View file

Before

Width:  |  Height:  |  Size: 900 B

After

Width:  |  Height:  |  Size: 900 B

View file

Before

Width:  |  Height:  |  Size: 788 B

After

Width:  |  Height:  |  Size: 788 B

View file

@ -4,6 +4,6 @@
"config:base", "config:base",
"docker:enableMajor" "docker:enableMajor"
], ],
"prConcurrentLimit": 5, "prConcurrentLimit": 0,
"gitLabAutomerge": true "gitLabAutomerge": true
} }

View file

@ -0,0 +1,44 @@
---
// Import the global.css file here so that it is included on
// all pages through the use of the <BaseHead /> component.
import '../styles/global.css'
export interface Props {
title: string
description: string
image?: string
}
const { title, description, image = '/android-chrome-192x192.png' } = Astro.props
---
<!-- Global Metadata -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="mask-icon" href="safari-pinned-tab.svg" color="" />
<link rel="shortcut icon" href="favicon.ico" />
<meta name="generator" content={Astro.generator} />
<!-- Primary Meta Tags -->
<title>{title}</title>
<meta name="title" content={title} />
<meta name="description" content={description} />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={new URL(image, Astro.url)} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={Astro.url} />
<meta property="twitter:title" content={title} />
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={new URL(image, Astro.url)} />

View file

@ -0,0 +1,27 @@
---
import RSS from './icons/RSS.astro'
const today = new Date()
---
<footer class="mt-24 mb-24 w-full flex flex-col items-center text-zinc-400">
<div class="">
<span>&copy; {today.getFullYear()} saibotk</span>
<span>&#183;</span>
<a href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank" rel="noopener">
CC BY-NC 4.0
</a>
</div>
<div>
<div class="inline-block">
Made with <a href="https://astro.build/" target="_blank" rel="noopener">Astro</a>
</div>
<span>&#183;</span>
<a href="https://git.saibotk.de/saibotk.de/saiblog" target="_blank" rel="noopener">
Source Code
</a>
<span>&#183;</span>
<a href="/rss.xml" target="_blank" rel="noopener"><RSS class="w-4 inline-block" /></a>
</div>
</footer>

View file

@ -0,0 +1,44 @@
---
import { SITE_TITLE } from '../config'
import HeaderLink from './HeaderLink.astro'
import GitHub from './icons/GitHub.astro'
import Mastodon from './icons/Mastodon.astro'
import GitLab from './icons/GitLab.astro'
---
<header class="mt-8">
<h2 class="text-3xl font-semibold mb-2">
{SITE_TITLE}
</h2>
<nav class="gap-2 flex items-center">
<HeaderLink href="/">Home</HeaderLink>
<HeaderLink href="/posts">Posts</HeaderLink>
<div class="ml-auto space-x-2">
<a
class="inline-block hover:text-purple-600"
href="https://flausch.social/@saibotk"
target="_blank"
aria-label="Link to my Mastodon account"
>
<Mastodon class="w-6" />
</a>
<a
class="inline-block hover:text-purple-600"
href="https://git.saibotk.de/saibotk"
target="_blank"
aria-label="Link to my Gitlab account"
>
<GitLab class="w-6" />
</a>
<a
class="inline-block hover:text-purple-600"
href="https://github.com/saibotk"
target="_blank"
aria-label="Link to my GitHub account"
>
<GitHub class="w-6" />
</a>
</div>
</nav>
</header>

View file

@ -0,0 +1,28 @@
---
export type Props = astroHTML.JSX.AnchorHTMLAttributes
const { href, class: className, ...props } = Astro.props
const pathname = Astro.url.pathname
const isActive =
typeof href === 'string' && ((href !== '/' && pathname.startsWith(href)) || pathname === href)
---
<a
href={href}
class:list={[
'group inline-block relative text-zinc-50 px-4 rounded',
className,
{
'font-semibold bg-gradient-to-r from-purple-600 to-pink-400': isActive,
},
]}
{...props}
>
<div
class="absolute rounded inset-0 block opacity-0 group-hover:opacity-100 bg-gradient-to-r from-purple-900 to-purple-500 transition duration-200"
>
</div>
<div class="relative z-10">
<slot />
</div>
</a>

View file

@ -0,0 +1,19 @@
---
export type Props = astroHTML.JSX.SVGAttributes
const { class: classes, ...props } = Astro.props
---
<svg
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24"
class={classes}
aria-label="GitHub logo"
{...props}
><path
fill="currentColor"
fill-rule="evenodd"
d="M12 2C6.475 2 2 6.475 2 12a9.994 9.994 0 0 0 6.838 9.488c.5.087.687-.213.687-.476c0-.237-.013-1.024-.013-1.862c-2.512.463-3.162-.612-3.362-1.175c-.113-.288-.6-1.175-1.025-1.413c-.35-.187-.85-.65-.013-.662c.788-.013 1.35.725 1.538 1.025c.9 1.512 2.338 1.087 2.912.825c.088-.65.35-1.087.638-1.337c-2.225-.25-4.55-1.113-4.55-4.938c0-1.088.387-1.987 1.025-2.688c-.1-.25-.45-1.275.1-2.65c0 0 .837-.262 2.75 1.026a9.28 9.28 0 0 1 2.5-.338c.85 0 1.7.112 2.5.337c1.912-1.3 2.75-1.024 2.75-1.024c.55 1.375.2 2.4.1 2.65c.637.7 1.025 1.587 1.025 2.687c0 3.838-2.337 4.688-4.562 4.938c.362.312.675.912.675 1.85c0 1.337-.013 2.412-.013 2.75c0 .262.188.574.688.474A10.016 10.016 0 0 0 22 12c0-5.525-4.475-10-10-10Z"
></path>
</svg>

View file

@ -0,0 +1,18 @@
---
export type Props = astroHTML.JSX.SVGAttributes
const { class: classes, ...props } = Astro.props
---
<svg
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid meet"
viewBox="-2 -2.5 24 24"
class={classes}
aria-label="GitLab logo"
{...props}
><path
fill="currentColor"
d="M10.006 18.443L6.326 7.118h7.36l-3.68 11.325zm0 0L1.168 7.118h5.158l3.68 11.325zM1.168 7.118l8.838 11.325l-9.68-7.032a.762.762 0 0 1-.276-.852l1.118-3.441zm0 0L3.385.296a.38.38 0 0 1 .724 0l2.217 6.822H1.168zm8.838 11.325l3.68-11.325h5.157l-8.837 11.325zm8.837-11.325l1.119 3.441a.762.762 0 0 1-.277.852l-9.68 7.032l8.838-11.325zm0 0h-5.157L15.902.296a.38.38 0 0 1 .725 0l2.216 6.822z"
></path>
</svg>

View file

@ -0,0 +1,18 @@
---
export type Props = astroHTML.JSX.SVGAttributes
const { class: classes, ...props } = Astro.props
---
<svg
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24"
class={classes}
aria-label="Mastodon logo"
{...props}
><path
fill="currentColor"
d="M12.158 0c-3.068.025-6.02.357-7.74 1.147c0 0-3.41 1.526-3.41 6.733c0 1.192-.024 2.617.014 4.129c.123 5.091.933 10.11 5.64 11.355c2.171.575 4.035.695 5.535.613c2.722-.151 4.25-.972 4.25-.972l-.09-1.974s-1.945.613-4.13.538c-2.163-.074-4.448-.233-4.798-2.89a5.448 5.448 0 0 1-.048-.745s2.124.519 4.816.642c1.647.076 3.19-.096 4.759-.283c3.007-.36 5.625-2.212 5.954-3.905c.519-2.667.476-6.508.476-6.508c0-5.207-3.411-6.733-3.411-6.733C18.255.357 15.302.025 12.233 0h-.075ZM8.686 4.068c1.278 0 2.245.491 2.885 1.474l.622 1.043l.623-1.043c.64-.983 1.607-1.474 2.885-1.474c1.105 0 1.995.388 2.675 1.146c.658.757.986 1.781.986 3.07v6.303h-2.497V8.47c0-1.29-.543-1.945-1.628-1.945c-1.2 0-1.802.777-1.802 2.313v3.349h-2.483v-3.35c0-1.535-.601-2.312-1.802-2.312c-1.085 0-1.628.655-1.628 1.945v6.118H5.024V8.283c0-1.288.328-2.312.987-3.07c.68-.757 1.57-1.145 2.675-1.145Z"
></path>
</svg>

View file

@ -0,0 +1,18 @@
---
export type Props = astroHTML.JSX.SVGAttributes
const { class: classes, ...props } = Astro.props
---
<svg
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 256 256"
class={classes}
aria-label="RSS icon"
{...props}
><path
fill="currentColor"
d="M101.7 154.3A75.2 75.2 0 0 1 124 208a12 12 0 0 1-24 0a51.9 51.9 0 0 0-52-52a12 12 0 0 1 0-24a75.2 75.2 0 0 1 53.7 22.3ZM48 84a12 12 0 0 0 0 24a100 100 0 0 1 100 100a12 12 0 0 0 24 0A123.9 123.9 0 0 0 48 84Zm121.6 2.4A170.9 170.9 0 0 0 48 36a12 12 0 0 0 0 24a147.8 147.8 0 0 1 148 148a12 12 0 0 0 24 0a170.7 170.7 0 0 0-50.4-121.6ZM52 188a16 16 0 1 0 16 16a16 16 0 0 0-16-16Z"
></path>
</svg>

5
src/config.ts Normal file
View file

@ -0,0 +1,5 @@
// Place any global data in this file.
// You can import this data from anywhere in your site by using the `import` keyword.
export const SITE_TITLE = "Saibotk's blog"
export const SITE_DESCRIPTION = 'Welcome to my personal blog!'

1
src/environment.d.ts vendored Normal file
View file

@ -0,0 +1 @@
/// <reference types="astro/client" />

35
src/layouts/Base.astro Normal file
View file

@ -0,0 +1,35 @@
---
import '@fontsource/inter/variable-full.css'
import '@fontsource/fira-code'
import BaseHead from '../components/BaseHead.astro'
import Header from '../components/Header.astro'
import Footer from '../components/Footer.astro'
import { SITE_TITLE, SITE_DESCRIPTION } from '../config'
export interface Props {
pageTitle?: string
description?: string
}
const { pageTitle, description } = Astro.props
---
<!DOCTYPE html>
<html lang="en">
<head>
<BaseHead
title={((pageTitle && pageTitle + ' - ') || '') + SITE_TITLE}
description={(description && description) || SITE_DESCRIPTION}
/>
</head>
<body
class="font-sans bg-zinc-900 text-zinc-300 w-full max-w-3xl px-4 mx-auto min-h-screen flex flex-col"
>
<Header title={SITE_TITLE} />
<main class="grow flex flex-col my-4 mx-4">
<slot />
</main>
<Footer />
</body>
</html>

View file

@ -0,0 +1,43 @@
---
import Base from './Base.astro'
export interface Props {
content: {
title: string
description: string
pubDate?: string
updatedDate?: string
heroImage?: string
}
}
const {
content: { title, description, pubDate, updatedDate, heroImage },
} = Astro.props
---
<Base pageTitle={title} description={description}>
<article>
<div class="text-center">
<h1 class="mt-20 mb-2 text-5xl font-bold text-purple-400">{title}</h1>
{pubDate && <time class="text-base text-zinc-400">{pubDate}</time>}
{
updatedDate && (
<div class="text-sm italic font-thin text-zinc-400">
Last updated on <time>{updatedDate}</time>
</div>
)
}
</div>
{
heroImage && (
<img class="my-20 w-full rounded" src={heroImage} alt="hero image of the blog post" />
)
}
<div class="prose-custom">
<slot />
</div>
</article>
</Base>

16
src/pages/index.astro Normal file
View file

@ -0,0 +1,16 @@
---
import Base from '../layouts/Base.astro'
---
<Base>
<div class="flex flex-col justify-center items-center grow">
<div class="prose-custom">
<h1 class="text-center">⛵️ Welcome on board!</h1>
<p>
We will cross the ocean of my written posts. Join me on my journey and learn about various
things I encountered during my daily adventures. Mostly related to the far lands of
containerization & Ansible, Laravel, PHP and Vue.
</p>
</div>
</div>
</Base>

36
src/pages/posts.astro Normal file
View file

@ -0,0 +1,36 @@
---
import Base from '../layouts/Base.astro'
const rawPosts = await Astro.glob('./posts/*.{md,mdx}')
const posts = rawPosts
.filter((post) => !post.frontmatter.draft)
.sort(
(a, b) => new Date(b.frontmatter.pubDate).valueOf() - new Date(a.frontmatter.pubDate).valueOf()
)
---
<Base>
<section class="my-12">
<ul class="space-y-2">
{
posts.map((post) => (
<li class="flex">
<time
datetime={post.frontmatter.pubDate}
class="w-32 italic text-zinc-400 underline underline-offset-3"
>
{new Date(post.frontmatter.pubDate).toLocaleDateString('en-us', {
year: 'numeric',
month: 'short',
day: 'numeric',
})}
</time>
<a class="visited:text-purple-600 hover:text-purple-800" href={post.url}>
{post.frontmatter.title}
</a>
</li>
))
}
</ul>
</section>
</Base>

View file

@ -1,13 +1,8 @@
--- ---
layout: "../../layouts/BlogPost.astro"
title: "First Post" title: "First Post"
date: 2020-01-07T22:46:09+01:00 description: "The first introductory and obligatory post on a typical blog :)"
draft: false pubDate: "Jan 07 2020"
toc: false
images:
tags:
- welcome
- blog
- me
--- ---
## Hello and welcome on my blog ## Hello and welcome on my blog
@ -19,5 +14,5 @@ The purpose will be to present solutions / things I encounter during my
daily work and to hopefully give back some knowledge to other people, daily work and to hopefully give back some knowledge to other people,
who are looking for the same problems or are just generally interested in reading about it. who are looking for the same problems or are just generally interested in reading about it.
Thank you, Thank you,
saibotk saibotk

10
src/pages/rss.xml.ts Normal file
View file

@ -0,0 +1,10 @@
import rss from '@astrojs/rss'
import { SITE_TITLE, SITE_DESCRIPTION } from '../config'
export const get = () =>
rss({
title: SITE_TITLE,
description: SITE_DESCRIPTION,
site: import.meta.env.SITE,
items: import.meta.glob('./posts/**/*.{md,mdx}'),
})

15
src/styles/global.css Normal file
View file

@ -0,0 +1,15 @@
html {
@apply font-sans bg-zinc-900 text-zinc-300 w-full max-w-3xl mx-auto;
}
.prose-custom {
@apply prose prose-invert max-w-full;
}
.prose-custom code {
@apply font-code;
}
.prose-custom :not(pre) code {
@apply before:hidden after:hidden bg-zinc-700 p-0.5 px-1 inline rounded-sm;
}

16
tailwind.config.cjs Normal file
View file

@ -0,0 +1,16 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const defaultTheme = require('tailwindcss/defaultTheme')
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {
fontFamily: {
sans: ['InterVariable', ...defaultTheme.fontFamily.sans],
code: ['Fira Code', ...defaultTheme.fontFamily.mono],
},
},
},
plugins: [require('@tailwindcss/typography')],
}

@ -1 +0,0 @@
Subproject commit 2dc35c5c6a52168a3a7b35c5ad51209f40a851cf

3
tsconfig.json Normal file
View file

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