main #1

Open
philipp wants to merge 97 commits from Ruderverein-Donau-Linz/rowt:main into main
4 changed files with 81 additions and 27 deletions
Showing only changes of commit 2a37bcbec5 - Show all commits

View File

@ -23,6 +23,7 @@ document.addEventListener("DOMContentLoaded", function () {
addRelationMagic(<HTMLElement>document.querySelector("body")); addRelationMagic(<HTMLElement>document.querySelector("body"));
reloadPage(); reloadPage();
setCurrentdate(<HTMLInputElement>document.querySelector("#departure")); setCurrentdate(<HTMLInputElement>document.querySelector("#departure"));
initDropdown();
}); });
function changeTheme() { function changeTheme() {
@ -795,3 +796,21 @@ function replaceStrings() {
weekday.innerHTML = weekday.innerHTML.replace("Freitag", "Markttag"); weekday.innerHTML = weekday.innerHTML.replace("Freitag", "Markttag");
}); });
} }
function initDropdown() {
const popoverTriggerList = document.querySelectorAll('[data-dropdown]');
popoverTriggerList.forEach((popoverTriggerEl: Element) => {
const id = popoverTriggerEl.getAttribute('data-dropdown');
if (id) {
const element = document.getElementById(id);
if (element) {
// Toggle visibility of the dropdown when clicked
popoverTriggerEl.addEventListener('click', () => {
element.classList.toggle('hidden');
});
}
}
});
}

View File

@ -591,15 +591,24 @@ WHERE lower(name)=?
} }
pub async fn all(db: &SqlitePool) -> Vec<Self> { pub async fn all(db: &SqlitePool) -> Vec<Self> {
sqlx::query_as!( Self::all_with_order(db, "last_access", false).await
Self, }
pub async fn all_with_order(db: &SqlitePool, sort: &str, asc: bool) -> Vec<Self> {
let mut query = format!(
" "
SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token
FROM user FROM user
WHERE deleted = 0 WHERE deleted = 0
ORDER BY last_access DESC ORDER BY {}
" ",
) sort
);
if !asc {
query.push_str(" DESC");
}
sqlx::query_as::<_, User>(&query)
.fetch_all(db) .fetch_all(db)
.await .await
.unwrap() .unwrap()

View File

@ -43,13 +43,17 @@ impl<'r> FromRequest<'r> for Referer {
} }
} }
#[get("/user")] #[get("/user?<sort>&<asc>")]
async fn index( async fn index(
db: &State<SqlitePool>, db: &State<SqlitePool>,
user: VorstandUser, user: VorstandUser,
flash: Option<FlashMessage<'_>>, flash: Option<FlashMessage<'_>>,
sort: Option<String>,
asc: bool,
) -> Template { ) -> Template {
let user_futures: Vec<_> = User::all(db) let sort_column = sort.unwrap_or_else(|| "last_access".to_string());
let user_futures: Vec<_> = User::all_with_order(db, &sort_column, asc)
.await .await
.into_iter() .into_iter()
.map(|u| async move { UserWithRolesAndMembershipPdf::from_user(db, u).await }) .map(|u| async move { UserWithRolesAndMembershipPdf::from_user(db, u).await })

View File

@ -4,37 +4,59 @@
<div class="max-w-screen-lg w-full"> <div class="max-w-screen-lg w-full">
<h1 class="h1">Users</h1> <h1 class="h1">Users</h1>
{% if allowed_to_edit %} {% if allowed_to_edit %}
<details class="mt-5 bg-gray-200 dark:bg-primary-600 p-3 rounded-md">
<summary class="px-3 cursor-pointer text-md font-bold text-primary-950 dark:text-white">Neue Person hinzufügen</summary>
<form action="/admin/user/new" <form action="/admin/user/new"
onsubmit="return confirm('Willst du wirklich einen neuen Benutzer anlegen?');" onsubmit="return confirm('Willst du wirklich einen neuen Benutzer anlegen?');"
method="post" method="post"
class="mt-4 bg-primary-900 rounded-md text-white px-3 pb-3 pt-2 sm:flex items-end justify-between"> class="flex mt-4 rounded-md sm:flex items-end justify-between">
<div class="w-full"> <div class="w-full">
<h2 class="text-md font-bold mb-2 uppercase tracking-wide">Neuen User hinzufügen</h2>
<div class="grid md:grid-cols-3">
<div> <div>
<label for="name" class="sr-only">Name</label> <label for="name" class="sr-only">Name</label>
<input type="text" <input type="text"
name="name" name="name"
class="relative block rounded-md border-0 py-1.5 px-2 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary-600 sm:text-sm sm:leading-6 mb-2 md:mb-0" class="input rounded-md w-100"
placeholder="Name" /> placeholder="Name" />
</div> </div>
</div> </div>
</div> <div class="text-right ml-3">
<div class="text-right">
<input value="Hinzufügen" <input value="Hinzufügen"
type="submit" type="submit"
class="w-28 mt-2 sm:mt-0 rounded-md bg-primary-500 px-3 py-2 text-sm font-semibold text-white hover:bg-primary-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600 cursor-pointer" /> class="w-28 mt-2 sm:mt-0 rounded-md bg-primary-500 px-3 py-2 text-sm font-semibold text-white hover:bg-primary-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-600 cursor-pointer" />
</div> </div>
</form> </form>
</details>
{% endif %} {% endif %}
<!-- START filterBar --> <!-- START filterBar -->
<div class="search-wrapper"> <div class="search-wrapper flex">
<label for="name" class="sr-only">Suche</label> <label for="name" class="sr-only">Suche</label>
<input type="search" <input type="search"
name="name" name="name"
id="filter-js" id="filter-js"
class="search-bar" class="search-bar"
placeholder="Suchen nach (Name, [yes|no]-role:<name>, has-[no-]membership-pdf)" /> placeholder="Suchen nach (Name, [yes|no]-role:<name>, has-[no-]membership-pdf)" />
<div class="relative">
<button id="dropdownbtn" data-dropdown="dropdown" class="btn btn-dark ml-3" type="button">
Sortieren
</button>
<!-- Dropdown menu -->
<div id="dropdown" class="z-10 hidden bg-white divide-y divide-gray-100 text-secondary-900 rounded-lg shadow-sm w-44 absolute right-0">
<ul class="py-2 text-sm" aria-labelledby="dropdownbtn">
<li>
<a href="./user" class="block px-4 py-2 hover:bg-gray-100 hover:text-secondary-950">Zuletzt eingeloggt</a>
</li>
<li>
<a href="?sort=name&asc" class="block px-4 py-2 hover:bg-gray-100 hover:text-secondary-950">Name A-Z</a>
</li>
<li>
<a href="?sort=name" class="block px-4 py-2 hover:bg-gray-100 hover:text-secondary-950">Name Z-A</a>
</li>
</ul>
</div>
</div>
</div> </div>
<!-- END filterBar --> <!-- END filterBar -->
<div id="filter-result-js" class="search-result"></div> <div id="filter-result-js" class="search-result"></div>
@ -47,7 +69,7 @@
<span class="text-black dark:text-white cursor-pointer"> <span class="text-black dark:text-white cursor-pointer">
<span class="font-bold"> <span class="font-bold">
{{ user.name }} {{ user.name }}
{% if not user.last_access and "admin" in loggedin_user.roles and user.mail %} {% if not user.last_access and allowed_to_edit and user.mail %}
<form action="/admin/user" <form action="/admin/user"
method="post" method="post"
enctype="multipart/form-data" enctype="multipart/form-data"