Compare commits

...

3 Commits

Author SHA1 Message Date
6c2ff716e1 Merge pull request 'staging' (#244) from staging into main
Some checks failed
CI/CD Pipeline / deploy-staging (push) Blocked by required conditions
CI/CD Pipeline / deploy-main (push) Blocked by required conditions
CI/CD Pipeline / test (push) Has been cancelled
Reviewed-on: #244
2024-03-05 09:19:50 +01:00
8b0cbe23d1 show year selector to admins for logbook
Some checks failed
CI/CD Pipeline / test (push) Failing after 8m58s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2024-03-05 09:19:15 +01:00
58f8cb14b8 allow admins to show logbook for any year
Some checks failed
CI/CD Pipeline / test (push) Failing after 10m41s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped
2024-03-05 08:59:44 +01:00
4 changed files with 55 additions and 3 deletions

View File

@ -260,6 +260,10 @@ ORDER BY departure DESC
pub async fn completed(db: &SqlitePool) -> Vec<LogbookWithBoatAndRowers> { pub async fn completed(db: &SqlitePool) -> Vec<LogbookWithBoatAndRowers> {
let year = chrono::Local::now().year(); let year = chrono::Local::now().year();
Self::completed_in_year(db, year).await
}
pub async fn completed_in_year(db: &SqlitePool, year: i32) -> Vec<LogbookWithBoatAndRowers> {
let logs = sqlx::query_as( let logs = sqlx::query_as(
&format!(" &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

View File

@ -753,7 +753,7 @@ impl<'r> FromRequest<'r> for AdminUser {
if user.has_role(db, "admin").await { if user.has_role(db, "admin").await {
Outcome::Success(AdminUser { user }) Outcome::Success(AdminUser { user })
} else { } else {
Outcome::Error((Status::Forbidden, LoginError::NotACox)) Outcome::Forward(Status::Forbidden)
} }
} }
Outcome::Error(f) => Outcome::Error(f), Outcome::Error(f) => Outcome::Error(f),

View File

@ -23,7 +23,7 @@ use crate::model::{
LogbookUpdateError, LogbookUpdateError,
}, },
logtype::LogType, logtype::LogType,
user::{DonauLinzUser, User, UserWithRoles, UserWithWaterStatus}, user::{AdminUser, DonauLinzUser, User, UserWithRoles, UserWithWaterStatus},
}; };
pub struct KioskCookie(String); pub struct KioskCookie(String);
@ -96,6 +96,16 @@ async fn show(db: &State<SqlitePool>, user: DonauLinzUser) -> Template {
) )
} }
#[get("/show?<year>")]
async fn show_for_year(db: &State<SqlitePool>, user: AdminUser, year: i32) -> Template {
let logs = Logbook::completed_in_year(db, year).await;
Template::render(
"log.completed",
context!(logs, loggedin_user: &UserWithRoles::from_user(user.user, db).await),
)
}
#[get("/show")] #[get("/show")]
async fn show_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie) -> Template { async fn show_kiosk(db: &State<SqlitePool>, _kiosk: KioskCookie) -> Template {
let logs = Logbook::completed(db).await; let logs = Logbook::completed(db).await;
@ -378,6 +388,7 @@ pub fn routes() -> Vec<Route> {
new_kiosk, new_kiosk,
show, show,
show_kiosk, show_kiosk,
show_for_year,
delete, delete,
delete_kiosk delete_kiosk
] ]

View File

@ -3,7 +3,16 @@
{% extends "base" %} {% extends "base" %}
{% block content %} {% block content %}
<div class="max-w-screen-lg w-full"> <div class="max-w-screen-lg w-full">
<h1 class="h1">Logbuch</h1> <h1 class="h1">
Logbuch
{% if "admin" in loggedin_user.roles %}
<select id="yearSelect"
onchange="changeYear()"
style="background: transparent;
background-image: none;
text-decoration: underline"></select>
{% endif %}
</h1>
<div class="mt-3"> <div class="mt-3">
<div class="search-wrapper"> <div class="search-wrapper">
<label for="name" class="sr-only">Suche</label> <label for="name" class="sr-only">Suche</label>
@ -17,4 +26,32 @@
{% for log in logs %}{{ log::show_old(log=log, state="completed", only_ones=false, index=loop.index) }}{% endfor %} {% for log in logs %}{{ log::show_old(log=log, state="completed", only_ones=false, index=loop.index) }}{% endfor %}
</div> </div>
</div> </div>
<script>
function getYearFromURL() {
var queryParams = new URLSearchParams(window.location.search);
return queryParams.get('year');
}
function populateYears() {
var select = document.getElementById('yearSelect');
var currentYear = new Date().getFullYear();
var selectedYear = getYearFromURL() || currentYear;
for (var year = 2019; year <= currentYear; year++) {
var option = document.createElement('option');
option.value = option.textContent = year;
if (year == selectedYear) {
option.selected = true;
}
select.appendChild(option);
}
}
function changeYear() {
var selectedYear = document.getElementById('yearSelect').value;
window.location.href = '?year=' + selectedYear;
}
// Call this function when the page loads
populateYears();
</script>
{% endblock content %} {% endblock content %}