Compare commits
20 Commits
429f0c1ddc
...
main
Author | SHA1 | Date | |
---|---|---|---|
539d299c1a | |||
f0936c7784 | |||
59478a5ee1 | |||
2f5d483bff | |||
7be9339645 | |||
837d0febdf | |||
51c7cf28f8 | |||
80eca1a3b2 | |||
d1341006f7 | |||
a534568a39 | |||
b4c04cbdd8 | |||
1f0bfb04e4 | |||
86b8d3a30d | |||
da7a303efb | |||
0a31410ca5 | |||
f793cb4a9a | |||
d3b2d78f9f | |||
155adce2e9 | |||
9548cb4f0b | |||
c42713b86e |
@@ -63,16 +63,16 @@ jobs:
|
|||||||
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
|
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
|
||||||
chmod 600 ~/.ssh/id_rsa
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
|
||||||
scp -C target/$CARGO_TARGET/release/rot $SSH_USER@$SSH_HOST:/home/rowing-staging/rot-updating
|
scp -C target/$CARGO_TARGET/release/rot $SSH_USER@$SSH_HOST:/root/rowing-staging/rot-updating
|
||||||
|
|
||||||
scp -C staging-diff.sql $SSH_USER@$SSH_HOST:/home/rowing-staging/
|
scp -C staging-diff.sql $SSH_USER@$SSH_HOST:/root/rowing-staging/
|
||||||
scp -C -r static $SSH_USER@$SSH_HOST:/home/rowing-staging/
|
scp -C -r static $SSH_USER@$SSH_HOST:/root/rowing-staging/
|
||||||
scp -C -r templates $SSH_USER@$SSH_HOST:/home/rowing-staging/
|
scp -C -r templates $SSH_USER@$SSH_HOST:/root/rowing-staging/
|
||||||
scp -C -r svelte $SSH_USER@$SSH_HOST:/home/rowing-staging/
|
scp -C -r svelte $SSH_USER@$SSH_HOST:/root/rowing-staging/
|
||||||
ssh $SSH_USER@$SSH_HOST 'sudo systemctl stop rotstaging'
|
ssh $SSH_USER@$SSH_HOST 'sudo systemctl stop rowing-staging'
|
||||||
ssh $SSH_USER@$SSH_HOST 'rm /home/rowing-staging/db.sqlite && cp /home/rowing/db.sqlite /home/rowing-staging/db.sqlite && mkdir -p /home/rowing-staging/svelte/build && mkdir -p /home/rowing-staging/data-ergo/thirty && mkdir -p /home/rowing-staging/data-ergo/dozen && sqlite3 /home/rowing-staging/db.sqlite < /home/rowing-staging/staging-diff.sql'
|
ssh $SSH_USER@$SSH_HOST 'rm /root/rowing-staging/db.sqlite && cp /root/rowing/db.sqlite /root/rowing-staging/db.sqlite && mkdir -p /root/rowing-staging/svelte/build && mkdir -p /root/rowing-staging/data-ergo/thirty && mkdir -p /root/rowing-staging/data-ergo/dozen && sqlite3 /root/rowing-staging/db.sqlite < /root/rowing-staging/staging-diff.sql'
|
||||||
ssh $SSH_USER@$SSH_HOST 'mv /home/rowing-staging/rot-updating /home/rowing-staging/rot'
|
ssh $SSH_USER@$SSH_HOST 'mv /home/rowing-staging/rot-updating /home/rowing-staging/rot'
|
||||||
ssh $SSH_USER@$SSH_HOST 'sudo systemctl start rotstaging'
|
ssh $SSH_USER@$SSH_HOST 'sudo systemctl start rowing-staging'
|
||||||
env:
|
env:
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
SSH_HOST: ${{ secrets.SSH_HOST }}
|
SSH_HOST: ${{ secrets.SSH_HOST }}
|
||||||
@@ -106,14 +106,14 @@ jobs:
|
|||||||
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
|
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
|
||||||
chmod 600 ~/.ssh/id_rsa
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
|
||||||
scp -C target/$CARGO_TARGET/release/rot $SSH_USER@$SSH_HOST:/home/rowing/rot-updating
|
scp -C target/$CARGO_TARGET/release/rot $SSH_USER@$SSH_HOST:/root/rowing-prod/rot-updating
|
||||||
scp -C -r static $SSH_USER@$SSH_HOST:/home/rowing/
|
scp -C -r static $SSH_USER@$SSH_HOST:/root/rowing-prod/
|
||||||
scp -C -r templates $SSH_USER@$SSH_HOST:/home/rowing/
|
scp -C -r templates $SSH_USER@$SSH_HOST:/root/rowing-prod/
|
||||||
scp -C -r svelte $SSH_USER@$SSH_HOST:/home/rowing/
|
scp -C -r svelte $SSH_USER@$SSH_HOST:/root/rowing-prod/
|
||||||
ssh $SSH_USER@$SSH_HOST 'mkdir -p /home/rowing/svelte/build && mkdir -p /home/rowing/data-ergo/thirty && mkdir -p /home/rowing/data-ergo/dozen'
|
ssh $SSH_USER@$SSH_HOST 'mkdir -p /root/rowing-prod/svelte/build && mkdir -p /root/rowing-prod/data-ergo/thirty && mkdir -p /root/rowing-prod/data-ergo/dozen'
|
||||||
ssh $SSH_USER@$SSH_HOST 'sudo systemctl stop rot'
|
ssh $SSH_USER@$SSH_HOST 'sudo systemctl stop rowing-prod'
|
||||||
ssh $SSH_USER@$SSH_HOST 'mv /home/rowing/rot-updating /home/rowing/rot'
|
ssh $SSH_USER@$SSH_HOST 'mv /root/rowing-prod/rot-updating /root/rowing-prod/rot'
|
||||||
ssh $SSH_USER@$SSH_HOST 'sudo systemctl start rot'
|
ssh $SSH_USER@$SSH_HOST 'sudo systemctl start rowing-prod'
|
||||||
env:
|
env:
|
||||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
SSH_HOST: ${{ secrets.SSH_HOST }}
|
SSH_HOST: ${{ secrets.SSH_HOST }}
|
||||||
|
@@ -31,7 +31,7 @@ jobs:
|
|||||||
- Run `cargo upgrade` to update version requirements in Cargo.toml
|
- Run `cargo upgrade` to update version requirements in Cargo.toml
|
||||||
- Run `cargo update` to update Cargo.lock
|
- Run `cargo update` to update Cargo.lock
|
||||||
branch: update-cargo-dependencies
|
branch: update-cargo-dependencies
|
||||||
delete-branch: true
|
delete-branch: false
|
||||||
|
|
||||||
- name: Create Pull Request Main
|
- name: Create Pull Request Main
|
||||||
uses: https://git.hofer.link/philipp/create-pull-request@18ef1fdad70eec569ab10292c1fa79c1b5296370
|
uses: https://git.hofer.link/philipp/create-pull-request@18ef1fdad70eec569ab10292c1fa79c1b5296370
|
||||||
|
287
LICENSE
Normal file
287
LICENSE
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
EUROPEAN UNION PUBLIC LICENCE v. 1.2
|
||||||
|
EUPL © the European Union 2007, 2016
|
||||||
|
|
||||||
|
This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined
|
||||||
|
below) which is provided under the terms of this Licence. Any use of the Work,
|
||||||
|
other than as authorised under this Licence is prohibited (to the extent such
|
||||||
|
use is covered by a right of the copyright holder of the Work).
|
||||||
|
|
||||||
|
The Work is provided under the terms of this Licence when the Licensor (as
|
||||||
|
defined below) has placed the following notice immediately following the
|
||||||
|
copyright notice for the Work:
|
||||||
|
|
||||||
|
Licensed under the EUPL
|
||||||
|
|
||||||
|
or has expressed by any other means his willingness to license under the EUPL.
|
||||||
|
|
||||||
|
1. Definitions
|
||||||
|
|
||||||
|
In this Licence, the following terms have the following meaning:
|
||||||
|
|
||||||
|
- ‘The Licence’: this Licence.
|
||||||
|
|
||||||
|
- ‘The Original Work’: the work or software distributed or communicated by the
|
||||||
|
Licensor under this Licence, available as Source Code and also as Executable
|
||||||
|
Code as the case may be.
|
||||||
|
|
||||||
|
- ‘Derivative Works’: the works or software that could be created by the
|
||||||
|
Licensee, based upon the Original Work or modifications thereof. This Licence
|
||||||
|
does not define the extent of modification or dependence on the Original Work
|
||||||
|
required in order to classify a work as a Derivative Work; this extent is
|
||||||
|
determined by copyright law applicable in the country mentioned in Article 15.
|
||||||
|
|
||||||
|
- ‘The Work’: the Original Work or its Derivative Works.
|
||||||
|
|
||||||
|
- ‘The Source Code’: the human-readable form of the Work which is the most
|
||||||
|
convenient for people to study and modify.
|
||||||
|
|
||||||
|
- ‘The Executable Code’: any code which has generally been compiled and which is
|
||||||
|
meant to be interpreted by a computer as a program.
|
||||||
|
|
||||||
|
- ‘The Licensor’: the natural or legal person that distributes or communicates
|
||||||
|
the Work under the Licence.
|
||||||
|
|
||||||
|
- ‘Contributor(s)’: any natural or legal person who modifies the Work under the
|
||||||
|
Licence, or otherwise contributes to the creation of a Derivative Work.
|
||||||
|
|
||||||
|
- ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of
|
||||||
|
the Work under the terms of the Licence.
|
||||||
|
|
||||||
|
- ‘Distribution’ or ‘Communication’: any act of selling, giving, lending,
|
||||||
|
renting, distributing, communicating, transmitting, or otherwise making
|
||||||
|
available, online or offline, copies of the Work or providing access to its
|
||||||
|
essential functionalities at the disposal of any other natural or legal
|
||||||
|
person.
|
||||||
|
|
||||||
|
2. Scope of the rights granted by the Licence
|
||||||
|
|
||||||
|
The Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
|
||||||
|
sublicensable licence to do the following, for the duration of copyright vested
|
||||||
|
in the Original Work:
|
||||||
|
|
||||||
|
- use the Work in any circumstance and for all usage,
|
||||||
|
- reproduce the Work,
|
||||||
|
- modify the Work, and make Derivative Works based upon the Work,
|
||||||
|
- communicate to the public, including the right to make available or display
|
||||||
|
the Work or copies thereof to the public and perform publicly, as the case may
|
||||||
|
be, the Work,
|
||||||
|
- distribute the Work or copies thereof,
|
||||||
|
- lend and rent the Work or copies thereof,
|
||||||
|
- sublicense rights in the Work or copies thereof.
|
||||||
|
|
||||||
|
Those rights can be exercised on any media, supports and formats, whether now
|
||||||
|
known or later invented, as far as the applicable law permits so.
|
||||||
|
|
||||||
|
In the countries where moral rights apply, the Licensor waives his right to
|
||||||
|
exercise his moral right to the extent allowed by law in order to make effective
|
||||||
|
the licence of the economic rights here above listed.
|
||||||
|
|
||||||
|
The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to
|
||||||
|
any patents held by the Licensor, to the extent necessary to make use of the
|
||||||
|
rights granted on the Work under this Licence.
|
||||||
|
|
||||||
|
3. Communication of the Source Code
|
||||||
|
|
||||||
|
The Licensor may provide the Work either in its Source Code form, or as
|
||||||
|
Executable Code. If the Work is provided as Executable Code, the Licensor
|
||||||
|
provides in addition a machine-readable copy of the Source Code of the Work
|
||||||
|
along with each copy of the Work that the Licensor distributes or indicates, in
|
||||||
|
a notice following the copyright notice attached to the Work, a repository where
|
||||||
|
the Source Code is easily and freely accessible for as long as the Licensor
|
||||||
|
continues to distribute or communicate the Work.
|
||||||
|
|
||||||
|
4. Limitations on copyright
|
||||||
|
|
||||||
|
Nothing in this Licence is intended to deprive the Licensee of the benefits from
|
||||||
|
any exception or limitation to the exclusive rights of the rights owners in the
|
||||||
|
Work, of the exhaustion of those rights or of other applicable limitations
|
||||||
|
thereto.
|
||||||
|
|
||||||
|
5. Obligations of the Licensee
|
||||||
|
|
||||||
|
The grant of the rights mentioned above is subject to some restrictions and
|
||||||
|
obligations imposed on the Licensee. Those obligations are the following:
|
||||||
|
|
||||||
|
Attribution right: The Licensee shall keep intact all copyright, patent or
|
||||||
|
trademarks notices and all notices that refer to the Licence and to the
|
||||||
|
disclaimer of warranties. The Licensee must include a copy of such notices and a
|
||||||
|
copy of the Licence with every copy of the Work he/she distributes or
|
||||||
|
communicates. The Licensee must cause any Derivative Work to carry prominent
|
||||||
|
notices stating that the Work has been modified and the date of modification.
|
||||||
|
|
||||||
|
Copyleft clause: If the Licensee distributes or communicates copies of the
|
||||||
|
Original Works or Derivative Works, this Distribution or Communication will be
|
||||||
|
done under the terms of this Licence or of a later version of this Licence
|
||||||
|
unless the Original Work is expressly distributed only under this version of the
|
||||||
|
Licence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee
|
||||||
|
(becoming Licensor) cannot offer or impose any additional terms or conditions on
|
||||||
|
the Work or Derivative Work that alter or restrict the terms of the Licence.
|
||||||
|
|
||||||
|
Compatibility clause: If the Licensee Distributes or Communicates Derivative
|
||||||
|
Works or copies thereof based upon both the Work and another work licensed under
|
||||||
|
a Compatible Licence, this Distribution or Communication can be done under the
|
||||||
|
terms of this Compatible Licence. For the sake of this clause, ‘Compatible
|
||||||
|
Licence’ refers to the licences listed in the appendix attached to this Licence.
|
||||||
|
Should the Licensee's obligations under the Compatible Licence conflict with
|
||||||
|
his/her obligations under this Licence, the obligations of the Compatible
|
||||||
|
Licence shall prevail.
|
||||||
|
|
||||||
|
Provision of Source Code: When distributing or communicating copies of the Work,
|
||||||
|
the Licensee will provide a machine-readable copy of the Source Code or indicate
|
||||||
|
a repository where this Source will be easily and freely available for as long
|
||||||
|
as the Licensee continues to distribute or communicate the Work.
|
||||||
|
|
||||||
|
Legal Protection: This Licence does not grant permission to use the trade names,
|
||||||
|
trademarks, service marks, or names of the Licensor, except as required for
|
||||||
|
reasonable and customary use in describing the origin of the Work and
|
||||||
|
reproducing the content of the copyright notice.
|
||||||
|
|
||||||
|
6. Chain of Authorship
|
||||||
|
|
||||||
|
The original Licensor warrants that the copyright in the Original Work granted
|
||||||
|
hereunder is owned by him/her or licensed to him/her and that he/she has the
|
||||||
|
power and authority to grant the Licence.
|
||||||
|
|
||||||
|
Each Contributor warrants that the copyright in the modifications he/she brings
|
||||||
|
to the Work are owned by him/her or licensed to him/her and that he/she has the
|
||||||
|
power and authority to grant the Licence.
|
||||||
|
|
||||||
|
Each time You accept the Licence, the original Licensor and subsequent
|
||||||
|
Contributors grant You a licence to their contributions to the Work, under the
|
||||||
|
terms of this Licence.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty
|
||||||
|
|
||||||
|
The Work is a work in progress, which is continuously improved by numerous
|
||||||
|
Contributors. It is not a finished work and may therefore contain defects or
|
||||||
|
‘bugs’ inherent to this type of development.
|
||||||
|
|
||||||
|
For the above reason, the Work is provided under the Licence on an ‘as is’ basis
|
||||||
|
and without warranties of any kind concerning the Work, including without
|
||||||
|
limitation merchantability, fitness for a particular purpose, absence of defects
|
||||||
|
or errors, accuracy, non-infringement of intellectual property rights other than
|
||||||
|
copyright as stated in Article 6 of this Licence.
|
||||||
|
|
||||||
|
This disclaimer of warranty is an essential part of the Licence and a condition
|
||||||
|
for the grant of any rights to the Work.
|
||||||
|
|
||||||
|
8. Disclaimer of Liability
|
||||||
|
|
||||||
|
Except in the cases of wilful misconduct or damages directly caused to natural
|
||||||
|
persons, the Licensor will in no event be liable for any direct or indirect,
|
||||||
|
material or moral, damages of any kind, arising out of the Licence or of the use
|
||||||
|
of the Work, including without limitation, damages for loss of goodwill, work
|
||||||
|
stoppage, computer failure or malfunction, loss of data or any commercial
|
||||||
|
damage, even if the Licensor has been advised of the possibility of such damage.
|
||||||
|
However, the Licensor will be liable under statutory product liability laws as
|
||||||
|
far such laws apply to the Work.
|
||||||
|
|
||||||
|
9. Additional agreements
|
||||||
|
|
||||||
|
While distributing the Work, You may choose to conclude an additional agreement,
|
||||||
|
defining obligations or services consistent with this Licence. However, if
|
||||||
|
accepting obligations, You may act only on your own behalf and on your sole
|
||||||
|
responsibility, not on behalf of the original Licensor or any other Contributor,
|
||||||
|
and only if You agree to indemnify, defend, and hold each Contributor harmless
|
||||||
|
for any liability incurred by, or claims asserted against such Contributor by
|
||||||
|
the fact You have accepted any warranty or additional liability.
|
||||||
|
|
||||||
|
10. Acceptance of the Licence
|
||||||
|
|
||||||
|
The provisions of this Licence can be accepted by clicking on an icon ‘I agree’
|
||||||
|
placed under the bottom of a window displaying the text of this Licence or by
|
||||||
|
affirming consent in any other similar way, in accordance with the rules of
|
||||||
|
applicable law. Clicking on that icon indicates your clear and irrevocable
|
||||||
|
acceptance of this Licence and all of its terms and conditions.
|
||||||
|
|
||||||
|
Similarly, you irrevocably accept this Licence and all of its terms and
|
||||||
|
conditions by exercising any rights granted to You by Article 2 of this Licence,
|
||||||
|
such as the use of the Work, the creation by You of a Derivative Work or the
|
||||||
|
Distribution or Communication by You of the Work or copies thereof.
|
||||||
|
|
||||||
|
11. Information to the public
|
||||||
|
|
||||||
|
In case of any Distribution or Communication of the Work by means of electronic
|
||||||
|
communication by You (for example, by offering to download the Work from a
|
||||||
|
remote location) the distribution channel or media (for example, a website) must
|
||||||
|
at least provide to the public the information requested by the applicable law
|
||||||
|
regarding the Licensor, the Licence and the way it may be accessible, concluded,
|
||||||
|
stored and reproduced by the Licensee.
|
||||||
|
|
||||||
|
12. Termination of the Licence
|
||||||
|
|
||||||
|
The Licence and the rights granted hereunder will terminate automatically upon
|
||||||
|
any breach by the Licensee of the terms of the Licence.
|
||||||
|
|
||||||
|
Such a termination will not terminate the licences of any person who has
|
||||||
|
received the Work from the Licensee under the Licence, provided such persons
|
||||||
|
remain in full compliance with the Licence.
|
||||||
|
|
||||||
|
13. Miscellaneous
|
||||||
|
|
||||||
|
Without prejudice of Article 9 above, the Licence represents the complete
|
||||||
|
agreement between the Parties as to the Work.
|
||||||
|
|
||||||
|
If any provision of the Licence is invalid or unenforceable under applicable
|
||||||
|
law, this will not affect the validity or enforceability of the Licence as a
|
||||||
|
whole. Such provision will be construed or reformed so as necessary to make it
|
||||||
|
valid and enforceable.
|
||||||
|
|
||||||
|
The European Commission may publish other linguistic versions or new versions of
|
||||||
|
this Licence or updated versions of the Appendix, so far this is required and
|
||||||
|
reasonable, without reducing the scope of the rights granted by the Licence. New
|
||||||
|
versions of the Licence will be published with a unique version number.
|
||||||
|
|
||||||
|
All linguistic versions of this Licence, approved by the European Commission,
|
||||||
|
have identical value. Parties can take advantage of the linguistic version of
|
||||||
|
their choice.
|
||||||
|
|
||||||
|
14. Jurisdiction
|
||||||
|
|
||||||
|
Without prejudice to specific agreement between parties,
|
||||||
|
|
||||||
|
- any litigation resulting from the interpretation of this License, arising
|
||||||
|
between the European Union institutions, bodies, offices or agencies, as a
|
||||||
|
Licensor, and any Licensee, will be subject to the jurisdiction of the Court
|
||||||
|
of Justice of the European Union, as laid down in article 272 of the Treaty on
|
||||||
|
the Functioning of the European Union,
|
||||||
|
|
||||||
|
- any litigation arising between other parties and resulting from the
|
||||||
|
interpretation of this License, will be subject to the exclusive jurisdiction
|
||||||
|
of the competent court where the Licensor resides or conducts its primary
|
||||||
|
business.
|
||||||
|
|
||||||
|
15. Applicable Law
|
||||||
|
|
||||||
|
Without prejudice to specific agreement between parties,
|
||||||
|
|
||||||
|
- this Licence shall be governed by the law of the European Union Member State
|
||||||
|
where the Licensor has his seat, resides or has his registered office,
|
||||||
|
|
||||||
|
- this licence shall be governed by Belgian law if the Licensor has no seat,
|
||||||
|
residence or registered office inside a European Union Member State.
|
||||||
|
|
||||||
|
Appendix
|
||||||
|
|
||||||
|
‘Compatible Licences’ according to Article 5 EUPL are:
|
||||||
|
|
||||||
|
- GNU General Public License (GPL) v. 2, v. 3
|
||||||
|
- GNU Affero General Public License (AGPL) v. 3
|
||||||
|
- Open Software License (OSL) v. 2.1, v. 3.0
|
||||||
|
- Eclipse Public License (EPL) v. 1.0
|
||||||
|
- CeCILL v. 2.0, v. 2.1
|
||||||
|
- Mozilla Public Licence (MPL) v. 2
|
||||||
|
- GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3
|
||||||
|
- Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for
|
||||||
|
works other than software
|
||||||
|
- European Union Public Licence (EUPL) v. 1.1, v. 1.2
|
||||||
|
- Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong
|
||||||
|
Reciprocity (LiLiQ-R+).
|
||||||
|
|
||||||
|
The European Commission may update this Appendix to later versions of the above
|
||||||
|
licences without producing a new version of the EUPL, as long as they provide
|
||||||
|
the rights granted in Article 2 of this Licence and protect the covered Source
|
||||||
|
Code from exclusive appropriation.
|
||||||
|
|
||||||
|
All other changes or additions to this Appendix require the production of a new
|
||||||
|
EUPL version.
|
@@ -1,8 +1,8 @@
|
|||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use rocket::FromForm;
|
|
||||||
use rocket::serde::{Deserialize, Serialize};
|
use rocket::serde::{Deserialize, Serialize};
|
||||||
|
use rocket::FromForm;
|
||||||
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
||||||
|
|
||||||
use crate::model::boathouse::Boathouse;
|
use crate::model::boathouse::Boathouse;
|
||||||
|
@@ -1,7 +1,10 @@
|
|||||||
use rocket::serde::{Deserialize, Serialize};
|
use rocket::serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, SqlitePool};
|
use sqlx::{FromRow, SqlitePool};
|
||||||
|
|
||||||
use crate::tera::board::boathouse::FormBoathouseToAdd;
|
use crate::{
|
||||||
|
model::{log::Log, user::AllowedToUpdateBoathouse},
|
||||||
|
tera::board::boathouse::FormBoathouseToAdd,
|
||||||
|
};
|
||||||
|
|
||||||
use super::boat::Boat;
|
use super::boat::Boat;
|
||||||
|
|
||||||
@@ -114,7 +117,11 @@ impl Boathouse {
|
|||||||
BoathouseAisles::from(db, boathouses).await
|
BoathouseAisles::from(db, boathouses).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create(db: &SqlitePool, data: FormBoathouseToAdd) -> Result<(), String> {
|
pub async fn create(
|
||||||
|
db: &SqlitePool,
|
||||||
|
changed_by: &AllowedToUpdateBoathouse,
|
||||||
|
data: FormBoathouseToAdd,
|
||||||
|
) -> Result<(), String> {
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"INSERT INTO boathouse(boat_id, aisle, side, level) VALUES (?,?,?,?)",
|
"INSERT INTO boathouse(boat_id, aisle, side, level) VALUES (?,?,?,?)",
|
||||||
data.boat_id,
|
data.boat_id,
|
||||||
@@ -125,6 +132,17 @@ impl Boathouse {
|
|||||||
.execute(db)
|
.execute(db)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
let boat = Boat::find_by_id(db, data.boat_id).await.unwrap();
|
||||||
|
Log::create(
|
||||||
|
db,
|
||||||
|
format!(
|
||||||
|
"{changed_by} hat das Boot {boat} auf den Gang {}, Seite {}, und Höhe {} 'gelegt'.",
|
||||||
|
data.aisle, data.side, data.level
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,10 +153,20 @@ impl Boathouse {
|
|||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(&self, db: &SqlitePool) {
|
pub async fn delete(&self, db: &SqlitePool, changed_by: &AllowedToUpdateBoathouse) {
|
||||||
sqlx::query!("DELETE FROM boathouse WHERE id=?", self.id)
|
sqlx::query!("DELETE FROM boathouse WHERE id=?", self.id)
|
||||||
.execute(db)
|
.execute(db)
|
||||||
.await
|
.await
|
||||||
.unwrap(); //Okay, because we can only create a Boat of a valid id
|
.unwrap(); //Okay, because we can only create a Boat of a valid id
|
||||||
|
|
||||||
|
let boat = Boat::find_by_id(db, self.boat_id as i32).await.unwrap();
|
||||||
|
Log::create(
|
||||||
|
db,
|
||||||
|
format!(
|
||||||
|
"{changed_by} hat das Boot {boat} von Gang {}, Seite {}, und Höhe {} gelöscht.",
|
||||||
|
self.aisle, self.side, self.level
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
use super::Trip;
|
use super::Trip;
|
||||||
use crate::model::{
|
use crate::model::{
|
||||||
|
log::Log,
|
||||||
notification::Notification,
|
notification::Notification,
|
||||||
planned::{tripdetails::TripDetails, triptype::TripType},
|
planned::{tripdetails::TripDetails, triptype::TripType},
|
||||||
user::{ErgoUser, SteeringUser, User},
|
user::{ErgoUser, SteeringUser, User},
|
||||||
@@ -34,6 +35,8 @@ impl Trip {
|
|||||||
.execute(db)
|
.execute(db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
Log::create(db, format!("{user} created a new trip: {trip_details}")).await;
|
||||||
|
|
||||||
Self::notify_trips_same_datetime(db, trip_details, user).await;
|
Self::notify_trips_same_datetime(db, trip_details, user).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@ use super::{
|
|||||||
trip::{Trip, TripWithDetails},
|
trip::{Trip, TripWithDetails},
|
||||||
triptype::TripType,
|
triptype::TripType,
|
||||||
};
|
};
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
||||||
pub struct TripDetails {
|
pub struct TripDetails {
|
||||||
@@ -22,6 +23,20 @@ pub struct TripDetails {
|
|||||||
pub is_locked: bool,
|
pub is_locked: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for TripDetails {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_str(&format!(
|
||||||
|
"Ausfahrt am {} um {} mit {} Personen",
|
||||||
|
self.day, self.planned_starting_time, self.max_people
|
||||||
|
))?;
|
||||||
|
if let Some(notes) = &self.notes {
|
||||||
|
f.write_str(&format!(" Notizen: {notes}"))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(FromForm, Serialize)]
|
#[derive(FromForm, Serialize)]
|
||||||
pub struct TripDetailsToAdd<'r> {
|
pub struct TripDetailsToAdd<'r> {
|
||||||
//TODO: properly parse `planned_starting_time`
|
//TODO: properly parse `planned_starting_time`
|
||||||
|
@@ -342,12 +342,33 @@ impl User {
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
ActivityBuilder::new(&format!("{updated_by} hat {self} zum normalen Mitglied gemacht (keine Steuerperson/Schiffsführer mehr)"))
|
ActivityBuilder::new(&format!("{updated_by} hat {self} zum normalen Mitglied gemacht (keine Steuerperson/Bootsführer mehr)"))
|
||||||
.user(self)
|
.user(self)
|
||||||
.save(db)
|
.save(db)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(old, new) if old == Some(bootsfuehrer.clone()) && new == Some(cox.clone()) => {
|
||||||
|
self.remove_role(db, updated_by, &bootsfuehrer).await?;
|
||||||
|
self.add_role(db, updated_by, &cox).await?;
|
||||||
|
Notification::create_for_role(
|
||||||
|
db,
|
||||||
|
&member,
|
||||||
|
&format!(
|
||||||
|
"Lieber Vorstand, {self} ist ab sofort kein Bootsführer:in mehr, sondern 'nur' mehr eine Steuerperson."
|
||||||
|
),
|
||||||
|
"Bootsführer--",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
ActivityBuilder::new(&format!(
|
||||||
|
"{updated_by} hat {self} zur Steuerperson gemacht (kein Bootsführer mehr)"
|
||||||
|
))
|
||||||
|
.user(self)
|
||||||
|
.save(db)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
(old, new) => return Err(format!("Not allowed to change from {old:?} to {new:?}")),
|
(old, new) => return Err(format!("Not allowed to change from {old:?} to {new:?}")),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -508,6 +529,13 @@ impl User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn remove_membership_pdf(&self, db: &SqlitePool, updated_by: &ManageUserUser) {
|
pub(crate) async fn remove_membership_pdf(&self, db: &SqlitePool, updated_by: &ManageUserUser) {
|
||||||
|
ActivityBuilder::new(&format!(
|
||||||
|
"{updated_by} hat die Beitrittserklärung vom Beutzer gelöscht."
|
||||||
|
))
|
||||||
|
.user(self)
|
||||||
|
.save(db)
|
||||||
|
.await;
|
||||||
|
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"UPDATE user SET membership_pdf = null where id = ?",
|
"UPDATE user SET membership_pdf = null where id = ?",
|
||||||
self.id
|
self.id
|
||||||
|
@@ -102,6 +102,13 @@ impl UserWithDetails {
|
|||||||
user,
|
user,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn allowed_to_row(&self) -> bool {
|
||||||
|
self.roles.contains(&"Donau Linz".into())
|
||||||
|
|| self.roles.contains(&"Förderndes Mitglied".into())
|
||||||
|
|| self.roles.contains(&"scheckbuch".into())
|
||||||
|
|| self.user.name == "Externe Steuerperson"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -424,7 +431,7 @@ WHERE family_id IS NULL;
|
|||||||
"
|
"
|
||||||
SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, phone, address, family_id, user_token
|
SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, phone, address, family_id, user_token
|
||||||
FROM user
|
FROM user
|
||||||
WHERE deleted = 0 AND (SELECT COUNT(*) FROM user_role WHERE user_id=user.id AND role_id = (SELECT id FROM role WHERE name = 'cox')) > 0
|
WHERE deleted = 0 AND (SELECT COUNT(*) FROM user_role WHERE user_id=user.id AND role_id in (SELECT id FROM role WHERE name = 'cox' or name = 'Bootsführer')) > 0
|
||||||
ORDER BY last_access DESC
|
ORDER BY last_access DESC
|
||||||
"
|
"
|
||||||
)
|
)
|
||||||
@@ -859,6 +866,7 @@ special_user!(AllowedToEditPaymentStatusUser, +"kassier", +"admin");
|
|||||||
special_user!(ManageUserUser, +"admin", +"schriftfuehrer");
|
special_user!(ManageUserUser, +"admin", +"schriftfuehrer");
|
||||||
special_user!(AllowedToSendFeeReminderUser, +"admin", +"schriftfuehrer", +"kassier");
|
special_user!(AllowedToSendFeeReminderUser, +"admin", +"schriftfuehrer", +"kassier");
|
||||||
special_user!(AllowedToUpdateTripToAlwaysBeShownUser, +"admin");
|
special_user!(AllowedToUpdateTripToAlwaysBeShownUser, +"admin");
|
||||||
|
special_user!(AllowedToUpdateBoathouse, +"admin", +"Vorstand", +"tech");
|
||||||
|
|
||||||
#[derive(FromRow, Serialize, Deserialize, Clone, Debug)]
|
#[derive(FromRow, Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct UserWithRolesAndMembershipPdf {
|
pub struct UserWithRolesAndMembershipPdf {
|
||||||
|
@@ -7,11 +7,11 @@ use crate::{
|
|||||||
mail::valid_mails,
|
mail::valid_mails,
|
||||||
role::Role,
|
role::Role,
|
||||||
user::{
|
user::{
|
||||||
AdminUser, AllowedToEditPaymentStatusUser, ManageUserUser, User, UserWithDetails,
|
|
||||||
UserWithMembershipPdf, UserWithRolesAndMembershipPdf, VorstandUser,
|
|
||||||
clubmember::ClubMemberUser, foerdernd::FoerderndUser, member::Member,
|
clubmember::ClubMemberUser, foerdernd::FoerderndUser, member::Member,
|
||||||
regular::RegularUser, scheckbuch::ScheckbuchUser, schnupperant::SchnupperantUser,
|
regular::RegularUser, scheckbuch::ScheckbuchUser, schnupperant::SchnupperantUser,
|
||||||
schnupperinterest::SchnupperInterestUser, unterstuetzend::UnterstuetzendUser,
|
schnupperinterest::SchnupperInterestUser, unterstuetzend::UnterstuetzendUser,
|
||||||
|
AdminUser, AllowedToEditPaymentStatusUser, ManageUserUser, User, UserWithDetails,
|
||||||
|
UserWithMembershipPdf, UserWithRolesAndMembershipPdf, VorstandUser,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
tera::Config,
|
tera::Config,
|
||||||
@@ -19,7 +19,6 @@ use crate::{
|
|||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use rocket::{
|
use rocket::{
|
||||||
FromForm, Request, Route, State,
|
|
||||||
form::Form,
|
form::Form,
|
||||||
fs::TempFile,
|
fs::TempFile,
|
||||||
get,
|
get,
|
||||||
@@ -27,9 +26,9 @@ use rocket::{
|
|||||||
post,
|
post,
|
||||||
request::{FlashMessage, FromRequest, Outcome},
|
request::{FlashMessage, FromRequest, Outcome},
|
||||||
response::{Flash, Redirect},
|
response::{Flash, Redirect},
|
||||||
routes,
|
routes, FromForm, Request, Route, State,
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::{Template, tera::Context};
|
use rocket_dyn_templates::{tera::Context, Template};
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
|
|
||||||
// Custom request guard to extract the Referer header
|
// Custom request guard to extract the Referer header
|
||||||
@@ -357,7 +356,7 @@ async fn add_note(
|
|||||||
match user.add_note(db, &admin, &data.note).await {
|
match user.add_note(db, &admin, &data.note).await {
|
||||||
Ok(_) => Flash::success(
|
Ok(_) => Flash::success(
|
||||||
Redirect::to(format!("/admin/user/{}", user.id)),
|
Redirect::to(format!("/admin/user/{}", user.id)),
|
||||||
"Notiz hinzugefügt",
|
"Notiz hinzugefügt. Du findest sie ab sofort unter 'Aktivitäten'.",
|
||||||
),
|
),
|
||||||
Err(e) => Flash::error(Redirect::to(format!("/admin/user/{}", user.id)), e),
|
Err(e) => Flash::error(Redirect::to(format!("/admin/user/{}", user.id)), e),
|
||||||
}
|
}
|
||||||
|
@@ -1,17 +1,16 @@
|
|||||||
use crate::model::{
|
use crate::model::{
|
||||||
boat::Boat,
|
boat::Boat,
|
||||||
boathouse::Boathouse,
|
boathouse::Boathouse,
|
||||||
user::{AdminUser, UserWithDetails, VorstandUser},
|
user::{AllowedToUpdateBoathouse, UserWithDetails, VorstandUser},
|
||||||
};
|
};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
FromForm, Route, State,
|
|
||||||
form::Form,
|
form::Form,
|
||||||
get, post,
|
get, post,
|
||||||
request::FlashMessage,
|
request::FlashMessage,
|
||||||
response::{Flash, Redirect},
|
response::{Flash, Redirect},
|
||||||
routes,
|
routes, FromForm, Route, State,
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::{Template, tera::Context};
|
use rocket_dyn_templates::{tera::Context, Template};
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
|
|
||||||
#[get("/boathouse")]
|
#[get("/boathouse")]
|
||||||
@@ -38,6 +37,11 @@ async fn index(
|
|||||||
let boathouse = Boathouse::get(db).await;
|
let boathouse = Boathouse::get(db).await;
|
||||||
context.insert("boathouse", &boathouse);
|
context.insert("boathouse", &boathouse);
|
||||||
|
|
||||||
|
let allowed_to_edit = AllowedToUpdateBoathouse::new(db, &admin.user)
|
||||||
|
.await
|
||||||
|
.is_some();
|
||||||
|
context.insert("allowed_to_edit", &allowed_to_edit);
|
||||||
|
|
||||||
context.insert(
|
context.insert(
|
||||||
"loggedin_user",
|
"loggedin_user",
|
||||||
&UserWithDetails::from_user(admin.into_inner(), db).await,
|
&UserWithDetails::from_user(admin.into_inner(), db).await,
|
||||||
@@ -57,36 +61,29 @@ pub struct FormBoathouseToAdd {
|
|||||||
async fn new<'r>(
|
async fn new<'r>(
|
||||||
db: &State<SqlitePool>,
|
db: &State<SqlitePool>,
|
||||||
data: Form<FormBoathouseToAdd>,
|
data: Form<FormBoathouseToAdd>,
|
||||||
_admin: AdminUser,
|
user: AllowedToUpdateBoathouse,
|
||||||
) -> Flash<Redirect> {
|
) -> Flash<Redirect> {
|
||||||
match Boathouse::create(db, data.into_inner()).await {
|
match Boathouse::create(db, &user, data.into_inner()).await {
|
||||||
Ok(_) => Flash::success(Redirect::to("/board/boathouse"), "Boot hinzugefügt"),
|
Ok(_) => Flash::success(Redirect::to("/board/boathouse"), "Boot hinzugefügt"),
|
||||||
Err(e) => Flash::error(Redirect::to("/board/boathouse"), e),
|
Err(e) => Flash::error(Redirect::to("/board/boathouse"), e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/boathouse/<boathouse_id>/delete")]
|
#[get("/boathouse/<boathouse_id>/delete")]
|
||||||
async fn delete(db: &State<SqlitePool>, _admin: AdminUser, boathouse_id: i32) -> Flash<Redirect> {
|
async fn delete(
|
||||||
|
db: &State<SqlitePool>,
|
||||||
|
user: AllowedToUpdateBoathouse,
|
||||||
|
boathouse_id: i32,
|
||||||
|
) -> Flash<Redirect> {
|
||||||
let boat = Boathouse::find_by_id(db, boathouse_id).await;
|
let boat = Boathouse::find_by_id(db, boathouse_id).await;
|
||||||
match boat {
|
match boat {
|
||||||
Some(boat) => {
|
Some(boat) => {
|
||||||
boat.delete(db).await;
|
boat.delete(db, &user).await;
|
||||||
Flash::success(Redirect::to("/board/boathouse"), "Bootsplatz gelöscht")
|
Flash::success(Redirect::to("/board/boathouse"), "Bootsplatz gelöscht")
|
||||||
}
|
}
|
||||||
None => Flash::error(Redirect::to("/board/boathouse"), "Boatplace does not exist"),
|
None => Flash::error(Redirect::to("/board/boathouse"), "Boatplace does not exist"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#[post("/boat/new", data = "<data>")]
|
|
||||||
//async fn create(
|
|
||||||
// db: &State<SqlitePool>,
|
|
||||||
// data: Form<BoatToAdd<'_>>,
|
|
||||||
// _admin: AdminUser,
|
|
||||||
//) -> Flash<Redirect> {
|
|
||||||
// match Boat::create(db, data.into_inner()).await {
|
|
||||||
// Ok(_) => Flash::success(Redirect::to("/admin/boat"), "Boot hinzugefügt"),
|
|
||||||
// Err(e) => Flash::error(Redirect::to("/admin/boat"), e),
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
pub fn routes() -> Vec<Route> {
|
pub fn routes() -> Vec<Route> {
|
||||||
routes![index, new, delete]
|
routes![index, new, delete]
|
||||||
|
119
src/tera/log.rs
119
src/tera/log.rs
@@ -47,12 +47,46 @@ impl<'r> FromRequest<'r> for KioskCookie {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/", rank = 2)]
|
#[get("/", rank = 2)]
|
||||||
async fn index(
|
async fn index_loggedin(
|
||||||
db: &State<SqlitePool>,
|
db: &State<SqlitePool>,
|
||||||
flash: Option<FlashMessage<'_>>,
|
flash: Option<FlashMessage<'_>>,
|
||||||
user: DonauLinzUser,
|
user: DonauLinzUser,
|
||||||
) -> Template {
|
) -> Template {
|
||||||
|
let mut context = Context::new();
|
||||||
|
|
||||||
let boats = Boat::for_user(db, &user).await;
|
let boats = Boat::for_user(db, &user).await;
|
||||||
|
context.insert("boats", &boats);
|
||||||
|
|
||||||
|
context.insert(
|
||||||
|
"loggedin_user",
|
||||||
|
&UserWithDetails::from_user(user.into_inner(), db).await,
|
||||||
|
);
|
||||||
|
|
||||||
|
let context = index(db, flash, context).await;
|
||||||
|
Template::render("log", context.into_json())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
async fn index_kiosk(
|
||||||
|
db: &State<SqlitePool>,
|
||||||
|
flash: Option<FlashMessage<'_>>,
|
||||||
|
_kiosk: KioskCookie,
|
||||||
|
) -> Template {
|
||||||
|
let mut context = Context::new();
|
||||||
|
|
||||||
|
let boats = Boat::all(db).await;
|
||||||
|
context.insert("boats", &boats);
|
||||||
|
|
||||||
|
context.insert("show_kiosk_header", &true);
|
||||||
|
|
||||||
|
let context = index(db, flash, context).await;
|
||||||
|
Template::render("kiosk", context.into_json())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn index(db: &SqlitePool, flash: Option<FlashMessage<'_>>, mut context: Context) -> Context {
|
||||||
|
if let Some(msg) = flash {
|
||||||
|
context.insert("flash", &msg.into_inner());
|
||||||
|
}
|
||||||
|
|
||||||
let mut coxes: Vec<UserWithDetails> = futures::future::join_all(
|
let mut coxes: Vec<UserWithDetails> = futures::future::join_all(
|
||||||
User::cox(db)
|
User::cox(db)
|
||||||
@@ -61,9 +95,7 @@ async fn index(
|
|||||||
.map(|user| UserWithDetails::from_user(user, db)),
|
.map(|user| UserWithDetails::from_user(user, db)),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
coxes.retain(|u| {
|
coxes.retain(|u| u.roles.contains(&"Donau Linz".into()));
|
||||||
u.roles.contains(&"Donau Linz".into()) || u.roles.contains(&"scheckbuch".into())
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut users: Vec<UserWithDetails> = futures::future::join_all(
|
let mut users: Vec<UserWithDetails> = futures::future::join_all(
|
||||||
User::all(db)
|
User::all(db)
|
||||||
@@ -72,23 +104,13 @@ async fn index(
|
|||||||
.map(|user| UserWithDetails::from_user(user, db)),
|
.map(|user| UserWithDetails::from_user(user, db)),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
users.retain(|u| {
|
users.retain(|u| u.allowed_to_row());
|
||||||
u.roles.contains(&"Donau Linz".into())
|
|
||||||
|| u.roles.contains(&"scheckbuch".into())
|
|
||||||
|| u.user.name == "Externe Steuerperson"
|
|
||||||
});
|
|
||||||
|
|
||||||
let logtypes = LogType::all(db).await;
|
let logtypes = LogType::all(db).await;
|
||||||
let distances = Distance::all(db).await;
|
let distances = Distance::all(db).await;
|
||||||
|
|
||||||
let on_water = Logbook::on_water(db).await;
|
let on_water = Logbook::on_water(db).await;
|
||||||
|
|
||||||
let mut context = Context::new();
|
|
||||||
if let Some(msg) = flash {
|
|
||||||
context.insert("flash", &msg.into_inner());
|
|
||||||
}
|
|
||||||
|
|
||||||
context.insert("boats", &boats);
|
|
||||||
context.insert("planned_trips", &Trip::get_for_today(db).await);
|
context.insert("planned_trips", &Trip::get_for_today(db).await);
|
||||||
context.insert(
|
context.insert(
|
||||||
"reservations",
|
"reservations",
|
||||||
@@ -97,14 +119,10 @@ async fn index(
|
|||||||
context.insert("coxes", &coxes);
|
context.insert("coxes", &coxes);
|
||||||
context.insert("users", &users);
|
context.insert("users", &users);
|
||||||
context.insert("logtypes", &logtypes);
|
context.insert("logtypes", &logtypes);
|
||||||
context.insert(
|
|
||||||
"loggedin_user",
|
|
||||||
&UserWithDetails::from_user(user.into_inner(), db).await,
|
|
||||||
);
|
|
||||||
context.insert("on_water", &on_water);
|
context.insert("on_water", &on_water);
|
||||||
context.insert("distances", &distances);
|
context.insert("distances", &distances);
|
||||||
|
|
||||||
Template::render("log", context.into_json())
|
context
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/show", rank = 3)]
|
#[get("/show", rank = 3)]
|
||||||
@@ -179,63 +197,6 @@ async fn new_kiosk(
|
|||||||
Redirect::to("/log")
|
Redirect::to("/log")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
|
||||||
async fn kiosk(
|
|
||||||
db: &State<SqlitePool>,
|
|
||||||
flash: Option<FlashMessage<'_>>,
|
|
||||||
_kiosk: KioskCookie,
|
|
||||||
) -> Template {
|
|
||||||
let boats = Boat::all(db).await;
|
|
||||||
let mut coxes: Vec<UserWithDetails> = futures::future::join_all(
|
|
||||||
User::cox(db)
|
|
||||||
.await
|
|
||||||
.into_iter()
|
|
||||||
.map(|user| UserWithDetails::from_user(user, db)),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
coxes.retain(|u| {
|
|
||||||
u.roles.contains(&"Donau Linz".into()) || u.roles.contains(&"scheckbuch".into())
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut users: Vec<UserWithDetails> = futures::future::join_all(
|
|
||||||
User::all(db)
|
|
||||||
.await
|
|
||||||
.into_iter()
|
|
||||||
.map(|user| UserWithDetails::from_user(user, db)),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
users.retain(|u| {
|
|
||||||
u.roles.contains(&"Donau Linz".into()) || u.roles.contains(&"scheckbuch".into())
|
|
||||||
});
|
|
||||||
|
|
||||||
let logtypes = LogType::all(db).await;
|
|
||||||
let distances = Distance::all(db).await;
|
|
||||||
|
|
||||||
let on_water = Logbook::on_water(db).await;
|
|
||||||
|
|
||||||
let mut context = Context::new();
|
|
||||||
if let Some(msg) = flash {
|
|
||||||
context.insert("flash", &msg.into_inner());
|
|
||||||
}
|
|
||||||
|
|
||||||
context.insert("planned_trips", &Trip::get_for_today(db).await);
|
|
||||||
context.insert("boats", &boats);
|
|
||||||
context.insert(
|
|
||||||
"reservations",
|
|
||||||
&BoatReservation::all_future_with_groups(db).await,
|
|
||||||
);
|
|
||||||
context.insert("coxes", &coxes);
|
|
||||||
context.insert("users", &users);
|
|
||||||
context.insert("logtypes", &logtypes);
|
|
||||||
context.insert("on_water", &on_water);
|
|
||||||
context.insert("distances", &distances);
|
|
||||||
context.insert("show_kiosk_header", &true);
|
|
||||||
|
|
||||||
Template::render("kiosk", context.into_json())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn create_logbook(
|
async fn create_logbook(
|
||||||
db: &SqlitePool,
|
db: &SqlitePool,
|
||||||
data: Form<LogToAdd>,
|
data: Form<LogToAdd>,
|
||||||
@@ -568,11 +529,11 @@ async fn delete_kiosk(
|
|||||||
|
|
||||||
pub fn routes() -> Vec<Route> {
|
pub fn routes() -> Vec<Route> {
|
||||||
routes![
|
routes![
|
||||||
index,
|
index_loggedin,
|
||||||
|
index_kiosk,
|
||||||
create,
|
create,
|
||||||
create_kiosk,
|
create_kiosk,
|
||||||
home,
|
home,
|
||||||
kiosk,
|
|
||||||
home_kiosk,
|
home_kiosk,
|
||||||
new_kiosk,
|
new_kiosk,
|
||||||
show,
|
show,
|
||||||
|
@@ -7,12 +7,12 @@
|
|||||||
{% set place = boathouse[aisle_name][side_name].boats %}
|
{% set place = boathouse[aisle_name][side_name].boats %}
|
||||||
{% if place[level] %}
|
{% if place[level] %}
|
||||||
{{ place[level].boat.name }}
|
{{ place[level].boat.name }}
|
||||||
{% if "admin" in loggedin_user.roles %}
|
{% if allowed_to_edit %}
|
||||||
<a class="btn btn-primary absolute end-0"
|
<a class="btn btn-primary absolute end-0"
|
||||||
href="/board/boathouse/{{ place[level].boathouse_id }}/delete">X</a>
|
href="/board/boathouse/{{ place[level].boathouse_id }}/delete">X</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% elif boats | length > 0 %}
|
{% elif boats | length > 0 %}
|
||||||
{% if "admin" in loggedin_user.roles %}
|
{% if allowed_to_edit %}
|
||||||
<details>
|
<details>
|
||||||
<summary>Kein Boot</summary>
|
<summary>Kein Boot</summary>
|
||||||
<form action="/board/boathouse" method="post" class="grid gap-3">
|
<form action="/board/boathouse" method="post" class="grid gap-3">
|
||||||
|
Reference in New Issue
Block a user