forked from swablab/website
Compare commits
34 commits
Author | SHA1 | Date | |
---|---|---|---|
29a6b544ad | |||
131df9f7e1 | |||
a954265409 | |||
d79a1528b2 | |||
0f02f367f5 | |||
8dabfd9645 | |||
4211805918 | |||
9e3ad0422b | |||
25dea7ff29 | |||
307785d019 | |||
c0e4c8d190 | |||
747d9fc9f7 | |||
340d6d4919 | |||
dcaad109ab | |||
a1f9272c50 | |||
4830cebc70 | |||
4cb8cad25b | |||
498c07ce66 | |||
3cfa61aa2b | |||
d172a0174a | |||
c2eb1b0d95 | |||
999ba5dbdf | |||
1379a30dcd | |||
4d06f859a8 | |||
889bbbb804 | |||
835921e73c | |||
b3568b7da4 | |||
34c7cb683a | |||
1183b6eedf | |||
2c90068506 | |||
d00b773aa3 | |||
1cfc0a44e6 | |||
5fab71837a | |||
980b3fc204 |
35 changed files with 6762 additions and 3703 deletions
|
@ -2,13 +2,13 @@
|
|||
"name": "swabsite",
|
||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers-community/features/deno": {}
|
||||
"ghcr.io/devcontainers/features/node": {}
|
||||
},
|
||||
"containerUser": "vscode",
|
||||
"containerEnv": {
|
||||
"ASTRO_TELEMETRY_DISABLED": "true"
|
||||
},
|
||||
"postStartCommand": "deno task install",
|
||||
"postStartCommand": "npm install",
|
||||
"runArgs": ["--userns=keep-id", "--security-opt=label=disable"],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
|
|
34
.forgejo/workflows/deploy.yml
Normal file
34
.forgejo/workflows/deploy.yml
Normal file
|
@ -0,0 +1,34 @@
|
|||
name: deploy
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
repo: website
|
||||
git: git.swablab.de
|
||||
url: git.swablab.de/${{ github.repository }}
|
||||
token: ${{ secrets.SWABLAB_ORGA_PACKAGE_TOKEN }}
|
||||
ASTRO_TELEMETRY_DISABLED: true
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: deploy
|
||||
runs-on: docker
|
||||
container:
|
||||
image: quay.io/buildah/stable:latest
|
||||
env:
|
||||
STORAGE_DRIVER: vfs
|
||||
steps:
|
||||
- name: download
|
||||
run: curl https://${{ env.url }}/archive/main.tar.gz | tar -xz
|
||||
|
||||
- name: build
|
||||
run: buildah build -f ${{ env.repo }}/Containerfile -t ${{ env.url }}:latest ${{ env.repo }}
|
||||
|
||||
- name: login
|
||||
run: buildah login -u token -p ${{ env.token }} ${{ env.git }}
|
||||
|
||||
- name: push
|
||||
run: buildah push ${{ env.git }}/${{ github.repository }}:latest
|
|
@ -1,53 +0,0 @@
|
|||
name: Build Astro
|
||||
on: [push, workflow_dispatch]
|
||||
|
||||
env:
|
||||
ASTRO_TELEMETRY_DISABLED: true
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: 🧪 Astro check
|
||||
runs-on: docker
|
||||
container:
|
||||
image: node:lts
|
||||
steps:
|
||||
- uses: https://github.com/actions/checkout@v4
|
||||
- uses: https://github.com/denoland/setup-deno@v2
|
||||
with:
|
||||
deno-version: v2.x
|
||||
- run: deno task install
|
||||
- run: deno task check
|
||||
|
||||
deploy:
|
||||
name: 🚢 Deploy
|
||||
runs-on: docker
|
||||
container:
|
||||
image: node:lts
|
||||
if: github.ref == 'refs/heads/main'
|
||||
needs: [check]
|
||||
steps:
|
||||
- uses: https://github.com/actions/checkout@v4
|
||||
|
||||
- uses: https://github.com/denoland/setup-deno@v2
|
||||
with:
|
||||
deno-version: v2.x
|
||||
- run: deno task install
|
||||
- run: deno task build
|
||||
|
||||
- name: build containerfile
|
||||
id: build-image
|
||||
uses: https://github.com/redhat-actions/buildah-build@v2
|
||||
with:
|
||||
image: website
|
||||
tags: latest
|
||||
containerfiles: |
|
||||
./Containerfile
|
||||
|
||||
- name: Push to registry
|
||||
uses: https://github.com/redhat-actions/push-to-registry@v2
|
||||
with:
|
||||
image: ${{ steps.build-image.outputs.image }}
|
||||
tags: ${{ steps.build-image.outputs.tags }}
|
||||
username: token
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
registry: ${{ github.server_url }}/${{ github.repository }}
|
5
.vscode/extensions.json
vendored
5
.vscode/extensions.json
vendored
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"astro-build.astro-vscode",
|
||||
"denoland.vscode-deno"
|
||||
"astro-build.astro-vscode"
|
||||
]
|
||||
}
|
||||
}
|
24
.vscode/tasks.json
vendored
24
.vscode/tasks.json
vendored
|
@ -2,35 +2,43 @@
|
|||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "install/update",
|
||||
"command": "deno task install",
|
||||
"label": "install",
|
||||
"command": "npm install",
|
||||
"type": "shell",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "update",
|
||||
"command": "npm update -S",
|
||||
"type": "shell",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "dev",
|
||||
"command": "deno task dev",
|
||||
"command": "npm run dev",
|
||||
"type": "shell",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "check",
|
||||
"command": "deno task check",
|
||||
"command": "npm run check",
|
||||
"type": "shell",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "preview",
|
||||
"command": "deno task preview",
|
||||
"command": "npm run preview",
|
||||
"type": "shell",
|
||||
"problemMatcher": [],
|
||||
"dependsOn": ["build"]
|
||||
"dependsOn": [
|
||||
"build"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "build",
|
||||
"command": "deno task build",
|
||||
"command": "npm run build",
|
||||
"type": "shell",
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,6 +1,13 @@
|
|||
FROM ghcr.io/swablab/documents:latest AS documents
|
||||
FROM docker.io/library/node AS build
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
ENV ASTRO_TELEMETRY_DISABLED=true
|
||||
RUN npm install
|
||||
RUN npm run build
|
||||
|
||||
FROM docker.io/nginxinc/nginx-unprivileged:latest
|
||||
FROM git.swablab.de/swablab/documents AS documents
|
||||
|
||||
FROM docker.io/nginxinc/nginx-unprivileged
|
||||
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY ./dist /usr/share/nginx/html
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
COPY --from=documents / /usr/share/nginx/html/docs
|
16
README.md
16
README.md
|
@ -1,16 +0,0 @@
|
|||
# swablab.de
|
||||
|
||||
[](https://github.com/swablab/website/actions/workflows/main.yml)
|
||||
|
||||
These are the source files for the page published at https://swablab.de.
|
||||
|
||||
Powered by [Astro](https://astro.build)
|
||||
|
||||
# Installation
|
||||
|
||||
We recommend [deno](https://deno.com/) as the package manager. To install all
|
||||
required packages, execute `deno task install`.
|
||||
|
||||
Afterwards, you can develop with `deno task dev` and build with
|
||||
`deno task build`. It is recommended to use VSCode as your editor, as all tasks
|
||||
can be executed easily within VSCode.
|
|
@ -1,5 +1,5 @@
|
|||
import sitemap from "@astrojs/sitemap"
|
||||
import tailwind from "@astrojs/tailwind"
|
||||
import tailwindcss from "@tailwindcss/vite"
|
||||
import { defineConfig, passthroughImageService } from "astro/config"
|
||||
|
||||
export default defineConfig({
|
||||
|
@ -8,9 +8,14 @@ export default defineConfig({
|
|||
server: {
|
||||
host: true,
|
||||
},
|
||||
integrations: [tailwind(), sitemap()],
|
||||
integrations: [sitemap()],
|
||||
image: {
|
||||
domains: ["directus.swablab.de", "files.mastodon.social"],
|
||||
service: passthroughImageService(),
|
||||
},
|
||||
vite: {
|
||||
plugins: [
|
||||
tailwindcss(),
|
||||
],
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"fmt": {
|
||||
"options": {
|
||||
"semiColons": false,
|
||||
"indentWidth": 2
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,8 +17,11 @@ server {
|
|||
internal;
|
||||
}
|
||||
|
||||
location /todo {
|
||||
return 302 https://directus.swablab.de/admin/content/tasks_general;
|
||||
}
|
||||
location /discord {
|
||||
return 301 https://discord.gg/sZbmJdGkMQ;
|
||||
return 302 https://discord.gg/A4grfc5Vzm;
|
||||
}
|
||||
|
||||
location / {
|
||||
|
|
6536
package-lock.json
generated
Normal file
6536
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
24
package.json
24
package.json
|
@ -2,7 +2,6 @@
|
|||
"name": "@swablab/website",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"install": "deno install -q",
|
||||
"check": "astro check",
|
||||
"dev": "astro dev",
|
||||
"build": "astro build",
|
||||
|
@ -10,22 +9,19 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/check": "^0.9.4",
|
||||
"@astrojs/sitemap": "^3.2.1",
|
||||
"@astrojs/tailwind": "^5.1.3",
|
||||
"@fontsource-variable/ubuntu-sans": "^5.1.0",
|
||||
"@iconify-json/ph": "^1.2.1",
|
||||
"@iconify/tailwind": "^1.1.3",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"@types/alpinejs": "^3.13.11",
|
||||
"alpinejs": "^3.14.6",
|
||||
"astro": "^5.0.3",
|
||||
"daisyui": "^4.12.14",
|
||||
"tailwindcss": "^3.4.16",
|
||||
"typescript": "^5.7.2"
|
||||
"@astrojs/sitemap": "^3.3.0",
|
||||
"@fontsource-variable/ubuntu-sans": "^5.2.6",
|
||||
"@iconify-json/ph": "^1.2.2",
|
||||
"@iconify/tailwind4": "^1.0.6",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@tailwindcss/vite": "^4.0.15",
|
||||
"astro": "^5.5.4",
|
||||
"daisyui": "^5.0.9",
|
||||
"tailwindcss": "^4.0.14"
|
||||
},
|
||||
"prettier": {
|
||||
"tabWidth": 2,
|
||||
"semi": false,
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"data": {
|
||||
"id": "user1"
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"data": {
|
||||
"id": 1,
|
||||
"last": "2024-05-08T18:00:00",
|
||||
"next": "2024-05-08T18:00:00"
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"data": {
|
||||
"id": "task",
|
||||
"status": "in_progress",
|
||||
"title": "title 1",
|
||||
"date_due": "2024-01-01T12:00:00",
|
||||
"labels": [
|
||||
"label1"
|
||||
],
|
||||
"description": "description 1",
|
||||
"priority": "high",
|
||||
"responsibles": [
|
||||
{
|
||||
"directus_users_id": {
|
||||
"id": "user1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"directus_users_id": {
|
||||
"id": "user2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
{
|
||||
"data": [
|
||||
{
|
||||
"id": "task",
|
||||
"status": "in_progress",
|
||||
"title": "title1",
|
||||
"date_due": "2024-01-01T12:00:00",
|
||||
"labels": [
|
||||
"label1"
|
||||
],
|
||||
"description": "description1",
|
||||
"priority": "high",
|
||||
"responsibles": [
|
||||
{
|
||||
"directus_users_id": {
|
||||
"id": "user1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"directus_users_id": {
|
||||
"id": "user2"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "task",
|
||||
"status": "in_progress",
|
||||
"title": "title2",
|
||||
"date_due": null,
|
||||
"labels": [],
|
||||
"description": "description2",
|
||||
"priority": "medium",
|
||||
"responsibles": []
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"data": [
|
||||
{
|
||||
"id": "user1",
|
||||
"first_name": "first_name1"
|
||||
},
|
||||
{
|
||||
"id": "user2",
|
||||
"first_name": "first_name2"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -34,7 +34,7 @@ const { name, image, link, small } = Astro.props
|
|||
<span class="card-title">{name}</span>
|
||||
)
|
||||
}
|
||||
<p>
|
||||
<p class="text-lg">
|
||||
<slot />
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -71,7 +71,7 @@ function replaceEmojis(content: string) {
|
|||
</figure>
|
||||
)}
|
||||
|
||||
<div class="card-body text-left">
|
||||
<div class="card-body text-left text-lg">
|
||||
<h2 class="card-title justify-between">
|
||||
<a href={post.url}>@swablab</a>
|
||||
<time class="text-xs opacity-50">
|
||||
|
|
|
@ -5,6 +5,7 @@ import DirectusImg from "./DirectusImg.astro"
|
|||
type Member = {
|
||||
firstname: string
|
||||
image?: string
|
||||
chairman?: boolean
|
||||
}
|
||||
const members = await directus<Member[]>("items/members?sort=firstname")
|
||||
---
|
||||
|
@ -24,27 +25,59 @@ const members = await directus<Member[]>("items/members?sort=firstname")
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-2xl md:text-4xl pt-8">Vorstand</div>
|
||||
|
||||
<div
|
||||
class="flex flex-row flex-wrap gap-6 justify-evenly sm:justify-center text-base pt-8"
|
||||
class="flex flex-row flex-wrap gap-6 justify-evenly sm:justify-center text-base"
|
||||
>
|
||||
{
|
||||
members.map((member) => (
|
||||
<div>
|
||||
<DirectusImg
|
||||
src={
|
||||
member.image != null
|
||||
? member.image
|
||||
: "a8f48962-9f0e-40e6-abd2-e932aa9dea2e"
|
||||
}
|
||||
widths={[200]}
|
||||
format="webp"
|
||||
alt={"Profilbild von " + member.firstname}
|
||||
class="rounded-full w-[100px] h-[100px]"
|
||||
/>
|
||||
members
|
||||
.filter((m) => m.chairman)
|
||||
.map((member) => (
|
||||
<div>
|
||||
<DirectusImg
|
||||
src={
|
||||
member.image != null
|
||||
? member.image
|
||||
: "a8f48962-9f0e-40e6-abd2-e932aa9dea2e"
|
||||
}
|
||||
widths={[200]}
|
||||
format="webp"
|
||||
alt={"Profilbild von " + member.firstname}
|
||||
class="rounded-full w-[100px] h-[100px]"
|
||||
/>
|
||||
|
||||
<p>{member.firstname}</p>
|
||||
</div>
|
||||
))
|
||||
<p>{member.firstname}</p>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="text-2xl md:text-4xl pt-8">Mitglieder</div>
|
||||
|
||||
<div
|
||||
class="flex flex-row flex-wrap gap-6 justify-evenly sm:justify-center text-base"
|
||||
>
|
||||
{
|
||||
members
|
||||
.filter((m) => !m.chairman)
|
||||
.map((member) => (
|
||||
<div>
|
||||
<DirectusImg
|
||||
src={
|
||||
member.image != null
|
||||
? member.image
|
||||
: "a8f48962-9f0e-40e6-abd2-e932aa9dea2e"
|
||||
}
|
||||
widths={[200]}
|
||||
format="webp"
|
||||
alt={"Profilbild von " + member.firstname}
|
||||
class="rounded-full w-[100px] h-[100px]"
|
||||
/>
|
||||
|
||||
<p>{member.firstname}</p>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
|
||||
<div>
|
||||
|
|
|
@ -7,7 +7,7 @@ const { title, jumpId }: Props = Astro.props
|
|||
---
|
||||
|
||||
<div class="text-center p-8 space-y-8 even:bg-base-200">
|
||||
<a hidden class="block invisible relative -top-20" id={jumpId}></a>
|
||||
<a class="invisible relative -top-24" id={jumpId}></a>
|
||||
<div class="text-3xl md:text-5xl">
|
||||
<a href={"#" + jumpId}>{title}</a>
|
||||
</div>
|
||||
|
|
|
@ -1,33 +1,7 @@
|
|||
const env = (import.meta as unknown as {
|
||||
env: {
|
||||
DEV: boolean
|
||||
SSR: boolean
|
||||
}
|
||||
}).env
|
||||
|
||||
export async function directus<T>(
|
||||
path: string,
|
||||
method: string = "GET",
|
||||
body: string | null = null,
|
||||
): Promise<T> {
|
||||
return await fetch(
|
||||
env.DEV && !env.SSR
|
||||
? `/test/${path.split("/").at(-1)}`
|
||||
: `https://directus.swablab.de/${path}`,
|
||||
{
|
||||
method,
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body,
|
||||
},
|
||||
)
|
||||
export async function directus<T>(path: string): Promise<T> {
|
||||
return await fetch(`https://directus.swablab.de/${path}`)
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
if (res.errors) throw res.errors[0].message
|
||||
return res.data
|
||||
})
|
||||
.then((res) => res.data)
|
||||
}
|
||||
|
||||
export function formatDate(
|
||||
|
@ -58,18 +32,3 @@ export const documents = {
|
|||
"Werkstatt-AGB": "/docs/werkstatt-agb.pdf",
|
||||
"Werkstatt-Regeln": "/docs/werkstatt-regeln.pdf",
|
||||
}
|
||||
|
||||
export type Task = {
|
||||
id: string | undefined
|
||||
title: string
|
||||
status: string
|
||||
date_due?: string
|
||||
priority: string
|
||||
description: string
|
||||
responsibles: {
|
||||
directus_users_id: {
|
||||
id: string
|
||||
first_name: string
|
||||
}
|
||||
}[]
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
---
|
||||
import "../style.css";
|
||||
import "../style.css"
|
||||
|
||||
export interface Props {
|
||||
title?: string;
|
||||
description?: string;
|
||||
title?: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
const { title } = Astro.props;
|
||||
const { title } = Astro.props
|
||||
|
||||
const titleFull = title == null ? "swablab e.V." : title + " | swablab e.V.";
|
||||
const titleFull = title == null ? "swablab e.V." : title + " | swablab e.V."
|
||||
const description =
|
||||
"swablab e.V. in Freudenstadt - die offene Werkstatt für alle ambitionierten Hobby-Schreiner, Bastler, Tüftler, Elektroniker und vieles mehr.";
|
||||
"swablab e.V. in Freudenstadt - die offene Werkstatt für alle ambitionierten Hobby-Schreiner, Bastler, Tüftler, Elektroniker und vieles mehr."
|
||||
---
|
||||
|
||||
<html lang="de-DE" class="scroll-smooth">
|
||||
|
@ -29,13 +29,6 @@ const description =
|
|||
<title>{titleFull}</title>
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
|
||||
<script
|
||||
is:inline
|
||||
defer
|
||||
data-domain="swablab.de"
|
||||
src="https://analytics.swablab.de/js/plausible.outbound-links.js"
|
||||
></script>
|
||||
</head>
|
||||
<body class="min-h-screen flex flex-col">
|
||||
<slot />
|
||||
|
|
|
@ -28,9 +28,9 @@ const social = [
|
|||
"https://www.printables.com/social/103546-swablab-ev/about",
|
||||
),
|
||||
entry(
|
||||
"GitHub",
|
||||
"icon-[ph--github-logo-duotone]",
|
||||
"https://github.com/swablab",
|
||||
"Forgejo",
|
||||
"icon-[ph--git-branch]",
|
||||
"https://git.swablab.de/explore/repos",
|
||||
),
|
||||
]
|
||||
|
||||
|
|
|
@ -14,10 +14,14 @@ const links = [
|
|||
|
||||
<nav class="fixed top-0 navbar z-30 glass bg-base-100/30">
|
||||
<div class="navbar-start">
|
||||
<a class="btn btn-ghost text-xl font-normal" href="/">
|
||||
<img class="w-8 h-8" src="/logo.svg" alt="swablab logo" />
|
||||
<span>swablab</span></a
|
||||
>
|
||||
<ul class="menu menu-horizontal p-0">
|
||||
<li>
|
||||
<a class="text-xl" href="/">
|
||||
<img class="w-8 h-8" src="/logo.svg" alt="" />
|
||||
<span>swablab</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="navbar-center hidden lg:flex">
|
||||
<ul class="menu menu-horizontal p-0">
|
||||
|
@ -34,6 +38,12 @@ const links = [
|
|||
</li>
|
||||
))
|
||||
}
|
||||
<li>
|
||||
<a class="text-black bg-primary" href="https://wiki.swablab.de">
|
||||
<span class="w-5 h-5 icon-[ph--notebook-duotone]"></span>
|
||||
wiki
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
|
@ -50,6 +60,12 @@ const links = [
|
|||
</li>
|
||||
))
|
||||
}
|
||||
<li>
|
||||
<a class="text-primary" href="https://wiki.swablab.de">
|
||||
<span class="w-5 h-5 icon-[ph--notebook-duotone]"></span>
|
||||
wiki
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<div id="presence" class="hidden">
|
||||
<div class="md:hidden">
|
||||
<div class="xl:hidden">
|
||||
<div class="tooltip tooltip-left">
|
||||
<button class="btn btn-square font-normal">
|
||||
<button class="btn btn-square">
|
||||
<span class="icon-[ph--door-open-duotone] w-6 h-6"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden md:flex">
|
||||
<button class="btn font-normal">
|
||||
<div class="hidden xl:flex">
|
||||
<button class="btn">
|
||||
<span id="presence-text"></span>
|
||||
<span class="icon-[ph--door-open-duotone] w-6 h-6"></span>
|
||||
</button>
|
||||
|
|
|
@ -82,7 +82,7 @@ import Page from "../layouts/Page.astro"
|
|||
],
|
||||
[
|
||||
"Sommer 2024",
|
||||
`Neben unserem Instagram-Account werden jetzt Neuigkeiten und Projekte auch auf Mastodon (@swablab) geposted.`,
|
||||
`Neben unserem Instagram-Account werden jetzt Neuigkeiten und Projekte auch auf Mastodon (@swablab@mastodon.social) geposted.`,
|
||||
],
|
||||
[
|
||||
"Herbst 2024",
|
||||
|
|
|
@ -14,11 +14,11 @@ import Page from "../layouts/Page.astro"
|
|||
kannst du an folgendes Konto deinen Spendenbeitrag überweisen:
|
||||
</Text>
|
||||
|
||||
<div class="stats shadow">
|
||||
<div class="stats shadow bg-base-300">
|
||||
<div class="stat">
|
||||
<div class="stat-title">IBAN: DE18 6039 1310 0125 6340 05</div>
|
||||
<div class="stat-title">BIC: GENODES1VBH</div>
|
||||
<div class="stat-title">Bank: Volksbank in der Region</div>
|
||||
<div class="stat-title text-xl">IBAN: DE18 6039 1310 0125 6340 05</div>
|
||||
<div class="stat-title text-xl">BIC: GENODES1VBH</div>
|
||||
<div class="stat-title text-xl">Bank: Volksbank in der Region</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@ Telefon: [+49 15679 232971](tel:+4915679232971)
|
|||
|
||||
**Vertreten durch**\
|
||||
Fabian Haas\
|
||||
Manuel Knodel
|
||||
Manuel Knodel\
|
||||
Bastian Wittke
|
||||
|
||||
**Registereintrag**\
|
||||
Amtsgericht Stuttgart\
|
||||
|
|
|
@ -24,11 +24,11 @@ import Page from "../layouts/Page.astro"
|
|||
oder ihn an folgende Adresse schicken:
|
||||
</Text>
|
||||
|
||||
<div class="stats shadow">
|
||||
<div class="stats shadow bg-base-300">
|
||||
<div class="stat">
|
||||
<div class="stat-value">swablab e.V.</div>
|
||||
<div class="stat-title">Katharinenstr. 1</div>
|
||||
<div class="stat-title">72250 Freudenstadt</div>
|
||||
<div class="stat-title text-xl">Katharinenstr. 1</div>
|
||||
<div class="stat-title text-xl">72250 Freudenstadt</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
|
|
|
@ -1,207 +0,0 @@
|
|||
---
|
||||
import Base from "../layouts/Base.astro"
|
||||
|
||||
const statuses = [
|
||||
{ id: "not_started", title: "Nicht gestartet" },
|
||||
{ id: "in_progress", title: "In Arbeit" },
|
||||
{ id: "hold", title: "Wartend" },
|
||||
{ id: "done", title: "Abgeschlossen" },
|
||||
]
|
||||
const priorities = [
|
||||
{ id: "low", title: "Niedrig" },
|
||||
{ id: "normal", title: "Normal" },
|
||||
{ id: "high", title: "Hoch" },
|
||||
]
|
||||
---
|
||||
|
||||
<Base title="Todo">
|
||||
<div x-data="task" x-cloak>
|
||||
<div class="navbar glass">
|
||||
<div class="navbar-start">
|
||||
<a class="btn btn-ghost text-xl">todo</a>
|
||||
</div>
|
||||
<div class="navbar-end space-x-2">
|
||||
<a class="btn btn-success btn-square" x-on:click="submit()">
|
||||
<span class="icon-[ph--floppy-disk] w-6 h-6"></span>
|
||||
</a>
|
||||
<a class="btn btn-error btn-square" href="/todo">
|
||||
<span class="icon-[ph--x] w-6 h-6"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div x-show="error" class="p-4 flex flex-col space-y-4">
|
||||
<div
|
||||
x-show="!error.includes('permission to access collection')"
|
||||
class="alert alert-error"
|
||||
>
|
||||
<span x-text="error"></span>
|
||||
</div>
|
||||
<a
|
||||
x-show="error.includes('permission to access collection')"
|
||||
class="btn btn-primary"
|
||||
href="https://directus.swablab.de/auth/login/zitadel?redirect=https://swablab.de/todo"
|
||||
>
|
||||
Klicke hier, um dich anzumelden
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="drawer">
|
||||
<input id="drawer" type="checkbox" class="drawer-toggle" />
|
||||
|
||||
<div class="drawer-content">
|
||||
<div class="p-4 grid md:grid-cols-3 gap-4">
|
||||
<input x-model="title" class="input input-bordered md:col-span-3" />
|
||||
|
||||
<label class="form-control">
|
||||
<div class="label">Status</div>
|
||||
<select x-model="status" class="select select-bordered">
|
||||
{
|
||||
statuses.map((status) => (
|
||||
<option value={status.id}>{status.title}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
<div class="label">Priorität</div>
|
||||
<select x-model="priority" class="select select-bordered">
|
||||
{
|
||||
priorities.map((prio) => (
|
||||
<option value={prio.id}>{prio.title}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
<div class="label">Fälligkeitdatum</div>
|
||||
<input
|
||||
x-model="date_due"
|
||||
class="input input-bordered"
|
||||
type="date"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<div class="form-control md:col-span-3">
|
||||
<div class="label space-x-2 justify-start">
|
||||
<span>Verantwortliche</span>
|
||||
<label for="drawer" class="btn btn-sm btn-primary btn-square">
|
||||
+
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex space-x-2">
|
||||
<template x-for="res in responsibles">
|
||||
<button
|
||||
class="btn"
|
||||
x-on:click="responsibles = responsibles.filter(x => x != res)"
|
||||
x-text="users.find(u => u.id == res)?.first_name ?? res"
|
||||
>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label class="form-control md:col-span-3 h-64">
|
||||
<div class="label">Beschreibung</div>
|
||||
<textarea
|
||||
x-model="description"
|
||||
class="textarea textarea-bordered md:col-span-3 h-64"
|
||||
>
|
||||
</textarea>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="drawer-side">
|
||||
<label for="drawer" class="drawer-overlay"></label>
|
||||
<ul class="menu p-4 w-80 min-h-full bg-base-200 text-base-content">
|
||||
<template x-for="user in users">
|
||||
<li>
|
||||
<a
|
||||
x-on:click="responsibles.indexOf(user.id) == -1 && responsibles.push(user.id)"
|
||||
x-text="user.first_name"
|
||||
>
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Base>
|
||||
|
||||
<script>
|
||||
import Alpine from "alpinejs"
|
||||
import { directus, Task } from "../helper"
|
||||
|
||||
Alpine.data("task", () => ({
|
||||
id: globalThis.location.search.replace("?", ""),
|
||||
title: "",
|
||||
status: "not_started",
|
||||
date_due: "",
|
||||
priority: "normal",
|
||||
description: "",
|
||||
responsibles: [],
|
||||
|
||||
users: [],
|
||||
error: "",
|
||||
|
||||
init() {
|
||||
directus<{ id: string; first_name: string }[]>(
|
||||
`users?fields=id,first_name&filter[provider][_neq]=default`,
|
||||
).then(
|
||||
(res) =>
|
||||
(this.users = res.sort((a, b) =>
|
||||
a.first_name.localeCompare(b.first_name),
|
||||
)),
|
||||
)
|
||||
|
||||
if (this.id != "") {
|
||||
directus<Task>(
|
||||
`items/tasks_general/${this.id}?fields=*,responsibles.directus_users_id.id`,
|
||||
)
|
||||
.then((res) => {
|
||||
this.title = res.title
|
||||
this.status = res.status
|
||||
this.date_due = res.date_due?.substring(0, 10) ?? ""
|
||||
this.priority = res.priority
|
||||
this.description = res.description
|
||||
this.responsibles = res.responsibles.map(
|
||||
(x) => x.directus_users_id.id,
|
||||
)
|
||||
})
|
||||
.catch((err) => (this.error = err))
|
||||
}
|
||||
},
|
||||
submit() {
|
||||
const task = {
|
||||
id: this.id,
|
||||
title: this.title,
|
||||
status: this.status,
|
||||
date_due: this.date_due != "" ? this.date_due : null,
|
||||
priority: this.priority,
|
||||
description: this.description,
|
||||
responsibles: this.responsibles.map(
|
||||
(r: { directus_users_id: string }) => ({
|
||||
directus_users_id: r,
|
||||
}),
|
||||
),
|
||||
}
|
||||
if (this.id != "") {
|
||||
directus(
|
||||
`items/tasks_general/${this.id}`,
|
||||
"PATCH",
|
||||
JSON.stringify(task),
|
||||
).then((_) => (document.location.href = "/todo"))
|
||||
} else {
|
||||
directus(`items/tasks_general`, "POST", JSON.stringify(task)).then(
|
||||
(_) => (document.location.href = "/todo"),
|
||||
)
|
||||
}
|
||||
},
|
||||
}))
|
||||
|
||||
Alpine.start()
|
||||
</script>
|
|
@ -1,133 +0,0 @@
|
|||
---
|
||||
import Base from "../layouts/Base.astro"
|
||||
|
||||
const statuses = [
|
||||
{ id: "not_started", title: "Nicht gestartet" },
|
||||
{ id: "in_progress", title: "In Arbeit" },
|
||||
{ id: "hold", title: "Wartend" },
|
||||
]
|
||||
---
|
||||
|
||||
<Base title="Todo">
|
||||
<div x-data="kanban" x-cloak>
|
||||
<div class="navbar glass">
|
||||
<div class="navbar-start">
|
||||
<a class="btn btn-ghost text-xl">todo</a>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
<a class="btn btn-primary btn-square" href="/todo-edit">
|
||||
<span class="icon-[ph--plus] w-6 h-6"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div x-show="error" class="p-4 flex flex-col space-y-4">
|
||||
<div
|
||||
x-show="!error.includes('permission to access collection')"
|
||||
class="alert alert-error"
|
||||
>
|
||||
<span x-text="error"></span>
|
||||
</div>
|
||||
<a
|
||||
x-show="error.includes('permission to access collection')"
|
||||
class="btn btn-primary"
|
||||
href="https://directus.swablab.de/auth/login/zitadel?redirect=https://swablab.de/todo"
|
||||
>
|
||||
Klicke hier, um dich anzumelden
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="p-4 flex flex-col space-y-2" x-show="!error">
|
||||
<div class="join">
|
||||
<input
|
||||
class="input input-primary w-full join-item"
|
||||
placeholder="Suchen nach Titel oder Mitglied..."
|
||||
x-model="search"
|
||||
/>
|
||||
<button
|
||||
class="btn btn-primary join-item"
|
||||
x-on:click="search = `id:${me}`"
|
||||
>
|
||||
Nur meine Aufgaben
|
||||
</button>
|
||||
</div>
|
||||
<ul class="menu grid lg:grid-cols-3 w-full bg-base-200 rounded-box">
|
||||
{
|
||||
statuses.map((status) => (
|
||||
<li x-data={"tasklist('" + status.id + "')"} class="flex-auto">
|
||||
<a class="pointer-events-none">{status.title}</a>
|
||||
<ul>
|
||||
<template x-for="task in sortedTasks()">
|
||||
<li>
|
||||
<a x-bind:href="`/todo-edit?${task.id}`">
|
||||
<span
|
||||
x-show="task.responsibles.find(x => x.directus_users_id.id == me)"
|
||||
class="badge badge-xs badge-info"
|
||||
/>
|
||||
<span
|
||||
x-bind:class="{'text-secondary': task.priority == 'high','text-neutral-500': task.priority == 'low'}"
|
||||
x-text="task.title"
|
||||
/>
|
||||
<span
|
||||
class="badge badge-xs"
|
||||
x-bind:class="new Date(task.date_due ?? 0) < new Date() ? `badge-error`: `badge-ghost`"
|
||||
x-show="task.date_due != null"
|
||||
x-text="formatDate(task.date_due, `short`)"
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</Base>
|
||||
|
||||
<script>
|
||||
import Alpine from "alpinejs"
|
||||
import { directus, formatDate, Task } from "../helper"
|
||||
|
||||
Alpine.data("kanban", () => ({
|
||||
me: "",
|
||||
search: "",
|
||||
error: "",
|
||||
init() {
|
||||
directus<{ id: string }>("users/me?fields=id")
|
||||
.then((res) => (this.me = res.id))
|
||||
.catch((err) => (this.error = err))
|
||||
},
|
||||
}))
|
||||
Alpine.data("tasklist", (status: string) => ({
|
||||
tasks: [],
|
||||
formatDate: formatDate,
|
||||
init() {
|
||||
directus<Task[]>(
|
||||
`items/tasks_general?filter[status][_eq]=${status}&fields=*,responsibles.directus_users_id.id,responsibles.directus_users_id.first_name`,
|
||||
)
|
||||
.then((res) => (this.tasks = res))
|
||||
.catch((err) => (this.error = err))
|
||||
},
|
||||
sortedTasks() {
|
||||
return (this.tasks as Task[])
|
||||
.filter(
|
||||
(a) =>
|
||||
a.title.toLowerCase().includes(this.search.toLowerCase()) ||
|
||||
a.responsibles
|
||||
.map(
|
||||
(x) =>
|
||||
`${x.directus_users_id.first_name}|id:${x.directus_users_id.id}`,
|
||||
)
|
||||
.join("|")
|
||||
.toLowerCase()
|
||||
.includes(this.search.toLowerCase()),
|
||||
)
|
||||
.sort((a, b) => a.title.localeCompare(b.title))
|
||||
.sort((a, b) => (a.date_due ?? "z").localeCompare(b.date_due ?? "z"))
|
||||
},
|
||||
}))
|
||||
|
||||
Alpine.start()
|
||||
</script>
|
|
@ -1,13 +1,50 @@
|
|||
input {
|
||||
color-scheme: dark;
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@theme {
|
||||
--font-sans: "Ubuntu", "sans-serif";
|
||||
--font-serif: "Ubuntu", "sans-serif";
|
||||
--font-mono: "Ubuntu Mono", "monospace";
|
||||
}
|
||||
|
||||
@plugin "@iconify/tailwind4";
|
||||
|
||||
@plugin "daisyui" {}
|
||||
|
||||
@plugin "daisyui/theme" {
|
||||
name: "swablab";
|
||||
default: true;
|
||||
prefersdark: true;
|
||||
color-scheme: dark;
|
||||
|
||||
--color-base-content: white;
|
||||
--color-base-100: "#171717";
|
||||
--color-base-200: "#262626";
|
||||
--color-base-300: "#404040";
|
||||
--color-primary: "#A3FFF1";
|
||||
--color-primary-content: black;
|
||||
--color-secondary: "#FF7F50";
|
||||
--color-primary-content: black;
|
||||
--color-neutral: "#404040";
|
||||
|
||||
--radius-selector: 1rem;
|
||||
--radius-field: 0.25rem;
|
||||
--radius-box: 0.5rem;
|
||||
--size-selector: 0.25rem;
|
||||
--size-field: 0.25rem;
|
||||
--border: 1px;
|
||||
|
||||
--depth: 0;
|
||||
--noise: 0;
|
||||
--glass-reflect-opacity: 0.001;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Ubuntu";
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
font-weight: 100 800;
|
||||
src: url(@fontsource-variable/ubuntu-sans/files/ubuntu-sans-latin-wght-normal.woff2)
|
||||
format("woff2-variations");
|
||||
src: url(@fontsource-variable/ubuntu-sans/files/ubuntu-sans-latin-wght-normal.woff2) format("woff2-variations");
|
||||
unicode-range:
|
||||
U+0000-00FF,
|
||||
U+0131,
|
||||
|
@ -29,8 +66,4 @@ input {
|
|||
U+2215,
|
||||
U+FEFF,
|
||||
U+FFFD;
|
||||
}
|
||||
|
||||
[x-cloak] {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
module.exports = {
|
||||
content: ["./src/**/*"],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#A3FFF1",
|
||||
secondary: "#FF7F50",
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ["Ubuntu", "sans-serif"],
|
||||
serif: ["Ubuntu", "sans-serif"],
|
||||
mono: ["Ubuntu Mono", "monospace"],
|
||||
},
|
||||
},
|
||||
},
|
||||
daisyui: {
|
||||
themes: [
|
||||
{
|
||||
swablab: {
|
||||
primary: "#A3FFF1",
|
||||
secondary: "#FF7F50",
|
||||
neutral: "#404040",
|
||||
"base-100": "#171717",
|
||||
"base-200": "#262626",
|
||||
"base-300": "#404040",
|
||||
|
||||
"--glass-reflex-opacity": "0.001",
|
||||
},
|
||||
},
|
||||
],
|
||||
logs: false,
|
||||
},
|
||||
plugins: [
|
||||
require("@tailwindcss/typography"),
|
||||
require("@iconify/tailwind").addDynamicIconSelectors(),
|
||||
require("daisyui"),
|
||||
],
|
||||
}
|
Loading…
Add table
Reference in a new issue