allow-reservation-edits #424
@ -72,5 +72,6 @@ export default defineConfig({
|
|||||||
webServer: {
|
webServer: {
|
||||||
timeout: 15 * 60 * 1000,
|
timeout: 15 * 60 * 1000,
|
||||||
command: 'cd .. && ./test_db.sh && cargo r',
|
command: 'cd .. && ./test_db.sh && cargo r',
|
||||||
|
url: 'http://127.0.0.1:8000'
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -13,3 +13,4 @@
|
|||||||
@import 'components/search';
|
@import 'components/search';
|
||||||
@import 'components/important';
|
@import 'components/important';
|
||||||
@import 'components/searchable-table';
|
@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").fill("cox");
|
||||||
await page.getByPlaceholder("Passwort").press("Enter");
|
await page.getByPlaceholder("Passwort").press("Enter");
|
||||||
await page.locator('li').filter({ hasText: 'Geplante Ausfahrten' }).getByRole('link').click();
|
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").click();
|
||||||
await page.locator("#sidebar #planned_starting_time").fill("18:00");
|
await page.locator("#sidebar #planned_starting_time").fill("18:00");
|
||||||
await page.locator("#sidebar #planned_starting_time").press("Tab");
|
await page.locator("#sidebar #planned_starting_time").press("Tab");
|
||||||
@ -39,7 +39,7 @@ test.describe("cox can edit trips", () => {
|
|||||||
await page.getByPlaceholder("Passwort").fill("cox");
|
await page.getByPlaceholder("Passwort").fill("cox");
|
||||||
await page.getByPlaceholder("Passwort").press("Enter");
|
await page.getByPlaceholder("Passwort").press("Enter");
|
||||||
await page.locator('li').filter({ hasText: 'Geplante Ausfahrten' }).getByRole('link').click();
|
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").click();
|
||||||
await page.locator("#sidebar #planned_starting_time").fill("18:00");
|
await page.locator("#sidebar #planned_starting_time").fill("18:00");
|
||||||
await page.locator("#sidebar #planned_starting_time").press("Tab");
|
await page.locator("#sidebar #planned_starting_time").press("Tab");
|
||||||
|
@ -31,21 +31,26 @@
|
|||||||
<a href="/">
|
<a href="/">
|
||||||
Hü
|
Hü
|
||||||
{{ loggedin_user.name }}
|
{{ loggedin_user.name }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
{% if loggedin_user.amount_unread_notifications > 0 %}
|
{% 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">
|
<a href="/#notification"
|
||||||
<svg class="w-3 h-3 me-1.5"
|
class="relative inline-flex items-end ms-2 me-3">
|
||||||
|
<svg height="20"
|
||||||
|
width="24"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
viewBox="0 0 20 20">
|
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="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" />
|
<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>
|
</svg>
|
||||||
{{ loggedin_user.amount_unread_notifications }}</span>
|
<small class="bg-red-500 rounded-full w-3 h-3 inline-flex justify-center items-center absolute p-1 notification">
|
||||||
{% endif %}
|
{{ loggedin_user.amount_unread_notifications }}
|
||||||
|
</small>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
{% endif %}
|
||||||
<div>
|
|
||||||
<a href="#"
|
<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"
|
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"
|
data-sidebar="true"
|
||||||
@ -175,18 +180,24 @@
|
|||||||
<div class="p-2 border border-t-0 border-{{ bg }} mb-4 rounded-b-md">
|
<div class="p-2 border border-t-0 border-{{ bg }} mb-4 rounded-b-md">
|
||||||
{% if participants | length > 0 %}
|
{% if participants | length > 0 %}
|
||||||
{% for rower in participants %}
|
{% for rower in participants %}
|
||||||
|
<div class="relative">
|
||||||
{{ rower.name }}
|
{{ rower.name }}
|
||||||
{% if rower.is_guest %}<small class="text-gray-600 dark:text-gray-100">(Scheckbuch)</small>{% endif %}
|
{% if rower.is_guest %}<small class="text-gray-600 dark:text-gray-100">(Scheckbuch)</small>{% endif %}
|
||||||
{% if rower.is_real_guest %}
|
{% if rower.is_real_guest %}
|
||||||
<small class="text-gray-600 dark:text-gray-100">(Gast)</small>
|
<small class="text-gray-600 dark:text-gray-100">(Gast)</small>
|
||||||
{% if allow_removing %}
|
{% if allow_removing %}
|
||||||
<a href="/planned/remove/{{ trip_details_id }}/{{ rower.name }}"
|
<a href="/planned/remove/{{ trip_details_id }}/{{ rower.name }}"
|
||||||
class="btn btn-attention btn-fw">Abmelden</a>
|
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 %}
|
{% endif %}
|
||||||
<span class="hidden">(angemeldet seit
|
<span class="hidden">(angemeldet seit
|
||||||
{{ rower.registered_at }})</span>
|
{{ rower.registered_at }})</span>
|
||||||
<br />
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ text }}
|
{{ text }}
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
{% 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">Ruderassistent</h1>
|
<h1 class="h1">
|
||||||
|
Ruder
|
||||||
|
<wbr />
|
||||||
|
assistent
|
||||||
|
</h1>
|
||||||
<div class="grid gap-3 my-5">
|
<div class="grid gap-3 my-5">
|
||||||
<div class="m-auto">
|
<div class="m-auto">
|
||||||
<a href="/planned"
|
<a href="/planned"
|
||||||
@ -11,9 +15,15 @@
|
|||||||
<span class="text-xl px-3">Geplante Ausfahrten</span>
|
<span class="text-xl px-3">Geplante Ausfahrten</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</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">
|
role="alert">
|
||||||
<h2 class="h2">Nachrichten</h2>
|
<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">
|
<div class="divide-y">
|
||||||
{% for notification in notifications %}
|
{% for notification in notifications %}
|
||||||
{% if not notification.read_at %}
|
{% if not notification.read_at %}
|
||||||
@ -27,7 +37,7 @@
|
|||||||
<div>
|
<div>
|
||||||
{% if not notification.read_at %}
|
{% if not notification.read_at %}
|
||||||
<a href="/notification/{{ notification.id }}/read" class="inline-block">
|
<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>
|
<span class="sr-only">Notification gelesen</span>
|
||||||
</button>
|
</button>
|
||||||
@ -38,8 +48,8 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<details class="py-3 bg-gray-200 dark:bg-primary-950 rounded-b-md">
|
<details class="py-3 border-t rounded-b-md">
|
||||||
<summary class="px-3">Vergangene Nachrichten (14 Tage)</summary>
|
<summary class="px-3 cursor-pointer">Vergangene Nachrichten (14 Tage)</summary>
|
||||||
<div class="divide-y text-sm">
|
<div class="divide-y text-sm">
|
||||||
{% for notification in notifications %}
|
{% for notification in notifications %}
|
||||||
{% if notification.read_at %}
|
{% if notification.read_at %}
|
||||||
|
Loading…
Reference in New Issue
Block a user