Compare commits

..

79 Commits

Author SHA1 Message Date
a17c120ebe Merge pull request 'log-2022' (#64) from log-2022 into main
All checks were successful
CI/CD Pipeline / test (push) Successful in 10m42s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Successful in 14m13s
Reviewed-on: #64
2023-11-20 10:11:04 +01:00
ecd4e87f98 Update staging-diff.sql
All checks were successful
CI/CD Pipeline / test (push) Successful in 11m1s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-20 08:22:48 +01:00
f004a34b54 Merge branch 'staging' into log-2022
All checks were successful
CI/CD Pipeline / test (push) Successful in 11m3s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 22:20:53 +01:00
4199fadc0a use current year in test_db
All checks were successful
CI/CD Pipeline / test (push) Successful in 11m10s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 22:19:28 +01:00
7bc8293c65 add routes for different years
Some checks failed
CI/CD Pipeline / test (push) Failing after 11m0s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 22:02:43 +01:00
1d9824dfdc push 2023-11-19 22:02:25 +01:00
08202691f6 push 2023-11-19 22:02:25 +01:00
188dd50a84 push 2023-11-19 22:02:25 +01:00
930ecd490b push 2023-11-19 22:02:25 +01:00
0ea4fef9f7 push 2023-11-19 22:02:25 +01:00
d10b22f145 push 2023-11-19 22:02:25 +01:00
a4945e5972 push 2023-11-19 22:02:25 +01:00
33a4cc49e1 push 2023-11-19 22:02:25 +01:00
6c5448c464 push 2023-11-19 22:02:25 +01:00
b4eefb60c4 push 2023-11-19 22:02:25 +01:00
3c8d240549 push 2023-11-19 22:02:25 +01:00
262839f276 push 2023-11-19 22:02:25 +01:00
5cc08d657d push 2023-11-19 22:02:25 +01:00
c0353c0915 push 2023-11-19 22:02:25 +01:00
67ae4095cb push 2023-11-19 22:02:25 +01:00
14d82576f8 push 2023-11-19 22:02:25 +01:00
a9b67660b1 push 2023-11-19 22:02:25 +01:00
34123d9f79 ? 2023-11-19 22:02:25 +01:00
0b1a6acd3a push 2023-11-19 22:02:25 +01:00
c9e47abd8e push 2023-11-19 22:02:25 +01:00
98b2b3d5f4 push 2023-11-19 22:02:25 +01:00
0db0a0f590 switch to gitea 2023-11-19 22:02:25 +01:00
9694fe6512 push
All checks were successful
CI/CD Pipeline / test (push) Successful in 11m59s
CI/CD Pipeline / deploy-staging (push) Successful in 14m50s
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 22:01:14 +01:00
fea5b6f3d8 push
All checks were successful
CI/CD Pipeline / test (push) Successful in 11m1s
CI/CD Pipeline / deploy-staging (push) Successful in 15m4s
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 21:41:46 +01:00
4c54ebf6c3 push
All checks were successful
CI/CD Pipeline / test (push) Successful in 11m21s
CI/CD Pipeline / deploy-staging (push) Successful in 15m22s
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 21:13:50 +01:00
a5aee6c6ed push
Some checks failed
CI/CD Pipeline / test (push) Successful in 11m20s
CI/CD Pipeline / deploy-main (push) Has been skipped
CI/CD Pipeline / deploy-staging (push) Failing after 14m53s
2023-11-19 20:14:08 +01:00
922716e1b7 push
Some checks failed
CI/CD Pipeline / test (push) Successful in 10m56s
CI/CD Pipeline / deploy-staging (push) Failing after 14m56s
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 19:36:19 +01:00
de75f5398a push
Some checks failed
CI/CD Pipeline / test (push) Successful in 11m4s
CI/CD Pipeline / deploy-staging (push) Failing after 14m41s
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 18:56:29 +01:00
c3d341d439 push
Some checks failed
CI/CD Pipeline / test (push) Successful in 11m2s
CI/CD Pipeline / deploy-staging (push) Failing after 14m42s
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 18:03:14 +01:00
a799edc78b push
Some checks failed
CI/CD Pipeline / test (push) Successful in 11m0s
CI/CD Pipeline / deploy-staging (push) Failing after 14m5s
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 10:14:44 +01:00
fb2e4a72ed push
Some checks failed
CI/CD Pipeline / test (push) Successful in 10m59s
CI/CD Pipeline / deploy-staging (push) Failing after 14m23s
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 09:47:08 +01:00
bf50f952dc push
Some checks failed
CI/CD Pipeline / test (push) Successful in 11m4s
CI/CD Pipeline / deploy-staging (push) Failing after 11m46s
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 09:21:50 +01:00
35f6dd2a38 push
Some checks failed
CI/CD Pipeline / test (push) Failing after 31s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-19 09:04:51 +01:00
1e9339642f push
Some checks failed
CI/CD Pipeline / test (push) Successful in 10m54s
CI/CD Pipeline / deploy-staging (push) Failing after 2m39s
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-18 22:36:13 +01:00
b0562299d6 push
Some checks reported warnings
CI/CD Pipeline / deploy-staging (push) Has been cancelled
CI/CD Pipeline / deploy-main (push) Has been cancelled
CI/CD Pipeline / test (push) Has been cancelled
2023-11-18 22:35:25 +01:00
8251d3b648 push
Some checks failed
CI/CD Pipeline / test (push) Successful in 11m18s
CI/CD Pipeline / deploy-staging (push) Failing after 2s
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-18 22:22:36 +01:00
70ead9a970 push
Some checks failed
CI/CD Pipeline / build (push) Successful in 14m46s
CI/CD Pipeline / test (push) Failing after 3m47s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-18 21:57:57 +01:00
fd3ed5a272 push
Some checks failed
CI/CD Pipeline / build (push) Failing after 2s
CI/CD Pipeline / test (push) Has been skipped
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-18 21:56:25 +01:00
becd1b99e6 push
Some checks failed
CI/CD Pipeline / build (push) Failing after 5s
CI/CD Pipeline / test (push) Has been skipped
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-18 21:54:11 +01:00
f96086753d ?
Some checks failed
CI/CD Pipeline / setup-environment (push) Successful in 0s
CI/CD Pipeline / build (push) Failing after 2s
CI/CD Pipeline / test (push) Has been skipped
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-18 21:46:00 +01:00
cf257c5f65 push
Some checks reported warnings
CI/CD Pipeline / test (push) Has been cancelled
CI/CD Pipeline / deploy-staging (push) Has been cancelled
CI/CD Pipeline / deploy-main (push) Has been cancelled
CI/CD Pipeline / build (push) Has been cancelled
2023-11-18 21:18:07 +01:00
ffb437e1f4 push
Some checks failed
CI/CD Pipeline / build (push) Successful in 14m45s
CI/CD Pipeline / test (push) Failing after 9m0s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-18 20:47:21 +01:00
0ec49ea264 push
Some checks failed
CI/CD Pipeline / build (push) Successful in 14m41s
CI/CD Pipeline / test (push) Failing after 7m31s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-18 20:23:07 +01:00
5c30fa3cfa switch to gitea
Some checks failed
CI/CD Pipeline / build (push) Successful in 14m46s
CI/CD Pipeline / test (push) Failing after 4s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2023-11-18 20:02:23 +01:00
53ed032c25 Merge branch 'staging' into 'log-2022'
# Conflicts:
#   src/model/logbook.rs
2023-11-18 11:22:50 +00:00
f001aaf90f add routes for different years 2023-11-18 12:21:37 +01:00
e053ff96cf migrate 2022 entries 2023-11-18 12:03:31 +01:00
f28a66b11e Merge branch 'no-data-mangling' into 'staging'
don't allow to add entry which is not completed today

See merge request PhilippHofer/rot!116
2023-11-16 14:50:39 +00:00
a87832e4f4 update tests to use current date 2023-11-16 15:36:38 +01:00
5b4238da92 update tests to use current date 2023-11-16 15:35:52 +01:00
5c7cd58edc Merge branch 'ergo-again' into 'staging'
Ergo again

See merge request PhilippHofer/rot!120
2023-11-16 14:00:41 +00:00
30bc29e987 Merge branch 'ergo-links' into 'staging'
use new fancy rudernlinz links

See merge request PhilippHofer/rot!119
2023-11-15 17:48:49 +00:00
aefa625524 merge 2023-11-15 18:35:33 +01:00
59b5b1bf97 use new fancy rudernlinz links 2023-11-15 18:27:46 +01:00
a3c7461c2b don't allow to add entry which is not completed today 2023-11-14 23:09:33 +01:00
Marie Birner
e1b9cdcd3b Merge branch 'ergo-style' into staging 2023-11-14 11:49:08 +01:00
7baa47d859 Merge branch 'save-ergo-imgs' into 'staging'
add timestamp to save imgs

See merge request PhilippHofer/rot!113
2023-11-12 20:41:31 +00:00
56163a4732 Merge branch 'finalize-ergo' into 'staging'
push

See merge request PhilippHofer/rot!111
2023-11-12 14:35:57 +00:00
be52b0daf5 Merge branch 'default-dist' into 'staging'
refactor(main.ts): refactor selectBoatChange and initNewChoice functions

See merge request PhilippHofer/rot!109
2023-11-12 12:46:47 +00:00
bfd9178d82 Merge branch 'fix-direct-add' into 'staging'
Fix direct add

See merge request PhilippHofer/rot!107
2023-11-10 16:09:07 +00:00
65edd4caa8 Merge branch 'ergo-desc' into 'staging'
Ergo desc

See merge request PhilippHofer/rot!106
2023-11-10 12:24:55 +00:00
23a21b55c7 Merge branch 'new-people' into 'staging'
improve text

See merge request PhilippHofer/rot!101
2023-11-10 09:30:56 +00:00
5c3be25285 Merge branch 'ergo-desc' into 'staging'
more concise

See merge request PhilippHofer/rot!100
2023-11-10 09:30:52 +00:00
f7c3fa01bc Merge branch 'change-artifact-expiration' into 'staging'
perf(expire_in): optimize expiration time

See merge request PhilippHofer/rot!102
2023-11-10 08:47:10 +00:00
e5f6a543e1 improve text 2023-11-10 09:03:04 +01:00
87b5cff190 Merge branch 'new-people' into 'staging'
New people

See merge request PhilippHofer/rot!98
2023-11-09 21:29:59 +00:00
9b86d93979 try to get new people 2023-11-09 22:02:31 +01:00
9bfa89a841 Merge branch 'ergo-desc' into 'staging'
add notes about ergo challenge

See merge request PhilippHofer/rot!96
2023-11-09 21:02:28 +00:00
Marie Birner
e8efe13ef5 Merge branch 'bugfix-label' into staging 2023-11-09 21:23:09 +01:00
Marie Birner
d60cbc7b5a Merge branch 'bugfix-label' into staging 2023-11-09 21:02:36 +01:00
Marie Birner
7e02c840b4 Merge branch 'bugfix-label' into staging 2023-11-09 19:40:56 +01:00
Marie Birner
cdc42d7154 [BUGFIX] color text dark-mode 2023-11-09 19:39:23 +01:00
Marie Birner
88c99b0898 Merge branch 'bugfix-label' into staging 2023-11-09 19:38:09 +01:00
b4e7a5f28b Merge branch 'default-boat-dest' into 'staging'
implement default destination for boats

See merge request PhilippHofer/rot!93
2023-11-09 08:26:41 +00:00
10 changed files with 2701 additions and 123 deletions

136
.gitea/workflows/action.yml Normal file
View File

@ -0,0 +1,136 @@
name: CI/CD Pipeline
on: push
env:
CARGO_TARGET: x86_64-unknown-linux-musl
SSH_HOST: ${{ secrets.SSH_HOST }}
SSH_USER: ${{ secrets.SSH_USER }}
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
jobs:
test:
runs-on: ubuntu-latest
container: rust:latest
steps:
- name: Setup Environment
run: |
apt-get update -qq && apt-get install -y -qq sshpass musl musl-tools sqlite3 curl gnupg && mkdir -p /etc/apt/keyrings | curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && apt-get update && apt-get install nodejs -y && apt-get install npm -y
- name: Checkout
uses: actions/checkout@v3
- name: Run Test DB Script
run: ./test_db.sh
- name: Build
run: |
cargo build
cd frontend && npm install && npm run build
- name: Run Tests
run: cargo test --verbose
deploy-staging:
runs-on: ubuntu-latest
container: rust:latest
needs: [test]
if: github.ref == 'refs/heads/staging'
steps:
- name: Setup Environment
run: |
rustup target add $CARGO_TARGET
apt-get update -qq && apt-get install -y -qq sshpass musl musl-tools sqlite3 curl gnupg
# Handling NodeSource GPG key
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key -o nodesource.gpg.key
if [ -f /etc/apt/keyrings/nodesource.gpg ]; then
rm /etc/apt/keyrings/nodesource.gpg
fi
gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg nodesource.gpg.key
# Adding NodeSource repository
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
# Installing Node.js and npm
apt-get update
apt-get install nodejs -y
apt-get install npm -y
- name: Checkout
uses: actions/checkout@v3
- name: Run Test DB Script
run: ./test_db.sh
- name: Build
run: |
cargo build --release --target $CARGO_TARGET
strip target/$CARGO_TARGET/release/rot
cd frontend && npm install && npm run build
- name: Deploy to Staging
run: |
mkdir ~/.ssh
ssh-keyscan -H $SSH_HOST >> ~/.ssh/known_hosts
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
scp target/$CARGO_TARGET/release/rot $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/rot-updating
scp staging-diff.sql $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/
scp -r static $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/
scp -r templates $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/
scp -r svelte $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/
ssh $SSH_USER@$SSH_HOST 'sudo systemctl stop rotstaging'
ssh $SSH_USER@$SSH_HOST 'rm /home/k004373/rowing-staging/db.sqlite && cp /home/k004373/rowing/db.sqlite /home/k004373/rowing-staging/db.sqlite && mkdir -p /home/k004373/rowing-staging/svelte/build && mkdir -p /home/k004373/rowing-staging/data-ergo/thirty && mkdir -p /home/k004373/rowing-staging/data-ergo/dozen && sqlite3 /home/k004373/rowing-staging/db.sqlite < /home/k004373/rowing-staging/staging-diff.sql'
ssh $SSH_USER@$SSH_HOST 'mv /home/k004373/rowing-staging/rot-updating /home/k004373/rowing-staging/rot'
ssh $SSH_USER@$SSH_HOST 'sudo systemctl start rotstaging'
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
SSH_HOST: ${{ secrets.SSH_HOST }}
SSH_USER: ${{ secrets.SSH_USER }}
deploy-main:
runs-on: ubuntu-latest
container: rust:latest
needs: [test]
if: github.ref == 'refs/heads/main'
steps:
- name: Setup Environment
run: |
rustup target add $CARGO_TARGET
apt-get update -qq && apt-get install -y -qq sshpass musl musl-tools sqlite3 curl gnupg && mkdir -p /etc/apt/keyrings | curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && apt-get update && apt-get install nodejs -y && apt-get install npm -y
- name: Checkout
uses: actions/checkout@v3
- name: Run Test DB Script
run: ./test_db.sh
- name: Build
run: |
cargo build --release --target $CARGO_TARGET
strip target/$CARGO_TARGET/release/rot
cd frontend && npm install && npm run build
- name: Deploy to Main
run: |
mkdir ~/.ssh
ssh-keyscan -H $SSH_HOST >> ~/.ssh/known_hosts
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
scp target/$CARGO_TARGET/release/rot $SSH_USER@$SSH_HOST:/home/k004373/rowing/rot-updating
scp -r static $SSH_USER@$SSH_HOST:/home/k004373/rowing/
scp -r templates $SSH_USER@$SSH_HOST:/home/k004373/rowing/
scp -r svelte $SSH_USER@$SSH_HOST:/home/k004373/rowing/
ssh $SSH_USER@$SSH_HOST 'mkdir -p /home/k004373/rowing/svelte/build && mkdir -p /home/k004373/rowing/data-ergo/thirty && mkdir -p /home/k004373/rowing/data-ergo/dozen'
ssh $SSH_USER@$SSH_HOST 'sudo systemctl stop rot'
ssh $SSH_USER@$SSH_HOST 'mv /home/k004373/rowing/rot-updating /home/k004373/rowing/rot'
ssh $SSH_USER@$SSH_HOST 'sudo systemctl start rot'
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
SSH_HOST: ${{ secrets.SSH_HOST }}
SSH_USER: ${{ secrets.SSH_USER }}

View File

@ -1,70 +0,0 @@
image: rust:latest
variables:
CARGO_TARGET: x86_64-unknown-linux-musl
before_script:
- rustup target add $CARGO_TARGET
- apt-get update -qq && apt-get install -y -qq sshpass musl musl-tools sqlite3 curl gnupg && mkdir -p /etc/apt/keyrings | curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && apt-get update && apt-get install nodejs -y && apt-get install npm -y
- ./test_db.sh
build:
stage: build
script:
- cargo build --release --target $CARGO_TARGET
- strip target/$CARGO_TARGET/release/rot
- cd frontend && npm install && npm run build
artifacts:
paths:
- target/$CARGO_TARGET/release/rot
- static
expire_in: 3 hours
test:
stage: test
image: rust:latest
script:
- cargo test --verbose
deploy-staging:
stage: deploy
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan -H $SSH_HOST > ~/.ssh/known_hosts
script:
- scp target/$CARGO_TARGET/release/rot $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/rot-updating
- scp staging-diff.sql $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/
- scp -r static $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/
- scp -r templates $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/
- scp -r svelte $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/
- ssh $SSH_USER@$SSH_HOST 'sudo systemctl stop rotstaging'
- ssh $SSH_USER@$SSH_HOST 'rm /home/k004373/rowing-staging/db.sqlite && cp /home/k004373/rowing/db.sqlite /home/k004373/rowing-staging/db.sqlite && mkdir -p /home/k004373/rowing-staging/svelte/build && mkdir -p /home/k004373/rowing-staging/data-ergo/thirty && mkdir -p /home/k004373/rowing-staging/data-ergo/dozen && sqlite3 /home/k004373/rowing-staging/db.sqlite < /home/k004373/rowing-staging/staging-diff.sql'
- ssh $SSH_USER@$SSH_HOST 'mv /home/k004373/rowing-staging/rot-updating /home/k004373/rowing-staging/rot'
- ssh $SSH_USER@$SSH_HOST 'sudo systemctl start rotstaging'
only:
- staging
deploy-main:
stage: deploy
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan -H $SSH_HOST > ~/.ssh/known_hosts
script:
- scp target/$CARGO_TARGET/release/rot $SSH_USER@$SSH_HOST:/home/k004373/rowing/rot-updating
- scp -r static $SSH_USER@$SSH_HOST:/home/k004373/rowing/
- scp -r templates $SSH_USER@$SSH_HOST:/home/k004373/rowing/
- scp -r svelte $SSH_USER@$SSH_HOST:/home/k004373/rowing/
- ssh $SSH_USER@$SSH_HOST 'mkdir -p /home/k004373/rowing/svelte/build && mkdir -p /home/k004373/rowing/data-ergo/thirty && mkdir -p /home/k004373/rowing/data-ergo/dozen'
- ssh $SSH_USER@$SSH_HOST 'sudo systemctl stop rot'
- ssh $SSH_USER@$SSH_HOST 'mv /home/k004373/rowing/rot-updating /home/k004373/rowing/rot'
- ssh $SSH_USER@$SSH_HOST 'sudo systemctl start rot'
only:
- main

View File

@ -26,9 +26,9 @@ INSERT INTO "boat" (name, amount_seats, location_id) VALUES ('Ottensheim Boot',
INSERT INTO "boat" (name, amount_seats, location_id, owner) VALUES ('second_private_boat_from_rower', 1, 1, 2); INSERT INTO "boat" (name, amount_seats, location_id, owner) VALUES ('second_private_boat_from_rower', 1, 1, 2);
INSERT INTO "logbook_type" (name) VALUES ('Wanderfahrt'); INSERT INTO "logbook_type" (name) VALUES ('Wanderfahrt');
INSERT INTO "logbook_type" (name) VALUES ('Regatta'); INSERT INTO "logbook_type" (name) VALUES ('Regatta');
INSERT INTO "logbook" (boat_id, shipmaster,steering_person, shipmaster_only_steering, departure) VALUES (2, 2, 2, false, '1142-12-24 10:00'); INSERT INTO "logbook" (boat_id, shipmaster,steering_person, shipmaster_only_steering, departure) VALUES (2, 2, 2, false, strftime('%Y', 'now') || '-12-24 10:00');
INSERT INTO "logbook" (boat_id, shipmaster, steering_person, shipmaster_only_steering, departure, arrival, destination, distance_in_km) VALUES (1, 4, 4, false, '1141-12-24 10:00', '2141-12-24 15:00', 'Ottensheim', 25); INSERT INTO "logbook" (boat_id, shipmaster, steering_person, shipmaster_only_steering, departure, arrival, destination, distance_in_km) VALUES (1, 4, 4, false, strftime('%Y', 'now') || '-12-24 10:00', strftime('%Y', 'now') || '-12-24 15:00', 'Ottensheim', 25);
INSERT INTO "logbook" (boat_id, shipmaster, steering_person, shipmaster_only_steering, departure, arrival, destination, distance_in_km) VALUES (3, 4, 4, false, '1142-12-24 10:00', '2142-12-24 11:30', 'Ottensheim + Regattastrecke', 29); INSERT INTO "logbook" (boat_id, shipmaster, steering_person, shipmaster_only_steering, departure, arrival, destination, distance_in_km) VALUES (3, 4, 4, false, strftime('%Y', 'now') || '-12-24 10:00', strftime('%Y', 'now') || '-12-24 11:30', 'Ottensheim + Regattastrecke', 29);
INSERT INTO "rower" (logbook_id, rower_id) VALUES(3,3); INSERT INTO "rower" (logbook_id, rower_id) VALUES(3,3);
INSERT INTO "boat_damage" (boat_id, desc, user_id_created, created_at) VALUES(4,'Dolle bei Position 2 fehlt', 5, '2142-12-24 15:02'); INSERT INTO "boat_damage" (boat_id, desc, user_id_created, created_at) VALUES(4,'Dolle bei Position 2 fehlt', 5, '2142-12-24 15:02');
INSERT INTO "boat_damage" (boat_id, desc, user_id_created, created_at, lock_boat) VALUES(5, 'TOHT', 5, '2142-12-24 15:02', 1); INSERT INTO "boat_damage" (boat_id, desc, user_id_created, created_at, lock_boat) VALUES(5, 'TOHT', 5, '2142-12-24 15:02', 1);

View File

@ -1,4 +1,4 @@
use chrono::NaiveDateTime; use chrono::{Datelike, NaiveDateTime, Utc};
use rocket::FromForm; use rocket::FromForm;
use serde::Serialize; use serde::Serialize;
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
@ -99,6 +99,7 @@ pub enum LogbookUpdateError {
ShipmasterNotInRowers, ShipmasterNotInRowers,
SteeringPersonNotInRowers, SteeringPersonNotInRowers,
UserNotAllowedToUseBoat, UserNotAllowedToUseBoat,
OnlyAllowedToEndTripsEndingToday,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -120,6 +121,7 @@ pub enum LogbookCreateError {
ShipmasterNotInRowers, ShipmasterNotInRowers,
NotYourEntry, NotYourEntry,
ArrivalSetButNotRemainingTwo, ArrivalSetButNotRemainingTwo,
OnlyAllowedToEndTripsEndingToday,
} }
impl From<LogbookUpdateError> for LogbookCreateError { impl From<LogbookUpdateError> for LogbookCreateError {
@ -140,6 +142,9 @@ impl From<LogbookUpdateError> for LogbookCreateError {
LogbookUpdateError::UserNotAllowedToUseBoat => { LogbookUpdateError::UserNotAllowedToUseBoat => {
LogbookCreateError::UserNotAllowedToUseBoat LogbookCreateError::UserNotAllowedToUseBoat
} }
LogbookUpdateError::OnlyAllowedToEndTripsEndingToday => {
LogbookCreateError::OnlyAllowedToEndTripsEndingToday
}
} }
} }
} }
@ -220,14 +225,14 @@ ORDER BY departure DESC
} }
pub async fn completed(db: &SqlitePool) -> Vec<LogbookWithBoatAndRowers> { pub async fn completed(db: &SqlitePool) -> Vec<LogbookWithBoatAndRowers> {
let logs = sqlx::query_as!( let year = chrono::Utc::now().year();
Logbook, let logs = sqlx::query_as(
" &format!("
SELECT id, boat_id, shipmaster, steering_person, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype SELECT id, boat_id, shipmaster, steering_person, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype
FROM logbook FROM logbook
WHERE arrival is not null WHERE arrival is not null AND arrival LIKE '{}-%'
ORDER BY departure DESC ORDER BY departure DESC
" ", year)
) )
.fetch_all(db) .fetch_all(db)
.await .await
@ -446,13 +451,8 @@ ORDER BY departure DESC
} }
if !boat.shipmaster_allowed(user).await && self.shipmaster != user.id { if !boat.shipmaster_allowed(user).await && self.shipmaster != user.id {
//second part: //second part: shipmaster has entered a different user, then the user should be able to
//shipmaster has //`home` it
//entered a
//different user,
//then the user
//should be able
//to `home` it
return Err(LogbookUpdateError::UserNotAllowedToUseBoat); return Err(LogbookUpdateError::UserNotAllowedToUseBoat);
} }
@ -468,6 +468,10 @@ ORDER BY departure DESC
if arr.timestamp() <= dep.timestamp() { if arr.timestamp() <= dep.timestamp() {
return Err(LogbookUpdateError::ArrivalNotAfterDeparture); return Err(LogbookUpdateError::ArrivalNotAfterDeparture);
} }
let today = Utc::now().date_naive();
if arr.date() != today && !user.is_admin {
return Err(LogbookUpdateError::OnlyAllowedToEndTripsEndingToday);
}
Log::create_with_tx(db, format!("New trip: {log:?}")).await; Log::create_with_tx(db, format!("New trip: {log:?}")).await;
@ -549,11 +553,11 @@ mod test {
assert_eq!( assert_eq!(
completed[0].logbook, completed[0].logbook,
Logbook::find_by_id(&pool, 3).await.unwrap() Logbook::find_by_id(&pool, 2).await.unwrap()
); );
assert_eq!( assert_eq!(
completed[1].logbook, completed[1].logbook,
Logbook::find_by_id(&pool, 2).await.unwrap() Logbook::find_by_id(&pool, 3).await.unwrap()
); );
} }
@ -793,6 +797,8 @@ mod test {
let logbook = Logbook::find_by_id(&pool, 1).await.unwrap(); let logbook = Logbook::find_by_id(&pool, 1).await.unwrap();
let user = User::find_by_id(&pool, 2).await.unwrap(); let user = User::find_by_id(&pool, 2).await.unwrap();
let current_date = chrono::Local::now().format("%Y-%m-%d").to_string();
logbook logbook
.home( .home(
&pool, &pool,
@ -806,8 +812,8 @@ mod test {
shipmaster: Some(2), shipmaster: Some(2),
steering_person: Some(2), steering_person: Some(2),
shipmaster_only_steering: false, shipmaster_only_steering: false,
departure: "1990-01-01T10:00".into(), departure: format!("{}T10:00", current_date),
arrival: "1990-01-01T12:00".into(), arrival: format!("{}T12:00", current_date),
}, },
) )
.await .await

