allow-reservation-edits #424
@ -72,5 +72,6 @@ export default defineConfig({
|
||||
webServer: {
|
||||
timeout: 15 * 60 * 1000,
|
||||
command: 'cd .. && ./test_db.sh && cargo r',
|
||||
url: 'http://127.0.0.1:8000'
|
||||
},
|
||||
});
|
||||
|
@ -13,3 +13,4 @@
|
||||
@import 'components/search';
|
||||
@import 'components/important';
|
||||
@import 'components/searchable-table';
|
||||
@import 'components/notification';
|
||||
|
5
frontend/scss/components/_notification.scss
Normal file
5
frontend/scss/components/_notification.scss
Normal file
@ -0,0 +1,5 @@
|
||||
.notification {
|
||||
right: -.2rem;
|
||||
top: -.1rem;
|
||||
font-size: .5rem;
|
||||
}
|
@ -8,7 +8,7 @@ test("cox can create and delete trip", async ({ page }) => {
|
||||
await page.getByPlaceholder("Passwort").fill("cox");
|
||||
await page.getByPlaceholder("Passwort").press("Enter");
|
||||
await page.locator('li').filter({ hasText: 'Geplante Ausfahrten' }).getByRole('link').click();
|
||||
await page.locator(".relative").first().click();
|
||||
await page.locator('a[href="#"]:has-text("Ausfahrt")').first().click();
|
||||
await page.locator("#sidebar #planned_starting_time").click();
|
||||
await page.locator("#sidebar #planned_starting_time").fill("18:00");
|
||||
await page.locator("#sidebar #planned_starting_time").press("Tab");
|
||||
@ -38,8 +38,8 @@ test.describe("cox can edit trips", () => {
|
||||
await page.getByPlaceholder("Name").press("Tab");
|
||||
await page.getByPlaceholder("Passwort").fill("cox");
|
||||
await page.getByPlaceholder("Passwort").press("Enter");
|
||||
await page.locator('li').filter({ hasText: 'Geplante Ausfahrten' }).getByRole('link').click();
|
||||
await page.locator(".relative").first().click();
|
||||
await page.locator('li').filter({ hasText: 'Geplante Ausfahrten' }).getByRole('link').click();
|
||||
await page.locator('a[href="#"]:has-text("Ausfahrt")').first().click();
|
||||
await page.locator("#sidebar #planned_starting_time").click();
|
||||
await page.locator("#sidebar #planned_starting_time").fill("18:00");
|
||||
await page.locator("#sidebar #planned_starting_time").press("Tab");
|
||||
|
@ -31,21 +31,26 @@
|
||||
<a href="/">
|
||||
Hü
|
||||
{{ loggedin_user.name }}
|
||||
{% if loggedin_user.amount_unread_notifications > 0 %}
|
||||
<span class="bg-red-100 text-red-800 text-sm font-medium me-2 px-2.5 py-0.5 rounded-full dark:bg-red-900 dark:text-red-300 inline-flex items-center">
|
||||
<svg class="w-3 h-3 me-1.5"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20">
|
||||
<path d="M1.5 8.67v8.58a3 3 0 0 0 3 3h15a3 3 0 0 0 3-3V8.67l-8.928 5.493a3 3 0 0 1-3.144 0L1.5 8.67Z" />
|
||||
<path d="M22.5 6.908V6.75a3 3 0 0 0-3-3h-15a3 3 0 0 0-3 3v.158l9.714 5.978a1.5 1.5 0 0 0 1.572 0L22.5 6.908Z" />
|
||||
</svg>
|
||||
{{ loggedin_user.amount_unread_notifications }}</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center">
|
||||
{% if loggedin_user.amount_unread_notifications > 0 %}
|
||||
<a href="/#notification"
|
||||
class="relative inline-flex items-end ms-2 me-3">
|
||||
<svg height="20"
|
||||
width="24"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 24">
|
||||
<path d="M1.5 8.67v8.58a3 3 0 0 0 3 3h15a3 3 0 0 0 3-3V8.67l-8.928 5.493a3 3 0 0 1-3.144 0L1.5 8.67Z" />
|
||||
<path d="M22.5 6.908V6.75a3 3 0 0 0-3-3h-15a3 3 0 0 0-3 3v.158l9.714 5.978a1.5 1.5 0 0 0 1.572 0L22.5 6.908Z" />
|
||||
</svg>
|
||||
<small class="bg-red-500 rounded-full w-3 h-3 inline-flex justify-center items-center absolute p-1 notification">
|
||||
{{ loggedin_user.amount_unread_notifications }}
|
||||
</small>
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="#"
|
||||
class="inline-flex justify-center rounded-md bg-primary-600 mx-1 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"
|
||||
data-sidebar="true"
|
||||
@ -175,18 +180,24 @@
|
||||
<div class="p-2 border border-t-0 border-{{ bg }} mb-4 rounded-b-md">
|
||||
{% if participants | length > 0 %}
|
||||
{% for rower in participants %}
|
||||
{{ rower.name }}
|
||||
{% if rower.is_guest %}<small class="text-gray-600 dark:text-gray-100">(Scheckbuch)</small>{% endif %}
|
||||
{% if rower.is_real_guest %}
|
||||
<small class="text-gray-600 dark:text-gray-100">(Gast)</small>
|
||||
{% if allow_removing %}
|
||||
<a href="/planned/remove/{{ trip_details_id }}/{{ rower.name }}"
|
||||
class="btn btn-attention btn-fw">Abmelden</a>
|
||||
<div class="relative">
|
||||
{{ rower.name }}
|
||||
{% if rower.is_guest %}<small class="text-gray-600 dark:text-gray-100">(Scheckbuch)</small>{% endif %}
|
||||
{% if rower.is_real_guest %}
|
||||
<small class="text-gray-600 dark:text-gray-100">(Gast)</small>
|
||||
{% if allow_removing %}
|
||||
<a href="/planned/remove/{{ trip_details_id }}/{{ rower.name }}"
|
||||
class="absolute r-0 bg-red-500 w-5 h-5 text-white rounded-full flex items-center justify-center transform rotate-45 top-0 right-0">
|
||||
<svg class="inline h-5 w-5" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"></path>
|
||||
</svg>
|
||||
<span class="sr-only">Abmelden</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<span class="hidden">(angemeldet seit
|
||||
{{ rower.registered_at }})</span>
|
||||
<br />
|
||||
<span class="hidden">(angemeldet seit
|
||||
{{ rower.registered_at }})</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{ text }}
|
||||
|
@ -2,7 +2,11 @@
|
||||
{% extends "base" %}
|
||||
{% block content %}
|
||||
<div class="max-w-screen-lg w-full">
|
||||
<h1 class="h1">Ruderassistent</h1>
|
||||
<h1 class="h1">
|
||||
Ruder
|
||||
<wbr />
|
||||
assistent
|
||||
</h1>
|
||||
<div class="grid gap-3 my-5">
|
||||
<div class="m-auto">
|
||||
<a href="/planned"
|
||||
@ -11,9 +15,15 @@
|
||||
<span class="text-xl px-3">Geplante Ausfahrten</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
|
||||
<div id="notification"
|
||||
class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
|
||||
role="alert">
|
||||
<h2 class="h2">Nachrichten</h2>
|
||||
{% if loggedin_user.amount_unread_notifications > 10 %}
|
||||
<div class="text-primary-950 dark:text-white bg-gray-200 dark:bg-primary-950 bg-opacity-80 text-center pb-3 px-3">
|
||||
Du hast viele ungelesene Benachrichtigungen. Um deine Oberfläche übersichtlich zu halten und wichtige Updates nicht zu verpassen, nimm dir bitte einen Moment Zeit sie zu überprüfen und als gelesen zu markieren (✓).
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="divide-y">
|
||||
{% for notification in notifications %}
|
||||
{% if not notification.read_at %}
|
||||
@ -27,7 +37,7 @@
|
||||
<div>
|
||||
{% if not notification.read_at %}
|
||||
<a href="/notification/{{ notification.id }}/read" class="inline-block">
|
||||
<button class="btn btn-alert bg-red-100 dark:bg-red-900" type="button">
|
||||
<button class="btn btn-primary" type="button">
|
||||
✓
|
||||
<span class="sr-only">Notification gelesen</span>
|
||||
</button>
|
||||
@ -38,8 +48,8 @@
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<details class="py-3 bg-gray-200 dark:bg-primary-950 rounded-b-md">
|
||||
<summary class="px-3">Vergangene Nachrichten (14 Tage)</summary>
|
||||
<details class="py-3 border-t rounded-b-md">
|
||||
<summary class="px-3 cursor-pointer">Vergangene Nachrichten (14 Tage)</summary>
|
||||
<div class="divide-y text-sm">
|
||||
{% for notification in notifications %}
|
||||
{% if notification.read_at %}
|
||||
|
Loading…
Reference in New Issue
Block a user