2024-08-13 23:02:34 +02:00
{% macro plannedtrips() %}
{% if planned_trips %}
<script>
function setChoiceByLabel(choicesInstance, label) {
const choices = choicesInstance.config.choices;
const normalizedLabel = label.trim().replace(/\n/g, '');
const choice = choices.find(c => {
const choiceLabel = c.label.trim().replace(/\n/g, '');
return choiceLabel === normalizedLabel;
});
if (choice) {
choicesInstance.setChoiceByValue(choice.value);
} else {
console.warn(`Choice with label "${normalizedLabel}" not found`);
}
}
</script>
<div class="bg-white dark:bg-primary-900 rounded-md shadow pb-2 mt-3">
<h2 class="h2">Heute geplante Ausfahrten</h2>
2024-09-03 21:35:43 +03:00
<div class="grid grid-cols-1 gap-3 w-full">
2024-08-13 23:02:34 +02:00
{% for planned_trip in planned_trips | sort(attribute='planned_starting_time') %}
2024-09-03 21:35:43 +03:00
<div class="pt-2 px-3 {% if not loop.first %}border-t{% endif %} text-primary-900 dark:text-white flex justify-between items-center">
2024-08-13 23:02:34 +02:00
<strong class="block">
2024-09-03 22:09:42 +03:00
{% set amount_members = planned_trip.rower | length + 1 %}
2024-09-03 21:35:43 +03:00
{{ planned_trip.cox_name }} ({{ amount_members }} Person{{ amount_members | pluralize(singular="", plural="en") }})
<small class="block">{{ planned_trip.planned_starting_time }}</small>
2024-09-03 22:09:42 +03:00
</strong>
<button class="btn btn-primary ml-3"
onclick="choiceObjects['newrower'].removeActiveItems(-2);choiceObjects['newrower'].setChoiceByValue('{{ planned_trip.cox_id }}'); {% for rower in planned_trip.rower %}setChoiceByLabel(choiceObjects['newrower'], '{{ rower.name }}');{% endfor %}window.scrollTo(0,0); ">
👥
</button>
2024-08-13 23:02:34 +02:00
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% endmacro plannedtrips %}
2024-03-20 09:14:26 +01:00
{% macro boatreservation() %}
2024-04-02 21:31:02 +02:00
<div class="bg-white dark:bg-primary-900 rounded-md shadow pb-2 mt-3">
<h2 class="h2">Reservierungen ({{ reservations | length }})</h2>
<div class="grid grid-cols-1 gap-3 mb-3 w-full">
2024-04-23 20:40:06 +02:00
{% for _, reservations_for_event in reservations %}
{% set reservation = reservations_for_event[0] %}
2024-09-03 21:35:43 +03:00
<div class="pt-2 px-3 {% if not loop.first %}border-t{% endif %} text-primary-900 dark:text-white">
2024-04-02 21:31:02 +02:00
<strong class="block">
{{ reservation.start_date | date(format="%d.%m.%Y") }}
{% if reservation.end_date != reservation.start_date %}
-
{{ reservation.end_date | date(format="%d.%m.%Y") }}
{% endif %}
<small>({{ reservation.time_desc }})</small>
</strong>
<span class="block">
2024-04-23 20:40:06 +02:00
{% for reservation in reservations_for_event %}
{{ reservation.boat.name }}
{% if not loop.last %}+{% endif %}
{% endfor %}
2024-04-02 21:31:02 +02:00
<small>({{ reservation.user_applicant.name }})</small>
</span>
<span class="text-sm italic">{{ reservation.usage }}</span>
</div>
{% else %}
<p class="p-3 text-center text-black dark:text-white">Keine Reservierung</p>
{% endfor %}
2024-03-20 09:14:26 +01:00
</div>
2024-04-02 21:31:02 +02:00
</div>
2024-03-20 09:14:26 +01:00
{% endmacro boatreservation %}
2023-04-06 09:30:43 +02:00
{% macro header(loggedin_user) %}
2024-03-04 13:28:42 +01:00
<header class="bg-primary-900 text-white flex justify-center p-3 fixed w-full z-10">
<div class="max-w-screen-xl w-full flex justify-between items-center">
<div class="w-1/3 truncate">
2024-04-19 11:25:25 +02:00
<a href="/">
2024-12-11 19:22:29 +01:00
Ahoi
2024-03-21 20:47:48 +01:00
{{ loggedin_user.name }}
</a>
</div>
2024-12-11 19:22:29 +01:00
<div class="w-1/3 text-xl"
onclick="document.getElementById('call-for-action').showModal()">💡</div>
2024-04-19 11:25:25 +02:00
<div class="flex items-center">
{% if loggedin_user.amount_unread_notifications > 0 %}
2024-04-19 12:06:24 +02:00
<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>
2024-04-19 11:25:25 +02:00
</a>
{% endif %}
2024-04-15 11:23:07 +02:00
<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"
data-trigger="sidebar"
data-header="Menü"
data-body="#mobile-menu">
{% include "includes/book" %}
<span class="sr-only">Logbuch</span>
</a>
<div class="hidden">
<div id="mobile-menu">
2024-12-11 16:24:20 +01:00
<a href="/" class="block w-100 py-2 hover:text-primary-600">Geplante Ausfahrten</a>
2024-04-15 11:23:07 +02:00
{% if "admin" in loggedin_user.roles %}
2024-12-11 16:24:20 +01:00
<a href="/admin/user"
class="block w-100 py-2 hover:text-primary-600 border-t">Mitgliederverwaltung</a>
2024-12-11 19:22:29 +01:00
<a href="/admin/log"
class="block w-100 py-2 hover:text-primary-600 border-t">Log</a>
2024-04-15 11:23:07 +02:00
{% endif %}
<a href="/auth/logout"
class="block w-100 py-2 hover:text-primary-600 border-t">Ausloggen
<svg class="inline h-4"
width="24"
height="24"
viewbox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-log-out">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path>
<polyline points="16 17 21 12 16 7"></polyline>
<line x1="21" y1="12" x2="9" y2="12"></line>
</svg>
</a>
2024-04-14 20:20:22 +02:00
</div>
2024-04-15 11:23:07 +02:00
</div>
2023-11-03 14:30:43 +01:00
</div>
2024-03-04 13:28:42 +01:00
</div>
2024-03-21 20:47:48 +01:00
</header>
2024-12-11 19:22:29 +01:00
<dialog id="call-for-action"
class="max-w-screen-sm dark:bg-primary-600 dark:text-white rounded-md"
onclick="document.getElementById('call-for-action').close()">
<div onclick="event.stopPropagation();" class="p-3">
<button type="button"
onclick="document.getElementById('call-for-action').close()"
title="Schließen"
class="sidebar-close border-0 bg-primary-100 focus:bg-primary-50 text-black flex items-center justify-center transform rotate-45 absolute right-0 mr-3">
<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>
</button>
<div class="mt-8">
<p class="p-2">
Willkommen in der Testversion von ruad.at!
Hier wird nochmal <s>alles</s> vieles erklärt.
Wenn du Fragen/Wünsche/... hast, kannst du dich gerne jederzeit unter <a href="mailto:philipp@hofer.link">philipp@hofer.link</a> melden.
</p>
<details class="p-2">
<summary>Rollen: Admin, Steuerperson, Anfänger + Eventmanager</summary>
<p>
Aktuell gibt es <b>4 Rollen</b>, die jedes Mitglied haben kann:
<ol class="list-decimal p-5">
<li><emph>Admin:</emph> dürfen Mitglieder verwalten (siehe Menüeintrag rechts oben → <q>Mitgliederverwaltung</q></li>
<li><emph>Steuerperson:</emph> können selbstständig <q>Ausfahrten</q> ausschreiben/bearbeiten, und sich zum steuern bei <q>Events</q> melden</li>
<li><emph>Anfänger:</emph> sehen nur Ausfahrten und Events, die explizit für Anfänger ausgeschrieben wurden</li>
<li><emph>Eventmanager:</emph> können <q>Events</q> ausschreiben/bearbeiten</li>
</ol>
</p>
</details>
<details class="p-2">
<summary>Rudertrips: Ausfahrten + Events</summary>
<p class="mt-3">
Es gibt 2 Arten von Rudertrips, die ausgeschrieben werden können:
<ol class="list-decimal p-5">
<li>Ausfahrten: Können jederzeit von Steuerpersonen ausgeschrieben/bearbeitet werden</li>
<li>Events: für Veranstaltungen, wo nicht nur Rudererinnen gesucht werden, sondern auch Steuerpersonen (zB Anrudern, Abrudern, Sternfahrten, Wanderfahrten, ...)</li>
</ol>
</p>
</details>
<details class="p-2">
<summary>Bearbeiten</summary>
<p class="mt-3">
Details, wie zB Anmerkungen können jederzeit geändert werden.
Wichtige Infos, auf die sich Rudernde verlassen (zB Startzeit und Ausfahrtstyp) können nicht mehr geändert werden.
Wenn sich die Startzeit ändert, kann man die Ausfahrt/Event absagen und stattdessen einen neuen Trip ausschreiben.
</p>
</details>
<details class="p-2">
<summary>Absagen/Löschen</summary>
<p class="mt-3">
Ausfahrten und Events können gelöscht werden, solange keine Ruderer angemeldet sind.
Sobald jemand angemeldet ist, kann die Ausfahrt/Event nicht mehr gelöscht werden, dafür <q>abgesagt</q> werden.
In diesem Fall bekommen alle die sich angemeldet haben eine Nachricht.
Sobald alle die Nachricht gelesen haben, wird der Trip automatisch gelöscht.
</p>
</details>
<details class="p-2">
<summary>Wieviele Tage sehe ich?</summary>
<p class="mt-3">
Rudernde sehen alle Trips 10 Tage im voraus + zusätzlich alle, wo <q>Immer Anzeigen</q> ausgewählt wurde.
Steuerpersonen sehen das ganze Jahr (um im Vorhinein Ausfahrten ausschreiben zu können). Ab Dezember sehen sie auch das volle kommende Jahr.
</p>
</details>
</div>
</dialog>
2024-03-21 20:47:48 +01:00
<div class="h-8"></div>
{% endmacro header %}
{% macro input(label, name, type, required=false, class='rounded-md', value='', min='', hide_label=false, id='', autofocus=false, wrapper_class='', pattern='', readonly=false, accept='') %}
<div class="{{ wrapper_class }}">
<label for="{{ name }}"
class="{% if hide_label %} sr-only {% else %} text-sm text-gray-600 dark:text-white {% endif %}">
2024-03-04 13:28:42 +01:00
{{ label }}
</label>
2024-03-21 20:47:48 +01:00
<input {% if type=='datetime-local' %}onclick='if (!this.value) setCurrentdate(this)'{% endif %}
{% if id %} id="{{ id }}" {% else %} id="{{ name }}" {% endif %}
name="{{ name }}"
type="{{ type }}"
{% if required %}required{% endif %}
value="{{ value }}"
class="input {{ class }}"
placeholder="{% if hide_label %}{{ label }}{% endif %}"
{% if min is defined %}min="{{ min }}"{% endif %}
{% if autofocus %}autofocus{% endif %}
{% if accept %}accept="{{ accept }}"{% endif %}
{% if pattern %}pattern="{{ pattern }}"{% endif %}
{% if readonly %}readonly{% endif %}>
</div>
{% endmacro input %}
2024-12-11 16:24:20 +01:00
{% macro fancy_role_name(name) %}
{%- if name == "cox" -%}
Steuerperson
{%- elif name == "manage_events" -%}
Eventmanager
{%- elif name == "admin" -%}
Admin
{%- elif name == "scheckbuch" -%}
Anfänger
{%- else -%}
{{name}}
{%- endif -%}
{% endmacro fancy_role_name %}
2024-12-11 19:22:29 +01:00
{% macro checkbox(label, name, id='', checked=false, class='', disabled=false, readonly=false, help=false) %}
2024-03-21 20:47:48 +01:00
<label for="{{ name }}{{ id }}"
class="flex items-center cursor-pointer text-black dark:text-white hover:text-gray-900 dark:hover:text-gray-100 {{ class }}">
<input type="checkbox"
id="{{ name }}{{ id }}"
name="{{ name }}"
2024-07-23 14:57:09 +02:00
{% if checked %}checked{% endif %}
{% if disabled %}disabled{% endif %}
{% if readonly %}readonly="readonly"{% endif %}
2024-03-21 20:47:48 +01:00
class="h-4 w-4 accent-primary-600 dark:accent-primary-200 mr-2" />
2024-12-11 16:24:20 +01:00
{{ self::fancy_role_name(name=label) }}
2024-12-11 19:22:29 +01:00
{% if help %}
<span class=""
onclick="this.nextElementSibling.showModal()">❓</span>
<dialog
class="max-w-screen-sm dark:bg-primary-600 dark:text-white rounded-md"
onclick="this.close()">
<div onclick="event.stopPropagation();" class="p-3">
<button type="button"
onclick="this.parentNode.parentNode.close()"
title="Schließen"
class="sidebar-close border-0 bg-primary-100 focus:bg-primary-50 text-black flex items-center justify-center transform rotate-45 absolute right-0 mr-3">
<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>
</button>
<div class="mt-8">
<p>
{{help}}
</p>
</div>
</dialog>
{% endif %}
2024-03-21 20:47:48 +01:00
</label>
{% endmacro checkbox %}
2024-11-25 12:12:36 +01:00
{% macro select(label, data, name='trip_type', default='', id='', selected_id='', display='', extras='', class='', wrapper_class='', required=false, show_seats=false, new_last_entry='', nonSelectableDefault=false, only_ergo=false) %}
2024-03-21 20:47:48 +01:00
<div class="{{ wrapper_class }}">
<label for="{{ name }}" class="text-sm text-gray-600 dark:text-gray-100">{{ label }}</label>
{% if display == '' %}
{% set display = ["name"] %}
{% endif %}
<select name="{{ name }}"
{% if id %} id="{{ id }}" {% else %} id="{{ name }}" {% endif %}
class="input rounded-md {{ class }}"
{% if required %}required="required"{% endif %}>
{% if default %}<option selected value>{{ default }}</option>{% endif %}
2024-04-29 21:40:35 +02:00
{% if nonSelectableDefault %}<option disabled selected value>{{ nonSelectableDefault }}</option>{% endif %}
2024-03-21 20:47:48 +01:00
{% for d in data %}
2024-11-25 12:12:36 +01:00
<option value="{{ d.id }}" {% if only_ergo and d.id!=4 %} disabled {% endif %}{% if d.id == selected_id %}selected{% endif %} {% if extras != '' %} {% for extra in extras %} {% if extra != 'on_water' and d[extra] %} data- {{ extra }}={{ d[extra] }} {% else %} {% if d[extra] %}disabled{% endif %} {% endif %} {% endfor %} {% endif %} {% if show_seats %} data-custom-properties='{"amount_seats": {{ d["amount_seats"] }}, "owner": "{{ d["owner"] }}", "default_destination": "{{ d["default_destination"] }}", "boat_in_ottensheim": {{ d["location_id"] == 2 }}, "boat_reserved_today": {{ d["reserved_today"] }}, "convert_handoperated_possible": {{ d["convert_handoperated_possible"] }}, "default_handoperated": {{ d["default_shipmaster_only_steering"] }}}' {% endif %}>
2024-03-21 20:47:48 +01:00
{% for displa in display -%}
{%- if d[displa] -%}
{{- d[displa] -}}
{%- else -%}
{{- displa -}}
{%- endif -%}
{%- endfor %}
</option>
{% endfor %}
{% if new_last_entry %}<option value="-1">{{ new_last_entry }}</option>{% endif %}
</select>
</div>
{% endmacro select %}
{% macro alert(message, type, class='') %}
<div class="{{ class }} alert-{{ type }} text-white px-3 py-1 rounded-md text-center">{{ message }}</div>
{% endmacro alert %}
{% macro box(participants, empty_seats='', header='Freie Plätze:', text='Keine Ruderer angemeldet', bg='primary-600', color='white', trip_details_id='', allow_removing=false) %}
<div class="text-{{ color }} bg-{{ bg }} text-center p-1 mt-1 rounded-t-md">
{{ header }}
{{ empty_seats }}
</div>
<div class="p-2 border border-t-0 border-{{ bg }} mb-4 rounded-b-md">
{% if participants | length > 0 %}
{% for rower in participants %}
2024-04-19 12:48:23 +02:00
<div class="relative">
{{ rower.name }}
2024-12-11 16:24:20 +01:00
{% if rower.is_guest %}<small class="text-gray-600 dark:text-gray-100">(Anfänger)</small>{% endif %}
2024-04-19 12:48:23 +02:00
{% if rower.is_real_guest %}
<small class="text-gray-600 dark:text-gray-100">(Gast)</small>
{% if allow_removing %}
2024-12-11 16:24:20 +01:00
<a href="/remove/{{ trip_details_id }}/{{ rower.name | urlencode }}"
2024-04-24 08:57:41 +02:00
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>
2024-04-19 12:48:23 +02:00
</a>
{% endif %}
2024-03-04 13:28:42 +01:00
{% endif %}
2024-04-24 08:57:41 +02:00
<span class="hidden">(angemeldet seit
{{ rower.registered_at }})</span>
2024-04-19 12:48:23 +02:00
</div>
2024-03-21 20:47:48 +01:00
{% endfor %}
{% else %}
{{ text }}
{% endif %}
</div>
{% endmacro box %}
{% macro faq(question, answer) %}
<div>
<h2 class="flex mb-4 text-lg font-bold text-primary-900">{{ question }}</h2>
<p class="text-primary-950">{{ answer | safe }}</p>
</div>
{% endmacro faq %}