View File

@ -1,4 +1,5 @@
use crate::model::user::User; use crate::model::user::User;
use chrono::Datelike;
use serde::Serialize; use serde::Serialize;
use sqlx::{FromRow, Row, SqlitePool}; use sqlx::{FromRow, Row, SqlitePool};
@ -9,15 +10,20 @@ pub struct Stat {
} }
impl Stat { impl Stat {
pub async fn boats(db: &SqlitePool) -> Vec<Stat> { pub async fn boats(db: &SqlitePool, year: Option<i32>) -> Vec<Stat> {
let year = match year {
Some(year) => year,
None => chrono::Utc::now().year(),
};
//TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server) //TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server)
sqlx::query( sqlx::query(&format!(
" "
SELECT (SELECT name FROM boat WHERE id=logbook.boat_id) as name, CAST(SUM(distance_in_km) AS INTEGER) AS rowed_km SELECT (SELECT name FROM boat WHERE id=logbook.boat_id) as name, CAST(SUM(distance_in_km) AS INTEGER) AS rowed_km
FROM logbook FROM logbook
WHERE arrival LIKE '{}-%'
GROUP BY boat_id GROUP BY boat_id
ORDER BY rowed_km DESC; ORDER BY rowed_km DESC;
", ",year)
) )
.fetch_all(db) .fetch_all(db)
.await .await
@ -30,19 +36,24 @@ ORDER BY rowed_km DESC;
.collect() .collect()
} }
pub async fn people(db: &SqlitePool) -> Vec<Stat> { pub async fn people(db: &SqlitePool, year: Option<i32>) -> Vec<Stat> {
let year = match year {
Some(year) => year,
None => chrono::Utc::now().year(),
};
//TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server) //TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server)
sqlx::query( sqlx::query(&format!(
" "
SELECT u.name, CAST(SUM(l.distance_in_km) AS INTEGER) AS rowed_km SELECT u.name, CAST(SUM(l.distance_in_km) AS INTEGER) AS rowed_km
FROM user u FROM user u
INNER JOIN rower r ON u.id = r.rower_id INNER JOIN rower r ON u.id = r.rower_id
INNER JOIN logbook l ON r.logbook_id = l.id INNER JOIN logbook l ON r.logbook_id = l.id
WHERE u.is_guest = 0 AND l.distance_in_km IS NOT NULL WHERE u.is_guest = 0 AND l.distance_in_km IS NOT NULL AND l.arrival LIKE '{}-%'
GROUP BY u.name GROUP BY u.name
ORDER BY rowed_km DESC; ORDER BY rowed_km DESC;
", ",
) year
))
.fetch_all(db) .fetch_all(db)
.await .await
.unwrap() .unwrap()

View File

@ -182,6 +182,7 @@ async fn create_logbook(
Err(LogbookCreateError::ShipmasterNotInRowers) => Flash::error(Redirect::to("/log"), "Schiffsführer nicht in Liste der Ruderer!"), Err(LogbookCreateError::ShipmasterNotInRowers) => Flash::error(Redirect::to("/log"), "Schiffsführer nicht in Liste der Ruderer!"),
Err(LogbookCreateError::NotYourEntry) => Flash::error(Redirect::to("/log"), "Nicht deine Ausfahrt!"), Err(LogbookCreateError::NotYourEntry) => Flash::error(Redirect::to("/log"), "Nicht deine Ausfahrt!"),
Err(LogbookCreateError::ArrivalSetButNotRemainingTwo) => Flash::error(Redirect::to("/log"), "Ankunftszeit gesetzt aber nicht Distanz + Strecke"), Err(LogbookCreateError::ArrivalSetButNotRemainingTwo) => Flash::error(Redirect::to("/log"), "Ankunftszeit gesetzt aber nicht Distanz + Strecke"),
Err(LogbookCreateError::OnlyAllowedToEndTripsEndingToday) => Flash::error(Redirect::to("/log"), format!("Nur Ausfahrten, die heute enden dürfen eingetragen werden. Für einen Nachtrag schreibe alle Daten Philipp (Tel. nr. siehe Signal oder it@rudernlinz.at).")),
} }
} }
@ -251,6 +252,7 @@ async fn home_logbook(
match logbook.home(db, &user.user, data.into_inner()).await { match logbook.home(db, &user.user, data.into_inner()).await {
Ok(_) => Flash::success(Redirect::to("/log"), "Ausfahrt korrekt eingetragen"), Ok(_) => Flash::success(Redirect::to("/log"), "Ausfahrt korrekt eingetragen"),
Err(LogbookUpdateError::TooManyRowers(expected, actual)) => Flash::error(Redirect::to("/log"), format!("Zu viele Ruderer (Boot fasst maximal {expected}, es wurden jedoch {actual} Ruderer ausgewählt)")), Err(LogbookUpdateError::TooManyRowers(expected, actual)) => Flash::error(Redirect::to("/log"), format!("Zu viele Ruderer (Boot fasst maximal {expected}, es wurden jedoch {actual} Ruderer ausgewählt)")),
Err(LogbookUpdateError::OnlyAllowedToEndTripsEndingToday) => Flash::error(Redirect::to("/log"), format!("Nur Ausfahrten, die heute enden dürfen eingetragen werden. Für einen Nachtrag schreibe alle Daten Philipp (Tel. nr. siehe Signal oder it@rudernlinz.at).")),
Err(e) => Flash::error( Err(e) => Flash::error(
Redirect::to("/log"), Redirect::to("/log"),
format!("Eintrag {logbook_id} konnte nicht abgesendet werden (Fehler: {e:?})!"), format!("Eintrag {logbook_id} konnte nicht abgesendet werden (Fehler: {e:?})!"),
@ -522,11 +524,12 @@ mod test {
.header(ContentType::Form) // Set the content type to form .header(ContentType::Form) // Set the content type to form
.body("name=admin&password=admin"); // Add the form data to the request body; .body("name=admin&password=admin"); // Add the form data to the request body;
login.dispatch().await; login.dispatch().await;
let current_date = chrono::Local::now().format("%Y-%m-%d").to_string();
let req = client let req = client.post("/log").header(ContentType::Form).body(format!(
.post("/log") "boat_id=1&shipmaster=4&departure={0}T10:00&steering_person=4&rowers[]=4",
.header(ContentType::Form) current_date
.body("boat_id=1&shipmaster=4&departure=2199-12-31T10:00&steering_person=4&rowers[]=4"); ));
let response = req.dispatch().await; let response = req.dispatch().await;
assert_eq!(response.status(), Status::SeeOther); assert_eq!(response.status(), Status::SeeOther);
@ -554,10 +557,12 @@ mod test {
let req = client.get("/log/kiosk/ekrv2019/Linz"); let req = client.get("/log/kiosk/ekrv2019/Linz");
let _ = req.dispatch().await; let _ = req.dispatch().await;
let current_date = chrono::Local::now().format("%Y-%m-%d").to_string();
let req = client let req = client
.post("/log/1") .post("/log/1")
.header(ContentType::Form) .header(ContentType::Form)
.body("destination=Ottensheim&distance_in_km=25&shipmaster=2&steering_person=2&departure=1990-01-01T10:00&arrival=1990-01-01T12:00&rowers[]=2"); .body(format!("destination=Ottensheim&distance_in_km=25&shipmaster=2&steering_person=2&departure={0}T10:00&arrival={0}T12:00&rowers[]=2", current_date));
let response = req.dispatch().await; let response = req.dispatch().await;
assert_eq!(response.status(), Status::SeeOther); assert_eq!(response.status(), Status::SeeOther);
@ -664,9 +669,10 @@ mod test {
.unwrap() .unwrap()
.id; .id;
let shipmaster_id = User::find_by_name(&db, "rower2".into()).await.unwrap().id; let shipmaster_id = User::find_by_name(&db, "rower2".into()).await.unwrap().id;
let current_date = chrono::Local::now().format("%Y-%m-%d").to_string();
let req = client.post("/log").header(ContentType::Form).body(format!( let req = client.post("/log").header(ContentType::Form).body(format!(
"boat_id={boat_id}&shipmaster={shipmaster_id}&departure=1199-12-31T10:00&steering_person={shipmaster_id}&rowers[]={shipmaster_id}" "boat_id={boat_id}&shipmaster={shipmaster_id}&departure={0}T10:00&steering_person={shipmaster_id}&rowers[]={shipmaster_id}", current_date
)); ));
let response = req.dispatch().await; let response = req.dispatch().await;
@ -695,7 +701,7 @@ mod test {
let req = client let req = client
.post(format!("/log/{log_id}")) .post(format!("/log/{log_id}"))
.header(ContentType::Form) .header(ContentType::Form)
.body(format!("destination=Ottensheim&distance_in_km=25&shipmaster={shipmaster_id}&steering_person={shipmaster_id}&departure=1990-01-01T10:00&arrival=1990-01-01T12:00&rowers[]={shipmaster_id}")); .body(format!("destination=Ottensheim&distance_in_km=25&shipmaster={shipmaster_id}&steering_person={shipmaster_id}&departure={0}T10:00&arrival={0}T12:00&rowers[]={shipmaster_id}", current_date));
let response = req.dispatch().await; let response = req.dispatch().await;
assert_eq!(response.status(), Status::SeeOther); assert_eq!(response.status(), Status::SeeOther);
@ -882,11 +888,12 @@ mod test {
.header(ContentType::Form) // Set the content type to form .header(ContentType::Form) // Set the content type to form
.body("name=rower2&password=rower"); // Add the form data to the request body; .body("name=rower2&password=rower"); // Add the form data to the request body;
login.dispatch().await; login.dispatch().await;
let current_date = chrono::Local::now().format("%Y-%m-%d").to_string();
let req = client let req = client
.post("/log/1") .post("/log/1")
.header(ContentType::Form) .header(ContentType::Form)
.body("destination=Ottensheim&distance_in_km=25&shipmaster=1&steering_person=1&departure=1199-12-12T10:00&arrival=1199-12-12T12:00&rowers[]=1"); .body(format!("destination=Ottensheim&distance_in_km=25&shipmaster=1&steering_person=1&departure={0}T10:00&arrival={0}T12:00&rowers[]=1", current_date));
let response = req.dispatch().await; let response = req.dispatch().await;
assert_eq!(response.status(), Status::SeeOther); assert_eq!(response.status(), Status::SeeOther);
@ -912,8 +919,10 @@ mod test {
let boat_id = Boat::find_by_name(db, boat_name).await.unwrap().id; let boat_id = Boat::find_by_name(db, boat_name).await.unwrap().id;
let shipmaster_id = User::find_by_name(db, &shipmaster_name).await.unwrap().id; let shipmaster_id = User::find_by_name(db, &shipmaster_name).await.unwrap().id;
let current_date = chrono::Local::now().format("%Y-%m-%d").to_string();
let req = client.post("/log").header(ContentType::Form).body(format!( let req = client.post("/log").header(ContentType::Form).body(format!(
"boat_id={boat_id}&shipmaster={shipmaster_id}&departure=1199-12-31T10:00&steering_person={shipmaster_id}&rowers[]={shipmaster_id}" "boat_id={boat_id}&shipmaster={shipmaster_id}&departure={current_date}T10:00&steering_person={shipmaster_id}&rowers[]={shipmaster_id}"
)); ));
let response = req.dispatch().await; let response = req.dispatch().await;
@ -935,7 +944,7 @@ mod test {
let req = client let req = client
.post(format!("/log/{log_id}")) .post(format!("/log/{log_id}"))
.header(ContentType::Form) .header(ContentType::Form)
.body(format!("destination=Ottensheim&distance_in_km=25&shipmaster={shipmaster_id}&steering_person={shipmaster_id}&departure=1199-12-31T10:00&arrival=1199-12-31T12:00&rowers[]={shipmaster_id}")); .body(format!("destination=Ottensheim&distance_in_km=25&shipmaster={shipmaster_id}&steering_person={shipmaster_id}&departure={current_date}T10:00&arrival={current_date}T12:00&rowers[]={shipmaster_id}"));
let response = req.dispatch().await; let response = req.dispatch().await;
assert_eq!(response.status(), Status::SeeOther); assert_eq!(response.status(), Status::SeeOther);
@ -962,8 +971,10 @@ mod test {
let boat_id = Boat::find_by_name(db, boat_name).await.unwrap().id; let boat_id = Boat::find_by_name(db, boat_name).await.unwrap().id;
let shipmaster_id = User::find_by_name(db, &shipmaster_name).await.unwrap().id; let shipmaster_id = User::find_by_name(db, &shipmaster_name).await.unwrap().id;
let current_date = chrono::Local::now().format("%Y-%m-%d").to_string();
let req = client.post("/log").header(ContentType::Form).body(format!( let req = client.post("/log").header(ContentType::Form).body(format!(
"boat_id={boat_id}&shipmaster={shipmaster_id}&departure=2199-12-31T10:00&steering_person={shipmaster_id}&rowers[]={shipmaster_id}" "boat_id={boat_id}&shipmaster={shipmaster_id}&departure={current_date}T10:00&steering_person={shipmaster_id}&rowers[]={shipmaster_id}"
)); ));
let response = req.dispatch().await; let response = req.dispatch().await;

View File

@ -9,9 +9,9 @@ use crate::model::{
use super::log::KioskCookie; use super::log::KioskCookie;
#[get("/boats", rank = 2)] #[get("/boats?<year>", rank = 2)]
async fn index_boat(db: &State<SqlitePool>, user: NonGuestUser) -> Template { async fn index_boat(db: &State<SqlitePool>, user: NonGuestUser, year: Option<i32>) -> Template {
let stat = Stat::boats(db).await; let stat = Stat::boats(db, year).await;
let kiosk = false; let kiosk = false;
Template::render( Template::render(
@ -20,17 +20,21 @@ async fn index_boat(db: &State<SqlitePool>, user: NonGuestUser) -> Template {
) )
} }
#[get("/boats")] #[get("/boats?<year>")]
async fn index_boat_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie) -> Template { async fn index_boat_kiosk(
let stat = Stat::boats(db).await; db: &State<SqlitePool>,
_kiosk: KioskCookie,
year: Option<i32>,
) -> Template {
let stat = Stat::boats(db, year).await;
let kiosk = true; let kiosk = true;
Template::render("stat.boats", context!(stat, kiosk, show_kiosk_header: true)) Template::render("stat.boats", context!(stat, kiosk, show_kiosk_header: true))
} }
#[get("/", rank = 2)] #[get("/?<year>", rank = 2)]
async fn index(db: &State<SqlitePool>, user: NonGuestUser) -> Template { async fn index(db: &State<SqlitePool>, user: NonGuestUser, year: Option<i32>) -> Template {
let stat = Stat::people(db).await; let stat = Stat::people(db, year).await;
let personal = stat::get_personal(db, &user.user).await; let personal = stat::get_personal(db, &user.user).await;
let kiosk = false; let kiosk = false;
@ -40,9 +44,9 @@ async fn index(db: &State<SqlitePool>, user: NonGuestUser) -> Template {
) )
} }
#[get("/")] #[get("/?<year>")]
async fn index_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie) -> Template { async fn index_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie, year: Option<i32>) -> Template {
let stat = Stat::people(db).await; let stat = Stat::people(db, year).await;
let kiosk = true; let kiosk = true;
Template::render( Template::render(

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
<div class="max-w-screen-xl w-full flex justify-between items-center"> <div class="max-w-screen-xl w-full flex justify-between items-center">
<div> <div>
<span class="text-[#ff0000]">&hearts;</span> <span class="text-[#ff0000]">&hearts;</span>
ASKÖ Ruderverein Donau Linz <small class="text-primary-100">&copy; {{ now() | date(format="%Y") }}</smalL> Erstellt vom ASKÖ Ruderverein Donau Linz <a onclick="alert('Wir suchen kreative und motivierte Köpfe, die diesen Ruderassistenten mitgestalten möchten. Das Backend ist in Rust (Rocket), das Frontend in TypeScript und Teraform, wobei wir mit dem Gedanken spielen, zu Svelte(Kit) zu wechseln.\n\nWenn du Lust hast, deine Skills in ein Projekt zu stecken, das Wellen schlagen wird, dann komm an Bord! Wir sind offen für frische Ideen, haben jedoch auch selber noch genügend; langweilig wird uns bestimmt nicht.\n\nWirf den Anker bei uns ausi und melde dich bei Marie oder Philipp oder it@rudernlinz.at für eine Zukunft ohne optische Kenterung in Form von hässlichen Alerts ;)');" style="text-decoration:underline">... und dir?</a>
</div> </div>
<div> <div>

View File

@ -8,7 +8,7 @@
{{ macros::alert(message=flash.1, type=flash.0, class="sm:col-span-2 lg:col-span-3") }} {{ macros::alert(message=flash.1, type=flash.0, class="sm:col-span-2 lg:col-span-3") }}
{% endif %} {% endif %}
<h1 class="h1 sm:col-span-2 lg:col-span-3">Ausfahrten</h1> <h1 class="h1 sm:col-span-2 lg:col-span-3">Ausfahrten!</h1>
{% include "includes/buttons" %} {% include "includes/buttons" %}