Compare commits
No commits in common. "main" and "main" have entirely different histories.
40 changed files with 3793 additions and 7086 deletions
|
@ -2,16 +2,17 @@
|
|||
"name": "swabsite",
|
||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/node": {}
|
||||
"ghcr.io/devcontainers-community/features/deno": {}
|
||||
},
|
||||
"containerUser": "vscode",
|
||||
"containerEnv": {
|
||||
"ASTRO_TELEMETRY_DISABLED": "true"
|
||||
},
|
||||
"postStartCommand": "deno task install",
|
||||
"runArgs": ["--userns=keep-id", "--security-opt=label=disable"],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"astro-build.astro-vscode"
|
||||
]
|
||||
"extensions": ["astro-build.astro-vscode"]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
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: docker:cli
|
||||
env:
|
||||
DOCKER_HOST: tcp://172.17.0.1:2375
|
||||
steps:
|
||||
- name: download
|
||||
run: wget -O- https://${{ env.url }}/archive/main.tar.gz | tar -xz
|
||||
|
||||
- name: build
|
||||
run: docker buildx build -f ${{ env.repo }}/Containerfile -t ${{ env.url }}:latest ${{ env.repo }}
|
||||
|
||||
- name: login
|
||||
run: docker login -u token -p ${{ env.token }} ${{ env.git }}
|
||||
|
||||
- name: push
|
||||
run: docker push ${{ env.git }}/${{ github.repository }}:latest
|
53
.forgejo/workflows/main.yml
Normal file
53
.forgejo/workflows/main.yml
Normal file
|
@ -0,0 +1,53 @@
|
|||
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 }}
|
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"astro-build.astro-vscode"
|
||||
"astro-build.astro-vscode",
|
||||
"denoland.vscode-deno"
|
||||
]
|
||||
}
|
22
.vscode/tasks.json
vendored
22
.vscode/tasks.json
vendored
|
@ -2,41 +2,33 @@
|
|||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "install",
|
||||
"command": "npm install",
|
||||
"type": "shell",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "update",
|
||||
"command": "npm update -S",
|
||||
"label": "install/update",
|
||||
"command": "deno task install",
|
||||
"type": "shell",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "dev",
|
||||
"command": "npm run dev",
|
||||
"command": "deno task dev",
|
||||
"type": "shell",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "check",
|
||||
"command": "npm run check",
|
||||
"command": "deno task check",
|
||||
"type": "shell",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "preview",
|
||||
"command": "npm run preview",
|
||||
"command": "deno task preview",
|
||||
"type": "shell",
|
||||
"problemMatcher": [],
|
||||
"dependsOn": [
|
||||
"build"
|
||||
]
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
{
|
||||
"label": "build",
|
||||
"command": "npm run build",
|
||||
"command": "deno task build",
|
||||
"type": "shell",
|
||||
"problemMatcher": []
|
||||
}
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
FROM docker.io/library/node AS build
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
ENV ASTRO_TELEMETRY_DISABLED=true
|
||||
RUN npm install
|
||||
RUN npm run build
|
||||
FROM ghcr.io/swablab/documents:latest AS documents
|
||||
|
||||
FROM git.swablab.de/swablab/documents AS documents
|
||||
|
||||
FROM docker.io/nginxinc/nginx-unprivileged:alpine-slim
|
||||
FROM docker.io/nginxinc/nginx-unprivileged:latest
|
||||
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
COPY ./dist /usr/share/nginx/html
|
||||
COPY --from=documents / /usr/share/nginx/html/docs
|
16
README.md
Normal file
16
README.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
# 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 tailwindcss from "@tailwindcss/vite"
|
||||
import tailwind from "@astrojs/tailwind"
|
||||
import { defineConfig, passthroughImageService } from "astro/config"
|
||||
|
||||
export default defineConfig({
|
||||
|
@ -8,14 +8,9 @@ export default defineConfig({
|
|||
server: {
|
||||
host: true,
|
||||
},
|
||||
integrations: [sitemap()],
|
||||
integrations: [tailwind(), sitemap()],
|
||||
image: {
|
||||
domains: ["directus.swablab.de", "files.mastodon.social"],
|
||||
service: passthroughImageService(),
|
||||
},
|
||||
vite: {
|
||||
plugins: [
|
||||
tailwindcss(),
|
||||
],
|
||||
},
|
||||
})
|
||||
|
|
8
deno.json
Normal file
8
deno.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"fmt": {
|
||||
"options": {
|
||||
"semiColons": false,
|
||||
"indentWidth": 2
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,14 +17,8 @@ server {
|
|||
internal;
|
||||
}
|
||||
|
||||
location /todo {
|
||||
return 302 https://directus.swablab.de/admin/content/tasks_general;
|
||||
}
|
||||
location /discord {
|
||||
return 302 https://discord.gg/A4grfc5Vzm;
|
||||
}
|
||||
location /linux {
|
||||
return 302 https://wiki.swablab.de/books/it/page/linux-installationsparty;
|
||||
return 301 https://discord.gg/sZbmJdGkMQ;
|
||||
}
|
||||
|
||||
location / {
|
||||
|
|
6770
package-lock.json
generated
6770
package-lock.json
generated
File diff suppressed because it is too large
Load diff
22
package.json
22
package.json
|
@ -2,6 +2,7 @@
|
|||
"name": "@swablab/website",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"install": "deno install -q",
|
||||
"check": "astro check",
|
||||
"dev": "astro dev",
|
||||
"build": "astro build",
|
||||
|
@ -9,15 +10,18 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@astrojs/check": "^0.9.4",
|
||||
"@astrojs/sitemap": "^3.3.1",
|
||||
"@fontsource-variable/ubuntu-sans": "^5.2.7",
|
||||
"@iconify-json/ph": "^1.2.2",
|
||||
"@iconify/tailwind4": "^1.0.6",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@tailwindcss/vite": "^4.1.5",
|
||||
"astro": "^5.7.12",
|
||||
"daisyui": "^5.0.35",
|
||||
"tailwindcss": "^4.0.14"
|
||||
"@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"
|
||||
},
|
||||
"prettier": {
|
||||
"tabWidth": 2,
|
||||
|
|
Before Width: | Height: | Size: 6 KiB After Width: | Height: | Size: 6 KiB |
50
public/logo_color.svg
Normal file
50
public/logo_color.svg
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 1080 1080" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:2.5;">
|
||||
<g transform="matrix(1,0,0,1,-2281.57,-1257.11)">
|
||||
<g id="Lightmode-no-text" serif:id="Lightmode no text" transform="matrix(1,0,0,1,-4466.43,123.108)">
|
||||
<rect x="6748" y="1134" width="1080" height="1080" style="fill:none;"/>
|
||||
<g transform="matrix(1.24839,0,0,1.24839,-749.242,-387.363)">
|
||||
<g transform="matrix(1,0,0,1,-849.9,42.4178)">
|
||||
<path d="M7200.48,1795.34C7204.27,1796.68 7207.24,1799.68 7208.55,1803.48C7214.69,1821.27 7232.49,1872.93 7241.19,1898.18C7244.23,1907 7251.7,1913.55 7260.84,1915.4C7279.24,1919.13 7310.73,1925.52 7330.82,1929.6C7341.98,1931.86 7353.33,1926.66 7358.9,1916.72C7366.21,1903.67 7376.32,1885.62 7383.58,1872.65C7389.62,1861.86 7393.28,1849.91 7394.31,1837.59C7394.99,1829.36 7395.8,1819.69 7396.49,1811.36C7397.42,1800.24 7406.61,1791.61 7417.77,1791.39C7431.82,1791.12 7448.27,1790.8 7448.27,1790.8C7473.78,1772.72 7496.06,1750.44 7514.14,1724.92L7506.91,1678.37C7513.47,1665.76 7518.92,1652.6 7523.2,1639.04L7561.23,1611.24C7566.49,1580.41 7566.49,1548.91 7561.23,1518.08L7523.2,1490.27C7518.92,1476.72 7513.47,1463.56 7506.91,1450.94L7514.14,1404.39C7496.06,1378.87 7473.78,1356.6 7448.27,1338.52L7401.72,1345.75C7389.1,1339.19 7375.94,1333.74 7362.39,1329.45L7334.58,1291.43C7303.75,1286.17 7272.25,1286.17 7241.42,1291.43L7213.61,1329.45C7200.06,1333.74 7186.9,1339.19 7174.28,1345.75L7127.73,1338.52C7102.22,1356.6 7079.94,1378.87 7061.86,1404.39L7069.09,1450.94C7062.53,1463.56 7057.08,1476.72 7052.8,1490.27L7014.77,1518.08C7009.51,1548.91 7009.51,1580.41 7014.77,1611.24L7052.8,1639.04C7057.08,1652.6 7062.53,1665.76 7069.09,1678.37L7061.86,1724.92C7079.94,1750.44 7102.22,1772.72 7127.73,1790.8L7174.28,1783.57C7184.89,1789.08 7190.81,1792 7200.48,1795.34ZM7288,1439.49C7357.71,1439.49 7414.3,1496.09 7414.3,1565.79C7414.3,1635.5 7357.71,1692.09 7288,1692.09C7218.29,1692.09 7161.7,1635.5 7161.7,1565.79C7161.7,1496.09 7218.29,1439.49 7288,1439.49Z" style="fill:rgb(163,255,241);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-849.728,-3.45885)">
|
||||
<path d="M7260.8,1855.8L7347.85,1876.46" style="fill:none;stroke:rgb(61,61,61);stroke-width:22.36px;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-847.9,0)">
|
||||
<path d="M7276.11,1906.48L7323.66,1917.98" style="fill:none;stroke:rgb(61,61,61);stroke-width:22.36px;stroke-linejoin:miter;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,2474.6,-129.288)">
|
||||
<circle cx="3963.5" cy="1737.5" r="126.3" style="fill:none;stroke:rgb(61,61,61);stroke-width:22.31px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,2474.6,-129.288)">
|
||||
<path d="M4021.69,1896.02C4032.02,1892.93 4043.63,1887.14 4052.61,1880.39L4089.23,1906.33C4105.61,1894.13 4120.13,1879.61 4132.33,1863.23L4106.39,1826.61C4116.21,1810.87 4123.36,1793.6 4127.55,1775.53L4171.78,1767.98C4174.74,1747.77 4174.74,1727.23 4171.78,1707.02L4127.55,1699.48C4123.36,1681.4 4116.21,1664.13 4106.39,1648.39L4132.33,1611.77C4120.13,1595.39 4105.61,1580.87 4089.23,1568.67L4052.61,1594.61C4036.87,1584.79 4019.6,1577.64 4001.53,1573.45L3993.98,1529.22C3973.77,1526.26 3953.23,1526.26 3933.02,1529.22L3925.47,1573.45C3907.4,1577.64 3890.13,1584.79 3874.39,1594.61L3837.77,1568.67C3821.39,1580.87 3806.87,1595.39 3794.67,1611.77L3820.61,1648.39C3810.79,1664.13 3803.64,1681.4 3799.45,1699.48L3755.22,1707.02C3752.26,1727.23 3752.26,1747.77 3755.22,1767.98L3799.45,1775.53C3803.64,1793.6 3810.79,1810.87 3820.61,1826.61L3794.67,1863.23C3806.87,1879.61 3821.39,1894.13 3837.77,1906.33L3874.39,1880.39C3883.06,1884.99 3896.11,1891.64 3904.67,1893.84L3921.92,1925.54L4026.94,1949.95" style="fill:none;stroke:rgb(61,61,61);stroke-width:22.31px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.418992,0,0,0.466271,4240.37,-631.785)">
|
||||
<g transform="matrix(1.22943,0,0,1.10477,-1501.56,-441.15)">
|
||||
<path d="M7070.03,4727.19C7062.51,4730.97 7054.03,4733.09 7045.06,4733.09C7014.28,4733.09 6989.29,4708.1 6989.29,4677.32C6989.29,4646.54 7014.28,4621.55 7045.06,4621.55C7070.73,4621.55 7092.37,4638.93 7098.85,4662.55C7081.1,4674.79 7069.46,4695.26 7069.46,4718.42C7069.46,4721.39 7069.65,4724.32 7070.03,4727.19Z" style="fill:rgb(102,102,102);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.22943,0,0,1.10477,-1501.56,-441.15)">
|
||||
<path d="M7102.94,4776.9L7102.91,4780.95C7102.91,4780.95 7080.42,4787.8 7063.75,4804.47C7052.4,4815.81 7032.47,4841.04 7032.47,4874.18C7032.47,4899.4 7032.47,4879.97 7032.47,4879.97C6988.12,4878.21 6952.83,4866.44 6952.83,4866.44C6952.83,4866.44 6952.83,4842.95 6952.83,4816.79C6952.83,4798.22 6960.21,4780.42 6973.34,4767.29C6986.46,4754.16 7004.27,4746.79 7022.83,4746.79C7037.39,4746.79 7052.73,4746.79 7067.28,4746.79C7070.18,4746.79 7073.07,4746.97 7075.92,4747.32C7081.76,4759.69 7091.23,4770 7102.94,4776.9Z" style="fill:rgb(102,102,102);"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.418992,0,0,0.466271,4240.37,-631.785)">
|
||||
<g transform="matrix(-1.22943,0,0,1.10477,16049,-441.15)">
|
||||
<path d="M7102.94,4776.9L7102.91,4780.95C7102.91,4780.95 7080.42,4787.8 7063.75,4804.47C7052.4,4815.81 7032.47,4841.04 7032.47,4874.18C7032.47,4899.4 7032.47,4879.97 7032.47,4879.97C6988.12,4878.21 6952.83,4866.44 6952.83,4866.44C6952.83,4866.44 6952.83,4842.95 6952.83,4816.79C6952.83,4798.22 6960.21,4780.42 6973.34,4767.29C6986.46,4754.16 7004.27,4746.79 7022.83,4746.79C7037.39,4746.79 7052.73,4746.79 7067.28,4746.79C7070.18,4746.79 7073.07,4746.97 7075.92,4747.32C7081.76,4759.69 7091.23,4770 7102.94,4776.9Z" style="fill:rgb(102,102,102);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.22943,0,0,1.10477,-1501.56,-441.15)">
|
||||
<path d="M7175.79,4662.61C7182.25,4638.96 7203.91,4621.55 7229.6,4621.55C7260.38,4621.55 7285.37,4646.54 7285.37,4677.32C7285.37,4708.1 7260.38,4733.09 7229.6,4733.09C7220.59,4733.09 7212.07,4730.95 7204.54,4727.15C7204.9,4724.29 7205.09,4721.38 7205.09,4718.42C7205.09,4695.29 7193.49,4674.86 7175.79,4662.61Z" style="fill:rgb(102,102,102);"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.418992,0,0,0.466271,4240.37,-631.785)">
|
||||
<g transform="matrix(1.29452,0,0,1.16326,-3371.22,3043.8)">
|
||||
<circle cx="8222.71" cy="1485.33" r="52.965" style="fill:rgb(128,128,128);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.22943,0,0,0.993178,-2937.04,3274.16)">
|
||||
<path d="M8397.09,1687.6C8397.09,1660.4 8387.38,1634.31 8370.08,1615.07C8352.79,1595.83 8329.33,1585.02 8304.88,1585.02L8304.87,1585.02C8280.41,1585.02 8256.95,1595.83 8239.66,1615.07C8222.37,1634.31 8212.65,1660.4 8212.65,1687.6L8212.65,1718.12C8212.65,1718.12 8255.69,1733.08 8304.87,1733.08C8354.06,1733.08 8397.09,1718.12 8397.09,1718.12L8397.09,1687.6Z" style="fill:rgb(128,128,128);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.4 KiB |
5
public/test/me
Normal file
5
public/test/me
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"data": {
|
||||
"id": "user1"
|
||||
}
|
||||
}
|
7
public/test/presence
Normal file
7
public/test/presence
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"data": {
|
||||
"id": 1,
|
||||
"last": "2024-05-08T18:00:00",
|
||||
"next": "2024-05-08T18:00:00"
|
||||
}
|
||||
}
|
25
public/test/task
Normal file
25
public/test/task
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
37
public/test/tasks_general
Normal file
37
public/test/tasks_general
Normal file
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"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": []
|
||||
}
|
||||
]
|
||||
}
|
12
public/test/users
Normal file
12
public/test/users
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"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 class="text-lg">
|
||||
<p>
|
||||
<slot />
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
export interface Props {
|
||||
title: string
|
||||
icon: string
|
||||
}
|
||||
const { title, icon }: Props = Astro.props
|
||||
---
|
||||
|
||||
<div class="collapse collapse-arrow join-item border-base-300 border">
|
||||
<input type="radio" name="collapse" />
|
||||
<div class="collapse-title font-semibold text-left">
|
||||
<span class={icon + " align-middle"}></span>
|
||||
<span class="ml-1">{title}</span>
|
||||
</div>
|
||||
<div class="collapse-content text-left">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
|
@ -71,7 +71,7 @@ function replaceEmojis(content: string) {
|
|||
</figure>
|
||||
)}
|
||||
|
||||
<div class="card-body text-left text-lg">
|
||||
<div class="card-body text-left">
|
||||
<h2 class="card-title justify-between">
|
||||
<a href={post.url}>@swablab</a>
|
||||
<time class="text-xs opacity-50">
|
||||
|
|
|
@ -5,7 +5,6 @@ import DirectusImg from "./DirectusImg.astro"
|
|||
type Member = {
|
||||
firstname: string
|
||||
image?: string
|
||||
chairman?: boolean
|
||||
}
|
||||
const members = await directus<Member[]>("items/members?sort=firstname")
|
||||
---
|
||||
|
@ -25,43 +24,11 @@ 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"
|
||||
class="flex flex-row flex-wrap gap-6 justify-evenly sm:justify-center text-base pt-8"
|
||||
>
|
||||
{
|
||||
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>
|
||||
|
||||
<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) => (
|
||||
members.map((member) => (
|
||||
<div>
|
||||
<DirectusImg
|
||||
src={
|
||||
|
|
|
@ -7,7 +7,7 @@ const { title, jumpId }: Props = Astro.props
|
|||
---
|
||||
|
||||
<div class="text-center p-8 space-y-8 even:bg-base-200">
|
||||
<a class="invisible relative -top-24" id={jumpId}></a>
|
||||
<a hidden class="block invisible relative -top-20" id={jumpId}></a>
|
||||
<div class="text-3xl md:text-5xl">
|
||||
<a href={"#" + jumpId}>{title}</a>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,33 @@
|
|||
export async function directus<T>(path: string): Promise<T> {
|
||||
return await fetch(`https://directus.swablab.de/${path}`)
|
||||
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,
|
||||
},
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((res) => res.data)
|
||||
.then((res) => {
|
||||
if (res.errors) throw res.errors[0].message
|
||||
return res.data
|
||||
})
|
||||
}
|
||||
|
||||
export function formatDate(
|
||||
|
@ -32,3 +58,18 @@ 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,6 +29,13 @@ 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(
|
||||
"Forgejo",
|
||||
"icon-[ph--git-branch]",
|
||||
"https://git.swablab.de/explore/repos",
|
||||
"GitHub",
|
||||
"icon-[ph--github-logo-duotone]",
|
||||
"https://github.com/swablab",
|
||||
),
|
||||
]
|
||||
|
||||
|
@ -47,25 +47,6 @@ const downloads = [
|
|||
documents.Mitgliedsantrag,
|
||||
),
|
||||
]
|
||||
|
||||
const contact = [
|
||||
entry(
|
||||
"Friedrichstr. 17, 72250 Freudenstadt",
|
||||
"icon-[ph--house-line-duotone]",
|
||||
"https://swablab.de/lab",
|
||||
),
|
||||
entry(
|
||||
"Katharinenstr. 1, 72250 Freudenstadt",
|
||||
"icon-[ph--mailbox-duotone]",
|
||||
"https://swablab.de/imprint",
|
||||
),
|
||||
entry(
|
||||
"info@swablab.de",
|
||||
"icon-[ph--envelope-simple-duotone]",
|
||||
"mailto:info@swablab.de",
|
||||
),
|
||||
entry("+49 15679 232971", "icon-[ph--phone-duotone]", "tel:+4915679232971"),
|
||||
]
|
||||
---
|
||||
|
||||
<div class="bg-base-200 border-t border-base-300">
|
||||
|
@ -103,17 +84,24 @@ const contact = [
|
|||
</nav>
|
||||
<nav class="w-full">
|
||||
<header class="footer-title border-b w-full">Kontakt</header>
|
||||
{
|
||||
contact.map((e) => (
|
||||
<div class="flex gap-1 items-center">
|
||||
<span class="icon-[ph--map-pin-duotone]"></span>
|
||||
Katharinenstr. 1, 72250 Freudenstadt
|
||||
</div>
|
||||
<a
|
||||
class="link link-hover link-primary flex gap-1 items-center"
|
||||
href={e.link}
|
||||
href="mailto:info@swablab.de"
|
||||
>
|
||||
<span class={e.icon} />
|
||||
{e.name}
|
||||
<span class="icon-[ph--envelope-simple-duotone]"></span>
|
||||
info@swablab.de
|
||||
</a>
|
||||
<a
|
||||
class="link link-hover link-primary flex gap-1 items-center"
|
||||
href="tel:+4915679232971"
|
||||
>
|
||||
<span class="icon-[ph--phone-duotone]"></span>
|
||||
+49 15679 232971
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</nav>
|
||||
</footer>
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
import Logo from "./Logo.svg"
|
||||
import Presence from "./Presence.astro"
|
||||
|
||||
const links = [
|
||||
|
@ -15,14 +14,10 @@ const links = [
|
|||
|
||||
<nav class="fixed top-0 navbar z-30 glass bg-base-100/30">
|
||||
<div class="navbar-start">
|
||||
<ul class="menu menu-horizontal p-0">
|
||||
<li>
|
||||
<a class="text-xl" href="/">
|
||||
<Logo class="w-8 h-8" />
|
||||
<span>swablab</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<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
|
||||
>
|
||||
</div>
|
||||
<div class="navbar-center hidden lg:flex">
|
||||
<ul class="menu menu-horizontal p-0">
|
||||
|
@ -39,12 +34,6 @@ 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">
|
||||
|
@ -61,12 +50,6 @@ 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="xl:hidden">
|
||||
<div class="md:hidden">
|
||||
<div class="tooltip tooltip-left">
|
||||
<button class="btn btn-square">
|
||||
<button class="btn btn-square font-normal">
|
||||
<span class="icon-[ph--door-open-duotone] w-6 h-6"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden xl:flex">
|
||||
<button class="btn">
|
||||
<div class="hidden md:flex">
|
||||
<button class="btn font-normal">
|
||||
<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@mastodon.social) geposted.`,
|
||||
`Neben unserem Instagram-Account werden jetzt Neuigkeiten und Projekte auch auf Mastodon (@swablab) 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 bg-base-300">
|
||||
<div class="stats shadow">
|
||||
<div class="stat">
|
||||
<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 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>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@ Telefon: [+49 15679 232971](tel:+4915679232971)
|
|||
|
||||
**Vertreten durch**\
|
||||
Fabian Haas\
|
||||
Manuel Knodel\
|
||||
Bastian Wittke
|
||||
Manuel Knodel
|
||||
|
||||
**Registereintrag**\
|
||||
Amtsgericht Stuttgart\
|
||||
|
|
|
@ -24,6 +24,17 @@ import Page from "../layouts/Page.astro"
|
|||
<span class="icon-[ph--arrow-circle-down-duotone] h-16 w-16"></span>
|
||||
</a>
|
||||
|
||||
<div class="text-center p-8 space-y-8 bg-secondary">
|
||||
<div class="text-3xl md:text-5xl">Info für Besucher!</div>
|
||||
<div class="max-w-4xl mx-auto flex flex-col gap-4">
|
||||
Wir sind umgezogen! Du findest uns jetzt in der
|
||||
<Link
|
||||
text="Friedrichstraße 17 in Freudenstadt!"
|
||||
href="https://www.openstreetmap.org/node/12119224010"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Section title="Offene Werkstatt?" jumpId="start">
|
||||
<DirectusImg
|
||||
src="753d211b-8b28-42cb-8ddd-0777911b3511"
|
||||
|
@ -50,14 +61,6 @@ import Page from "../layouts/Page.astro"
|
|||
</Text>
|
||||
</Section>
|
||||
|
||||
<Section title="Was gibt's neues?" jumpId="news">
|
||||
<Mastodon />
|
||||
</Section>
|
||||
|
||||
<Section title="Unsere Sponsoren" jumpId="sponsors">
|
||||
<Sponsors />
|
||||
</Section>
|
||||
|
||||
<Section title="Was interessiert dich?" jumpId="services">
|
||||
<Card
|
||||
name="Über uns"
|
||||
|
@ -109,6 +112,14 @@ import Page from "../layouts/Page.astro"
|
|||
</Card>
|
||||
</Section>
|
||||
|
||||
<Section title="Was gibt's neues?" jumpId="news">
|
||||
<Mastodon />
|
||||
</Section>
|
||||
|
||||
<Section title="Unsere Sponsoren" jumpId="sponsors">
|
||||
<Sponsors />
|
||||
</Section>
|
||||
|
||||
<div class="fixed bottom-4 left-4 flex">
|
||||
<a
|
||||
class="btn btn-square btn-ghost z-10 discord-left"
|
||||
|
|
|
@ -24,11 +24,11 @@ import Page from "../layouts/Page.astro"
|
|||
oder ihn an folgende Adresse schicken:
|
||||
</Text>
|
||||
|
||||
<div class="stats shadow bg-base-300">
|
||||
<div class="stats shadow">
|
||||
<div class="stat">
|
||||
<div class="stat-value">swablab e.V.</div>
|
||||
<div class="stat-title text-xl">Katharinenstr. 1</div>
|
||||
<div class="stat-title text-xl">72250 Freudenstadt</div>
|
||||
<div class="stat-title">Katharinenstr. 1</div>
|
||||
<div class="stat-title">72250 Freudenstadt</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
---
|
||||
import Card from "../components/Card.astro"
|
||||
import Collapse from "../components/Collapse.astro"
|
||||
import Contact from "../components/Contact.astro"
|
||||
import Gallery from "../components/Gallery.astro"
|
||||
import Link from "../components/Link.astro"
|
||||
import Map from "../components/Map.astro"
|
||||
import Section from "../components/Section.astro"
|
||||
import Text from "../components/Text.astro"
|
||||
|
@ -93,32 +91,6 @@ import Page from "../layouts/Page.astro"
|
|||
<Map />
|
||||
</Section>
|
||||
|
||||
<Section title="Anreise" jumpId="trips">
|
||||
<div class="join join-vertical bg-base-100">
|
||||
<Collapse title="per Auto" icon="icon-[ph--car-duotone]">
|
||||
Parken kannst du in den benachbarten Straßen auf ausgewiesenen
|
||||
Parkplätzen sowie auf dem Kasernenplatz vor dem Rathaus (dort gibt es
|
||||
auch E-Ladestationen). Einige Parkplätze sind Montag bis Freitag bis 19
|
||||
Uhr kostenpflichtig.
|
||||
</Collapse>
|
||||
<Collapse title="per Bus/Bahn" icon="icon-[ph--train-duotone]">
|
||||
Die Bushaltestelle der Martin-Luther-Straße ist zwei Straßen weiter,
|
||||
sonst ist auch der ZOB in der Nähe. Direkt neben dem ZOB befindet sich
|
||||
der Freudenstädter Stadtbahnhof.
|
||||
</Collapse>
|
||||
<Collapse title="per Fahrrad" icon="icon-[ph--bicycle-duotone]">
|
||||
Fahrradständer sind vor dem Intersport Glaser sowie auf dem
|
||||
Kasernenplatz vor dem Rathaus.
|
||||
</Collapse>
|
||||
<Collapse title="per Flugzeug" icon="icon-[ph--airplane-duotone]">
|
||||
Hierfür empfehlen wir die <Link
|
||||
text="Anreise-Seite von Freudenstadt"
|
||||
href="https://www.freudenstadt.de/anfahrt"
|
||||
/>.
|
||||
</Collapse>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Contact>
|
||||
<Text>
|
||||
Egal, ob du an 3D-Druck, Elektronik, CNC-Arbeiten oder anderen Projekten
|
||||
|
|
207
src/pages/todo-edit.astro
Normal file
207
src/pages/todo-edit.astro
Normal file
|
@ -0,0 +1,207 @@
|
|||
---
|
||||
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>
|
133
src/pages/todo.astro
Normal file
133
src/pages/todo.astro
Normal file
|
@ -0,0 +1,133 @@
|
|||
---
|
||||
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,50 +1,13 @@
|
|||
@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;
|
||||
input {
|
||||
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,
|
||||
|
@ -67,3 +30,7 @@
|
|||
U+FEFF,
|
||||
U+FFFD;
|
||||
}
|
||||
|
||||
[x-cloak] {
|
||||
display: none !important;
|
||||
}
|
||||
|
|
38
tailwind.config.ts
Normal file
38
tailwind.config.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
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