2023-06-09 13:33:27 +02:00

1838 lines
68 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% macro render_field_with_errors(field) %}
{% set is_collapsible = kwargs['is_collapsible'] if 'is_collapsible' in kwargs else False %}
{% if is_collapsible %}
<div class="mb-3" id="{{ field.id }}-show-container"{% if field.data %} style="display: none;"{% endif %}>
<a href="#" class="show-link" data-container="{{ field.id }}-container" data-show-container="{{ field.id }}-show-container"><i class="fa fa-plus"></i> {{ field.label.text }}</a>
</div>
<div id="{{ field.id }}-container"{% if not field.data %} style="display: none;"{% endif %}>
{% endif %}
{% set is_required = kwargs['is_required'] if 'is_required' in kwargs else field.flags.required %}
{% set label_text = field.label.text + ' *' if is_required else field.label.text %}
<div class="form-group {% if field.errors %} has-error{% endif -%} {% if 'formrow' in kwargs %} row{% endif -%}">
{% if 'label_hidden' in kwargs or ('ri' in kwargs and kwargs['ri'] == 'checkbox') %}
{% else %}
{% set label_class = "col-sm-2 col-form-label" if 'formrow' in kwargs else "mb-0" %}
{{ field.label(text=label_text, class=label_class) }}
{% endif %}
{% if 'formrow' in kwargs %}
<div class="col-sm-10">
{% endif %}
{% if field.description %}
<div class="form-text mt-0 text-muted w-100">
{{ field.description }}
</div>
{% endif %}
<div class="input-group">
{% set field_class = kwargs['class'] if 'class' in kwargs else '' %}
{% set field_class = field_class + ' form-control' %}
{% if field.errors %}
{% set field_class = field_class + ' is-invalid' %}
{% endif %}
{% if 'ri' in kwargs and kwargs['ri'] == 'multicheckbox' %}
<fieldset class="form-group">
{% for choice in field %}
<div class="form-check">
{{ choice(class="form-check-input") }}
{{ choice.label(class="form-check-label") }}
</div>
{% endfor %}
</fieldset>
{% elif 'ri' in kwargs and kwargs['ri'] == 'multicheckbox-inline' %}
<fieldset class="form-group my-auto">
{% for choice in field %}
<div class="form-check form-check-inline">
{{ choice(class="form-check-input") }}
{{ choice.label(class="form-check-label") }}
</div>
{% endfor %}
</fieldset>
{% elif 'ri' in kwargs and kwargs['ri'] == 'checkbox' %}
<div class="form-check">
{{ field(class="form-check-input") }}
{{ field.label(class="form-check-label") }}
</div>
{% elif 'ri' in kwargs and kwargs['ri'] == 'switch' %}
<div class="custom-control custom-switch">
{{ field(class="custom-control-input") }}
<label class="custom-control-label" for="{{ field.id }}"></label>
</div>
{% elif 'ri' in kwargs and kwargs['ri'] == 'radio-buttons' %}
<div class="btn-group btn-group-toggle" data-toggle="buttons">
{% for choice in field %}
{% set color = kwargs['colors'][loop.index0] if 'colors' in kwargs else 'secondary' %}
<label class="btn btn-outline-{{ color }}">
<input type="radio" id="{{ choice.id }}" name="{{ field.id }}" value="{{ choice.id[-1] }}" {% if choice.checked %}checked {% endif %}> {{ choice.label.text }}
</label>
{% endfor %}
</div>
{% elif 'ri' in kwargs and kwargs['ri'] == 'radio' %}
{{ render_radio_buttons(field) }}
{% else %}
{% if 'class' in kwargs %}
{% set _dummy=kwargs.pop('class') %}
{% endif %}
{{ field(class=field_class, **kwargs)|safe }}
{% endif %}
{% if 'ri' in kwargs %}
{% if kwargs['ri'] == 'rrule' %}
<script type="text/javascript">
$( function() {
$("textarea[name=recurrence_rule]").recurrenceinput({lang:'de', startField: "start", ajaxURL: "{{ url_for('event_rrule') }}", firstDay: 1});
});
</script>
{% endif %}
{% endif %}
</div>
{% if field.errors %}
<div class="invalid-feedback d-block">
{% for error in field.errors %}
<div>{{ error }}</div>
{% endfor %}
</div>
{% endif %}
{% if 'formrow' in kwargs %}
</div>
{% endif %}
</div>
{% if is_collapsible %}
<div class="mb-3" id="{{ field.id }}-hide-container">
<a href="#" class="hide-link" data-container="{{ field.id }}-container" data-show-container="{{ field.id }}-show-container"><i class="fa fa-minus"></i> {{ field.label.text }}</a>
</div>
</div>
{% endif %}
{% endmacro %}
{% macro render_field(field) %}
<p>{{ field(class="btn btn-primary", **kwargs)|safe }}</p>
{% endmacro %}
{% macro render_field_errors(field) %}
<p>
{% if field and field.errors %}
<ul>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</p>
{% endmacro %}
{% macro render_event_organizer(organizer) %}
{{ organizer.name }}
{% endmacro %}
{% macro render_location(location) %}{{ location | location_str }}{% endmacro %}
{% macro render_place(place) %}{{ place | place_str }}{% endmacro %}
{% macro render_events_sub_menu() %}
{% endmacro %}
{% macro render_location_card(location, place=None) %}
{% if location %}
<div class="card card-body">
<p>
{{ location.street }}<br />
{{ location.postalCode }} {{ location.city }}
</p>
<p>
<a href="http://www.google.com/maps?q={% if place %}{{ render_place(place) | quote_plus }}{% else %}{{ render_location(location) | quote_plus }}{% endif %}">{{ _('Show on Google Maps') }}</a>
</p>
</div>
{% endif %}
{% endmacro %}
{% macro render_kv_begin() %}
<dl class="row">
{% endmacro %}
{% macro render_kv_end() %}
</dl>
{% endmacro %}
{% macro render_kv_prop(prop, label_key = None) %}
{% if prop %}
<dt class="col-sm-3">{{ _(label_key) }}</dt>
<dd class="col-sm-9">{% if prop|is_list %}{{ prop|join(', ') }}{% else %}{{ prop }}{% endif %}</dd>
{% endif %}
{% endmacro %}
{% macro render_string_prop(prop, icon = None, label_key = None) %}
{% if prop %}
<div>
{% if icon %}<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>{% endif %}
{{ prop }}
</div>
{% endif %}
{% endmacro %}
{% macro render_text_prop(prop, icon = None, label_key = None) %}
{% if prop %}
<div>
{% if icon %}<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>{% endif %}
<span style="white-space:pre-wrap;">{{ prop }}</span>
</div>
{% endif %}
{% endmacro %}
{% macro render_int_prop(prop, icon = None, label_key = None) %}
{% if prop %}
<div>
{% if icon %}<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>{% endif %}
{{ prop }}
</div>
{% endif %}
{% endmacro %}
{% macro render_bool_prop(prop, icon, label_key) %}
{% if prop %}
<div>
<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>
{{ _(label_key) }}
</div>
{% endif %}
{% endmacro %}
{% macro render_enum_prop(prop, icon, label_key, ignore=0) %}
{% if prop and prop.value > 0 and prop.value != ignore %}
<div>
<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>
{{ prop | loc_enum }}
</div>
{% endif %}
{% endmacro %}
{% macro render_range_prop(from, to, icon, label_key) %}
{% if from or to %}
<div>
<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>
{{ from if from }} - {{ to if to }}
</div>
{% endif %}
{% endmacro %}
{% macro render_tag_prop(tags) %}
{% if tags %}
<div>
<i class="fa fa-fw fa-tags" data-toggle="tooltip" title="{{ _('Tags') }}"></i>
{{ tags }}
</div>
{% endif %}
{% endmacro %}
{% macro render_link_prop(link) %}
{% if link %}
<div>
<i class="fa fa-fw fa-link" data-toggle="tooltip" title="{{ _('Link') }}"></i>
<a href="{{ link | ensure_link_scheme }}" target="_blank" rel="noopener noreferrer" style="word-break: break-all;">{{ link }}</a>
</div>
{% endif %}
{% endmacro %}
{% macro render_email_prop(email) %}
{% if email %}
<div>
<i class="fa fa-fw fa-envelope" data-toggle="tooltip" title="{{ _('Email') }}"></i>
<a href="mailto:{{ email }}">{{ email }}</a>
</div>
{% endif %}
{% endmacro %}
{% macro render_event_status_pill(event) %}
{% if event.status and event.status != 1 %}
<span class="badge badge-pill badge-warning">{{ event.status | loc_enum }}</span>
{% endif %}
{% endmacro %}
{% macro render_booked_up_pill(event) %}
{% if event.booked_up %}
<span class="badge badge-pill badge-warning">{{ _('Booked up') }}</span>
{% endif %}
{% endmacro %}
{% macro render_public_status_pill(event) %}
{% if event.public_status %}
{% if event.public_status == 1 %}
<span class="badge badge-pill badge-dark">{{ _('PublicStatus.draft') }}</span>
{% elif event.public_status == 3 %}
<span class="badge badge-pill badge-dark">{{ _('PublicStatus.planned') }}</span>
{% endif %}
{% endif %}
{% endmacro %}
{% macro render_attendance_mode_pill(event) %}
{% if event.attendance_mode and event.attendance_mode.value != 1 %}
<span class="badge badge-pill badge-info">{{ event.attendance_mode | loc_enum }}</span>
{% endif %}
{% endmacro %}
{% macro render_event_warning_pills(event) %}
{{ render_public_status_pill(event) }} {{ render_event_status_pill(event) }} {{ render_booked_up_pill(event) }} {{ render_attendance_mode_pill(event) }}
{% endmacro %}
{% macro render_event_review_status_pill(event) %}
{% if event.review_status %}
<span class="badge badge-pill {% if event.review_status == 2 %}badge-success{% elif event.review_status == 1 %}badge-info{% else %}badge-danger{% endif %}">{{ event.review_status | loc_enum }}</span>
{% endif %}
{% endmacro %}
{% macro render_reference_request_review_status_pill(reference_request) %}
{% if reference_request.review_status %}
<span class="badge badge-pill {% if reference_request.review_status == 1 %}badge-info{% elif reference_request.review_status == 2 %}badge-success{% else %}badge-danger{% endif %}">{{ reference_request.review_status | loc_enum }}</span>
{% endif %}
{% endmacro %}
{% macro render_verification_request_review_status_pill(reference_request) %}
{% if reference_request.review_status %}
<span class="badge badge-pill {% if reference_request.review_status == 1 %}badge-info{% elif reference_request.review_status == 2 %}badge-success{% else %}badge-danger{% endif %}">{{ reference_request.review_status | loc_enum }}</span>
{% endif %}
{% endmacro %}
{% macro render_admin_unit_badges(admin_unit) %}
{% if admin_unit.is_verified %}<i class="fa fa-check-circle text-primary" data-toggle="tooltip" title="{{ _('Verified') }}"></i>{% endif %}
{% endmacro %}
{% macro render_phone_prop(phone) %}
{% if phone %}
<div>
<i class="fa fa-fw fa-phone" data-toggle="tooltip" title="{{ _('Phone') }}"></i>
<a href="tel:{{ phone }}">{{ phone }}</a>
</div>
{% endif %}
{% endmacro %}
{% macro render_fax_prop(fax) %}
{% if fax %}
<div><i class="fa fa-fw fa-fax" data-toggle="tooltip" title="{{ _('Fax') }}"></i> {{ fax }}</div>
{% endif %}
{% endmacro %}
{% macro render_location_prop(location) %}
{% if location and location.street or location.postalCode or location.city %}
<div>
<i class="fa fa-fw fa-map-marker" data-toggle="tooltip" title="{{ _('Location') }}"></i>
{{ render_location(location) }}
</div>
{% endif %}
{% endmacro %}
{% macro render_img_src(image, size=500) %}
<img src="{{ url_for_image(image, s=size) }}" class="{{ kwargs['class'] or 'img-fluid' }}" style="{{ kwargs['style'] or 'max-width:100%;' }}" alt="{{ kwargs['alt'] or 'image' }}" />
{% endmacro %}
{% macro render_image(image, size=500) %}
{% if image %}
{% set img_class = kwargs.pop('class', '') %}
{% set img_style = kwargs.pop('style', '') %}
{% set img_class = img_class + ' figure-img img-fluid' %}
<figure class="figure mx-auto">
{{ render_img_src(image, size, class=img_class, style=img_style, **kwargs) }}
{% if image.copyright_text %}
<figcaption class="figure-caption">&copy; {{ image.copyright_text }}</figcaption>
{% endif %}
</figure>
{% endif %}
{% endmacro %}
{% macro render_logo(image) %}
{{ render_image(image, 120, style="max-width:120px;", alt="Logo") }}
{% endmacro %}
{% macro render_event_review_status(event) %}
{{ render_enum_prop(event.review_status, 'fa-certificate', 'Review status') }}
{{ render_enum_prop(event.rejection_resaon, 'fa-search-minus', 'Rejection reason') }}
{% endmacro %}
{% macro render_reference_request_review_status(reference_request) %}
{{ render_enum_prop(reference_request.review_status, 'fa-certificate', 'Review status') }}
{{ render_enum_prop(reference_request.rejection_reason, 'fa-search-minus', 'Rejection reason') }}
{% endmacro %}
{% macro render_verification_request_review_status(verification_request) %}
{{ render_enum_prop(verification_request.review_status, 'fa-certificate', 'Review status') }}
{{ render_enum_prop(verification_request.rejection_reason, 'fa-search-minus', 'Rejection reason') }}
{% endmacro %}
{% macro render_audit(tracking_mixing, show_user=False) %}
{% set created_at = tracking_mixing.created_at | datetimeformat('short') %}
{% set updated_at = tracking_mixing.updated_at | datetimeformat('short') %}
{% if show_user %}
{{ _('Created at %(created_at)s by %(created_by)s.', created_at=created_at, created_by=tracking_mixing.created_by.email) }}
{% else %}
{{ _('Created at %(created_at)s.', created_at=created_at) }}
{% endif %}
{% if created_at != updated_at %}
{% if show_user %}
{{ _('Last updated at %(updated_at)s by %(updated_by)s.', updated_at=updated_at, updated_by=tracking_mixing.updated_by.email) }}
{% else %}
{{ _('Last updated at %(updated_at)s.', updated_at=updated_at) }}
{% endif %}
{% endif %}
{% endmacro %}
{% macro render_audit_container(tracking_mixing, show_user=False) %}
<div class="my-4 small">{{ render_audit(tracking_mixing, show_user) }}</div>
{% endmacro %}
{% macro render_event_add_props(event) %}
{{ render_string_prop(event.price_info, 'fa-euro-sign', 'Price info') }}
{{ render_link_prop(event.external_link) }}
{{ render_link_prop(event.ticket_link) }}
{% if event.category %}
<div><i class="fa fa-fw fa-archive" data-toggle="tooltip" title="{{ _('Category') }}"></i> {% for category in event.categories %}{{ category | event_category_name }}{%if not loop.last %}, {% endif %}{% endfor %}</div>
{% endif %}
{{ render_tag_prop(event.tags) }}
{{ render_bool_prop(event.kid_friendly, 'fa-child', 'Kid friendly') }}
{{ render_bool_prop(event.accessible_for_free, 'fa-door-open', 'Accessible for free') }}
{{ render_range_prop(event.age_from, event.age_to, 'fa-people-arrows', 'Typical Age range') }}
{{ render_enum_prop(event.target_group_origin, 'fa-users', 'Target group origin', 1) }}
{{ render_enum_prop(event.attendance_mode, 'fa-mouse-pointer', 'Attendance mode', 1) }}
{{ render_bool_prop(event.registration_required, 'fa-list', 'Registration required') }}
{{ render_bool_prop(event.booked_up, 'fa-square-full', 'Booked up') }}
{{ render_int_prop(event.expected_participants, 'fa-users', 'Expected number of participants') }}
{% endmacro %}
{% macro render_event_props(event, start, end, allday, dates = None, show_rating = False, show_admin_unit = True, share_links=None, calendar_links=None) %}
<div class="card mb-3">
<div class="card-header">
{{ _('Event') }}
</div>
<div class="card-body">
<h5 class="card-title">{{ event.name }}{{ render_event_warning_pills(event) }}</h5>
<div>
<i class="fa fa-fw fa-calendar" data-toggle="tooltip" title="{{ _('Date') }}"></i>
{{ render_event_date_with_dates_link(start, end, allday) }}
</div>
{{ render_enum_prop(event.status, 'fa-info-circle', 'Status', 1) }}
{% if event.previous_start_date %}
<div><i class="fa fa-fw fa-calendar-times" data-toggle="tooltip" title="{{ _('Previous start date') }}"></i> {{ event.previous_start_date | datetimeformat('short') }}</div>
{% endif %}
{% if show_rating and event.rating and event.rating != 50 %}
{{ render_string_prop("%d/10" % (event.rating/10), 'fa-adjust', 'Rating') }}
{% endif %}
{% if event.photo_id %}
<div class="my-4">{{ render_image(event.photo, 700) }}</div>
{% endif %}
{% if event.description %}
<div class="my-4" style="white-space:pre-wrap;">{{ event.description|urlize(nofollow=True, target='_blank', rel="nofollow") }}</div>
{% endif %}
<div class="mt-4">
{{ render_event_add_props(event) }}
</div>
{% if share_links or calendar_links %}
<div class="mt-4">
{% if share_links %}
<button type="button" class="btn btn-outline-secondary mr-1 mb-1" data-toggle="modal" data-target="#shareModal"><i class="fa fa-share-alt"></i> {{ _('Share') }}</button>
{{ render_share_modal(share_links) }}
{% endif %}
{% if calendar_links %}
<button type="button" class="btn btn-outline-secondary mb-1" data-toggle="modal" data-target="#calendarExportModal"><i class="fa fa-calendar"></i> {{ _('Add to calendar') }}</button>
{{ render_calendar_export_modal(calendar_links) }}
{% endif %}
</div>
{% endif %}
</div>
<div class="card-footer small">
{{ render_audit(event, show_rating) }}
<a href="{{ url_for('event_report', event_id=event.id) }}" class="text-dark" target="_blank" rel="noopener noreferrer">{{ _('Report event') }}</a>
</div>
</div>
<div class="card mb-3">
<div class="card-header">
{{ _('Place') }}
</div>
<div class="card-body">
{% if event.event_place %}
<h5 class="card-title">{{ event.event_place.name }}</h5>
{% if event.event_place.photo_id %}
<div class="my-4">{{ render_image(event.event_place.photo, 300) }}</div>
{% endif %}
{% if event.event_place.description %}
<div class="my-4">{{ event.event_place.description }}</div>
{% endif %}
<div class="my-4">
{{ render_link_prop(event.event_place.url) }}
{{ render_location_prop(event.event_place.location) }}
</div>
{% if event.attendance_mode and event.attendance_mode.value != 1 %}
<p>
<a href="http://www.google.com/maps?q={{ render_place(event.event_place) | quote_plus }}" class="btn btn-secondary" target="_blank" rel="noopener noreferrer">{{ _('Show directions') }}</a>
</p>
{% endif %}
{% if event.attendance_mode and event.attendance_mode.value == 2 %}
<p>{{ _('The event takes place online.') }}</p>
{% elif event.attendance_mode and event.attendance_mode.value == 3 %}
<p>{{ _('The event takes place both offline and online.') }}</p>
{% endif %}
{% endif %}
</div>
</div>
{% if event.organizer %}
<div class="card mb-3">
<div class="card-header">
{{ _('Organizer') }}
</div>
<div class="card-body">
{{ render_event_props_organizer(event.organizer) }}
{% for co_organizer in event.co_organizers %}
<div{% if loop.index > 0 %} class="mt-4"{% endif %}>
{{ render_event_props_organizer(co_organizer) }}
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if show_admin_unit %}
<div class="card mb-3">
<div class="card-header">
{{ _('Organization') }}
</div>
<div class="card-body">
<h5 class="card-title">{{ event.admin_unit.name }}{{ render_admin_unit_badges(event.admin_unit) }}</h5>
{% if event.admin_unit.logo_id %}
<div class="my-4">{{ render_logo(event.admin_unit.logo) }}</div>
{% endif %}
<div class="my-4">
{{ render_link_prop(event.admin_unit.url) }}
{{ render_email_prop(event.admin_unit.email) }}
{{ render_phone_prop(event.admin_unit.phone) }}
{{ render_fax_prop(event.admin_unit.fax) }}
{{ render_location_prop(event.admin_unit.location) }}
</div>
</div>
</div>
{% endif %}
{% endmacro %}
{% macro render_event_props_organizer(organizer) %}
<h5 class="card-title">{{ render_string_prop(organizer.name) }}</h5>
{% if organizer.logo_id %}
<div class="my-4">{{ render_logo(organizer.logo) }}</div>
{% endif %}
{{ render_link_prop(organizer.url) }}
{{ render_email_prop(organizer.email) }}
{{ render_phone_prop(organizer.phone) }}
{{ render_fax_prop(organizer.fax) }}
{% endmacro %}
{% macro render_event_props_seo(event, start, end, allday, dates = None, show_rating = False, show_admin_unit = True, user_rights=None, share_links=None, calendar_links=None, current_user=None, can_add_to_list=False) %}
<div class="w-normal mx-auto">
{% if event.photo_id %}
<div class="d-flex">{{ render_image(event.photo, 700, class="mx-auto") }}</div>
{% endif %}
<div class="p-3 clearfix">
{% if user_rights %}
<div class="float-sm-right">
{{ render_event_menu(user_rights, event, can_add_to_list) }}
</div>
{% endif %}
<div class="font-weight-bold text-uppercase">
{{ render_event_date_with_dates_link(start, end, allday) }}
</div>
<h1 class="font-weight-bold my-1">{{ event.name }}{{ render_event_warning_pills(event) }}</h1>
<div class="text-muted">{{ event.event_place.name }}{% if event.event_place.location and event.event_place.location.city %}, {{ event.event_place.location.city }}{% endif %}</div>
</div>
</div>
<div class="d-flex bg-light p-3"><div class="mx-auto" style="width:40rem;">
<div class="card mb-3">
<div class="card-body">
<h2 class="mt-0">{{ _('Event') }}</h2>
{{ render_enum_prop(event.status, 'fa-info-circle', 'Status', 1) }}
{% if event.previous_start_date %}
<div><i class="fa fa-fw fa-calendar-times" data-toggle="tooltip" title="{{ _('Previous start date') }}"></i> {{ event.previous_start_date | datetimeformat('short') }}</div>
{% endif %}
{% if show_rating and event.rating and event.rating != 50 %}
{{ render_string_prop("%d/10" % (event.rating/10), 'fa-adjust', 'Rating') }}
{% endif %}
<div>
{{ render_event_add_props(event) }}
</div>
{% if event.description %}
<div class="mt-4" style="white-space:pre-wrap;">{{ event.description|urlize(nofollow=True, target='_blank', rel="nofollow") }}</div>
{% endif %}
{% if share_links or calendar_links or (current_user and current_user.is_authenticated) %}
<div class="mt-4">
{% if share_links %}
<button type="button" class="btn btn-outline-secondary mr-1 mb-1" data-toggle="modal" data-target="#shareModal"><i class="fa fa-share-alt"></i> {{ _('Share') }}</button>
{{ render_share_modal(share_links) }}
{% endif %}
{% if calendar_links %}
<button type="button" class="btn btn-outline-secondary mb-1" data-toggle="modal" data-target="#calendarExportModal"><i class="fa fa-calendar"></i> {{ _('Add to calendar') }}</button>
{{ render_calendar_export_modal(calendar_links) }}
{% endif %}
{% if current_user and current_user.is_authenticated %}
<button type="button" class="btn btn-outline-secondary mb-1 toggle-user-event-favorite" data-event-id="{{ event.id }}"><i class="{%if event.is_favored_by_current_user() %}fa{% else %}far{% endif %} fa-bookmark"></i> {{ _('Favorite events') }}</button>
{% endif %}
{% if user_rights['can_update_event'] %}
<a href="{{ url_for('event_update', event_id=event.id) }}" class="btn btn-outline-secondary mb-1"><i class="fa fa-edit"></i> {{ _('Edit') }}</a>
{% endif %}
</div>
{% endif %}
<div class="small mt-2">
{{ render_audit(event, show_rating) }}
<a href="{{ url_for('event_report', event_id=event.id) }}" class="text-dark">{{ _('Report event') }}</a>
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-body">
<h2 class="mt-0">{{ _('Place') }}</h2>
<div class="row">
{% if event.event_place.photo_id %}
<div class="col-12 col-sm-auto order-sm-last">{{ render_image(event.event_place.photo, 240, class="img-thumbnail") }}</div>
{% endif %}
<div class="col-12 col-sm">
<div class="font-weight-bold">{{ event.event_place.name }}</div>
{% if event.event_place.description %}
<div class="my-4">{{ event.event_place.description }}</div>
{% endif %}
{{ render_link_prop(event.event_place.url) }}
{{ render_location_prop(event.event_place.location) }}
{% if event.attendance_mode and event.attendance_mode.value == 2 %}
<div class="mt-2">{{ _('The event takes place online.') }}</div>
{% elif event.attendance_mode and event.attendance_mode.value == 3 %}
<div class="mt-2">{{ _('The event takes place both offline and online.') }}</div>
{% endif %}
{% if (event.attendance_mode and event.attendance_mode.value != 2) or user_rights['can_update_event'] %}
<div class="mt-2">
{% if event.attendance_mode and event.attendance_mode.value != 2 %}
<a href="http://www.google.com/maps?q={{ render_place(event.event_place) | quote_plus }}" class="btn btn-outline-secondary mr-1" target="_blank" rel="noopener noreferrer"><i class="fa fa-directions"></i> {{ _('Show directions') }}</a>
{% endif %}
{% if user_rights['can_update_event'] %}
<a href="{{ url_for('event_place_update', id=event.event_place.id) }}" class="btn btn-outline-secondary"><i class="fa fa-edit"></i> {{ _('Edit') }}</a>
{% endif %}
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% if event.organizer %}
<div class="card mb-3">
<div class="card-body">
<h2 class="mt-0">{{ _('Organizer') }}</h2>
{{ render_event_props_seo_organizer(event.organizer, user_rights) }}
{% for co_organizer in event.co_organizers %}
<div{% if loop.index > 0 %} class="mt-4"{% endif %}>
{{ render_event_props_seo_organizer(co_organizer, user_rights) }}
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if show_admin_unit %}
<div class="card mb-3">
<div class="card-body">
<h2 class="mt-0">{{ _('Organization') }}</h2>
<div class="row">
{% if event.admin_unit.logo_id %}
<div class="col-12 col-sm-auto order-sm-last">{{ render_logo(event.admin_unit.logo) }}</div>
{% endif %}
<div class="col-12 col-sm">
<div class="font-weight-bold">
<a href="{{ url_for('organizations', path=event.admin_unit.id) }}">{{ event.admin_unit.name }}</a>
{{ render_admin_unit_badges(event.admin_unit) }}
</div>
{{ render_link_prop(event.admin_unit.url) }}
{{ render_email_prop(event.admin_unit.email) }}
{{ render_phone_prop(event.admin_unit.phone) }}
{{ render_fax_prop(event.admin_unit.fax) }}
{{ render_location_prop(event.admin_unit.location) }}
</div>
</div>
</div>
</div>
{% endif %}
{% if user_rights['can_reference_event'] or (event.references and event.references|length > 0) %}
<div class="card mb-3">
<div class="card-body pb-0">
<h2 class="mt-0"><a name="event-dates">{{ _('Referenced by') }}</a>
</div>
<div class="list-group list-group-flush mb-4" style="max-height: 30vh; overflow: scroll; overflow-y: auto;">
{% for event_reference in event.references %}
<span class="list-group-item">
<a href="{{ url_for('organizations', path=event_reference.admin_unit.id) }}">{{ event_reference.admin_unit.name }}</a>
{{ render_admin_unit_badges(event_reference.admin_unit) }}
</span>
{% endfor %}
</div>
{% if user_rights['can_reference_event'] %}
<div class="ml-3 mb-3">
<a href="{{ url_for('event_reference_create', event_id=event.id) }}" class="btn btn-outline-secondary"><i class="fa fa-link"></i> {{ _('Reference event') }}</a>
</div>
{% endif %}
</div>
{% endif %}
{% if user_rights['can_create_reference_request'] %}
<div class="card mb-3">
<div class="card-body pb-0">
<h2 class="mt-0"><a name="event-dates">{{ _('Reference requests') }}</a>
</div>
<div class="list-group list-group-flush mb-4" style="max-height: 30vh; overflow: scroll; overflow-y: auto;">
{% for reference_request in event.reference_requests %}
<span class="list-group-item">
<a href="{{ url_for('event_reference_request_review_status', id=reference_request.id) }}">{{ reference_request.admin_unit.name }}</a>
{{ render_reference_request_review_status_pill(reference_request) }}
</span>
{% endfor %}
</div>
<div class="ml-3 mb-3">
<a href="{{ url_for('event_reference_request_create', event_id=event.id) }}" class="btn btn-outline-secondary"><i class="fa fa-link"></i> {{ _('Request reference') }}</a>
</div>
</div>
{% endif %}
{% if dates and dates|length > 0 %}
<div class="card mb-3">
<div class="card-body pb-0">
<h2 class="mt-0"><a name="event-dates">{{ _('Event Dates') }}</a>
</div>
<div class="list-group list-group-flush mb-4" style="max-height: 30vh; overflow: scroll; overflow-y: auto;">
{% for date in dates %}
<a href="{{ url_for('event_date', id=date.id) }}" class="list-group-item">{{ render_event_date(date.start, date.end, date.allday) }}</a>
{% endfor %}
</div>
</div>
{% endif %}
</div>
</div>
{% endmacro %}
{% macro render_event_props_seo_organizer(organizer, user_rights) %}
<div class="row">
{% if organizer.logo_id %}
<div class="col-12 col-sm-auto order-sm-last">{{ render_logo(organizer.logo) }}</div>
{% endif %}
<div class="col-12 col-sm">
<div class="font-weight-bold">
<a href="{{ url_for('organizers', path=organizer.id) }}">{{ organizer.name }}</a>
</div>
{{ render_link_prop(organizer.url) }}
{{ render_email_prop(organizer.email) }}
{{ render_phone_prop(organizer.phone) }}
{{ render_fax_prop(organizer.fax) }}
</div>
</div>
{% if user_rights['can_update_event'] %}
<div class="mt-2">
<a href="{{ url_for('organizer_update', id=organizer.id) }}" class="btn btn-outline-secondary"><i class="fa fa-edit"></i> {{ _('Edit') }}</a>
</div>
{% endif %}
{% endmacro %}
{% macro render_google_place_autocomplete_header() %}
<script>
$( function() {
$('#location_search').select2({
theme: 'bootstrap4',
ajax: {
url: "{{ url_for('js_autocomplete_place') }}",
dataType: 'json',
delay: 250,
cache: true,
data: function (params) {
return {
keyword: params.term
};
}
},
placeholder: $('#location_search').attr("placeholder"),
minimumInputLength: 1,
templateResult: select2TemplateResult
}).on('select2:close', function (e) {
var data = select2GetData(e);
if ("gmaps_id" in data) {
$(this).val(null).trigger('change');
var location_only = $(this).attr("data-location-only");
if (location_only) {
reset_location_form();
} else {
reset_place_form();
$('#place-name').val(data.main_text);
}
get_gmaps_place_details(data.gmaps_id, location_only);
}
});
function get_gmaps_place_details(place_id, location_only) {
$.ajax({
url: "{{ url_for('js_autocomplete_gmaps_place') }}",
type: "get",
dataType: "json",
data: "gmaps_id=" + place_id,
success: function (data) {
fill_place_form_with_gmaps_place(data, "", location_only);
}
});
}
});
</script>
{% endmacro %}
{% macro render_google_place_autocomplete_field(location_only = False) %}
<div class="form-group row">
<div class="col-sm-12">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><span><i class="fab fa-google"></i></span></span>
</div>
<select id="location_search" class="form-control" placeholder="{{ _('Search location on Google') }}" {% if location_only %}data-location-only="1"{% endif %}></select>
</div>
</div>
</div>
{% endmacro %}
{% macro render_google_filter_autocomplete_header() %}
<script>
$( function() {
$('#location').select2({
theme: 'bootstrap4',
ajax: {
url: "{{ url_for('js_autocomplete_place') }}",
dataType: 'json',
delay: 250,
cache: true,
data: function (params) {
return {
keyword: params.term
};
}
},
placeholder: $('#location').attr("placeholder"),
minimumInputLength: 1,
templateResult: select2TemplateResult
}).on('select2:close', function (e) {
var data = select2GetData(e);
if ("gmaps_id" in data) {
get_gmaps_place_details(data.gmaps_id, data.text);
}
});
function get_gmaps_place_details(place_id, place_name) {
$.ajax({
url: "{{ url_for('js_autocomplete_gmaps_place') }}",
type: "get",
dataType: "json",
data: "gmaps_id=" + place_id,
success: function (data) {
$('#coordinate').val('' + data.geometry.location.lat + ',' + data.geometry.location.lng);
$('#location_name').val(place_name);
}
});
}
});
</script>
{% endmacro %}
{% macro render_event_date_instance(instance, allday, dateModifier = 'short', timeModifier = 'short') %}
{{ instance | dateformat(dateModifier) }}{% if not allday %} {{ instance | timeformat(timeModifier) }}{% endif %}
{% endmacro %}
{% macro render_event_date(start, end, allday) %}
{% set start_date_str = start|dateformat('full') %}
{{ start_date_str }}{% if not allday %} {{ start | timeformat('short') }}{% endif %}
{% if end %}
{% set end_date_str = end|dateformat('full') %}
{% if end_date_str != start_date_str or not allday %} - {% endif %}
{% if end_date_str != start_date_str %}{{ end_date_str }}{% endif %}{% if not allday %} {{ end | timeformat('short') }}{% endif %}
{% endif %}
{% endmacro %}
{% macro render_event_date_with_dates_link(start, end, allday) %}
{{ render_event_date(start, end, allday) }}
{% if dates and dates|length > 1 %}
| <a href="#event-dates">{{ _('%(count)d event dates', count=dates|length) }}</a>
{% endif %}
{% endmacro %}
{% macro render_event_date_in_list(event_date) %}
{{ render_event_date_instance(event_date.start, event_date.allday) }}
{% if event_date.recurrence_rule %}
<i class="fas fa-history"></i>
{% endif %}
{% endmacro %}
{% macro render_event_in_list(event) %}
{{ render_event_date_instance(event.min_start_definition.start, event.min_start_definition.allday) }}
{% if event.is_recurring %}
<i class="fas fa-history"></i>
{% endif %}
{% endmacro %}
{% macro render_pagination(pagination) %}
{% if pagination['prev_url'] or pagination['next_url'] %}
<nav aria-label="Page navigation">
<ul class="pagination">
{% if pagination['first_url'] %}
<li class="page-item"> <a class="page-link" href="{{ pagination['first_url'] }}" title="{{ _('First') }}"><i class="fa fa-angle-double-left"></i></a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#" title="{{ _('First') }}"><i class="fa fa-angle-double-left"></i></a></li>
{% endif %}
{% if pagination['prev_url'] %}
<li class="page-item"> <a class="page-link" href="{{ pagination['prev_url'] }}" title="{{ _('Previous') }}"><i class="fa fa-angle-left"></i></a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#" title="{{ _('Previous') }}"><i class="fa fa-angle-left"></i></a></li>
{% endif %}
<li class="page-item disabled d-none d-sm-inline"><span class="page-link">{{ _('Page %(page)d of %(pages)d (%(total)d total)', page=pagination["page"], pages=pagination["pages"], total=pagination["total"]) }}</span></li>
{% if pagination['next_url'] %}
<li class="page-item"> <a class="page-link" href="{{ pagination['next_url'] }}" title="{{ _('Next') }}"><i class="fa fa-angle-right"></i></a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#" title="{{ _('Next') }}"><i class="fa fa-angle-right"></i></a></li>
{% endif %}
{% if pagination['last_url'] %}
<li class="page-item"> <a class="page-link" href="{{ pagination['last_url'] }}" title="{{ _('Last') }}"><i class="fa fa-angle-double-right"></i></a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#" title="{{ _('Last') }}"><i class="fa fa-angle-double-right"></i></a></li>
{% endif %}
</ul>
</nav>
{% endif %}
{% endmacro %}
{% macro render_roles(roles) %}
{% if roles %}
{% for role in roles %}{{ _(role.title) }}{%if not loop.last %}, {% endif %}{% endfor %}
{% endif %}
{% endmacro %}
{% macro render_email_button(url, title) %}
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
<tbody>
<tr>
<td align="left">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td> <a href="{{ url }}" target="_blank" rel="noopener noreferrer">{{ title }}</a> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
{% endmacro %}
{% macro render_radio_buttons(field) %}
{% for subfield in field %}
<div class="form-check form-check-inline">
<td>{{ subfield(class="form-check-input") }}</td>
<td>{{ subfield.label(class="form-check-label") }}</td>
</div>
{% endfor %}
{% endmacro %}
{% macro render_event_dates_date_field(from_field, to_field) %}
<div class="form-group row">
<label class="col-sm-2 col-form-label">{{ _('Date') }}</label>
<div class="col-sm-5 mb-1">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">{{ from_field.label.text }}</span>
</div>
{{ from_field(**{"class":"form-control datepicker", "data-range-to":"#date_to"})|safe }}
</div>
</div>
<div class="col-sm-5">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">{{ to_field.label.text }}</span>
</div>
{{ to_field(class="form-control datepicker")|safe }}
</div>
</div>
</div>
{% endmacro %}
{% macro render_event_dates_location_field(location_field, distance_field) %}
{% if location_field %}
<div class="form-group row">
<label for="location" class="col-sm-2 col-form-label">{{ _('Radius') }}</label>
<div class="col-sm-7 mb-1">
<div class="input-group">
{{ location_field(class="form-control", placeholder='Ort', autocomplete="off")|safe }}
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="button" id="clear_location_btn">
<i class="fa fa-times"></i>
</button>
<button class="btn btn-outline-primary" type="button" id="geolocation_btn">
<i class="fa fa-location-arrow"></i>
</button>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">{{ distance_field.label.text }}</span>
</div>
{{ distance_field(class="form-control")|safe }}
</div>
</div>
</div>
{% endif %}
{% endmacro %}
{% macro render_cropper_code(field_id = "photo", min_width=320, min_height=160) %}
var field_id = "#{{ field_id }}-image_base64";
var inputImage = document.getElementById('photo-image_file');
var Cropper = window.Cropper;
var URL = window.URL || window.webkitURL;
var image = document.getElementById('photo-image');
var cropper = null;
var crop_data = null;
var minCroppedWidth = {{ min_width }};
var minCroppedHeight = {{ min_height }};
var uploadedImageURL;
var photo_modal = $('#photo_modal');
if (URL) {
inputImage.onchange = function () {
$('.dropzone-wrapper').removeClass('dragover');
var files = this.files;
var file;
if (files && files.length) {
file = files[0];
if (/^image\/\w+/.test(file.type)) {
if (uploadedImageURL) {
URL.revokeObjectURL(uploadedImageURL);
}
image.src = uploadedImageURL = URL.createObjectURL(file);
inputImage.value = null;
crop_data = null;
photo_modal.modal();
} else {
window.alert('Please choose an image file.');
}
}
};
photo_modal.on('shown.bs.modal', function () {
cropper = new Cropper(image, {
viewMode: 1,
autoCropArea: 1.0,
data: crop_data,
ready() {
var image_data = cropper.getImageData();
if (image_data.naturalWidth < minCroppedWidth || image_data.naturalHeight < minCroppedHeight) {
window.alert('Die Auflösung ist zu gering. Mindestens ' + minCroppedWidth + 'x' + minCroppedHeight + 'px.');
photo_modal.modal('hide');
}
},
crop: function (event) {
var width = event.detail.width;
var height = event.detail.height;
if (width < minCroppedWidth || height < minCroppedHeight) {
cropper.setData({
width: Math.max(minCroppedWidth, width),
height: Math.max(minCroppedHeight, height),
});
}
}
});
}).on('hidden.bs.modal', function () {
cropper.destroy();
cropper = null;
});
if ($('#photo_preview').attr("src")) {
image.src = uploadedImageURL = $('#photo_preview').attr("src");
$('.hide-if-photo-exists').hide();
} else {
$('.show-if-photo-exists').hide();
}
$('#photo-edit-btn').click(function(e){
e.preventDefault();
photo_modal.modal();
});
$('#photo-delete-btn').click(function(e){
e.preventDefault();
$(field_id).val('');
$('#photo_preview').attr("src", '');
$('.show-if-photo-exists').hide();
$('.hide-if-photo-exists').show();
});
$('#photo-zoom-in').click(function(e){
e.preventDefault();
cropper.zoom(0.1);
});
$('#photo-zoom-out').click(function(e){
e.preventDefault();
cropper.zoom(-0.1);
});
$('#photo-rotate-left').click(function(e){
e.preventDefault();
cropper.rotate(-90);
});
$('#photo-rotate-right').click(function(e){
e.preventDefault();
cropper.rotate(90);
});
$('#photo-save-btn').click(function(e){
e.preventDefault();
photo_modal.modal('hide');
if (cropper) {
var canvas = cropper.getCroppedCanvas({
maxWidth: 1200,
maxHeight: 1200,
fillColor: 'transparent'
});
var data_url = canvas.toDataURL();
crop_data = cropper.getData();
$(field_id).val(data_url);
$('#photo_preview').attr("src", data_url);
$('.show-if-photo-exists').show();
$('.hide-if-photo-exists').hide();
}
});
} else {
inputImage.disabled = true;
inputImage.parentNode.className += ' disabled';
}
{% endmacro %}
{% macro render_cropper_script(field_id = "photo", min_width=320, min_height=320) %}
<script>
$( function() {
{{ render_cropper_code(field_id, min_width, min_height) }}
});
</script>
{% endmacro %}
{% macro render_cropper_block(field_id = "photo", min_width=320, min_height=320) %}
{{ render_cropper_header() }}
{{ render_cropper_script(field_id, min_width, min_height) }}
{% endmacro %}
{% macro render_cropper_logo_block() %}
{{ render_cropper_block("logo") }}
{% endmacro %}
{% macro render_crop_image_form(form_field) %}
{{ form_field.hidden_tag() }}
<div class="mb-3">
<div id="photo_modal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{ _('Edit image') }}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div style="height: 40vh;">
<img class="w-100" id="photo-image" />
</div>
<div class="my-3">
<div class="btn-group">
<button id="photo-zoom-in" type="button" class="btn btn-outline-secondary"><i class="fa fa-search-plus"></i></button>
<button id="photo-zoom-out" type="button" class="btn btn-outline-secondary"><i class="fa fa-search-minus"></i></button>
</div>
<div class="btn-group">
<button id="photo-rotate-left" type="button" class="btn btn-outline-secondary"><i class="fa fa-undo-alt"></i></button>
<button id="photo-rotate-right" type="button" class="btn btn-outline-secondary"><i class="fa fa-redo-alt"></i></button>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ _('Close') }}</button>
<button type="button" class="btn btn-primary" id="photo-save-btn">{{ _('Okay') }}</button>
</div>
</div>
</div>
</div>
<div class="mb-1 show-if-photo-exists"><img id="photo_preview" style="max-height: 20vh; max-width:100%;" {% if form_field.image_base64.data %}src="{{ form_field.image_base64.data }}"{% endif %} /></div>
<div class="py-1">
<div class="dropzone-wrapper mb-2 hide-if-photo-exists">
<div class="dropzone-desc">
<i class="fa fa-upload"></i>
<p>{{ _('Choose image file') }}&hellip;</p>
</div>
<input type="file" id="photo-image_file" name="photo" accept="image/*" class="dropzone" />
</div>
<button type="button" id="photo-edit-btn" class="btn btn-outline-secondary show-if-photo-exists"><i class="fa fa-edit"></i></button>
<button type="button" id="photo-delete-btn" class="btn btn-outline-secondary show-if-photo-exists"><i class="fa fa-trash"></i></button>
</div>
</div>
{{ render_field_with_errors(form_field.copyright_text) }}
{% endmacro %}
{% macro render_crop_image_form_section(form_field) %}
<div class="card mb-4">
<div class="card-header">
{{ form_field.label() }}
</div>
<div class="card-body">
{% if form_field.description %}
<div class="form-text mt-0 mb-2 text-muted w-100">
{{ form_field.description }}
</div>
{% endif %}
{{ render_crop_image_form(form_field) }}
</div>
</div>
{% endmacro %}
{% macro render_event_menu(user_rights, event, can_add_to_list) %}
{% if user_rights|any_dict_value_true %}
<div class="dropdown my-1">
<button class="btn btn-outline-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-cog"></i>
</button>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton">
{% if user_rights['can_update_event'] %}
<a class="dropdown-item" href="{{ url_for('event_update', event_id=event.id) }}"><i class="fa fa-edit"></i> {{ _('Edit event') }}</a>
<a class="dropdown-item" href="{{ url_for('event_delete', event_id=event.id) }}"><i class="fa fa-trash"></i> {{ _('Delete event') }}&hellip;</a>
{% endif %}
{% if user_rights['can_duplicate_event'] %}
<a class="dropdown-item" href="{{ url_for('event_create_for_admin_unit_id', id=event.admin_unit_id, template_id=event.id) }}"><i class="fa fa-copy"></i> {{ _('Duplicate event') }}</a>
{% endif %}
<div class="dropdown-divider"></div>
{% if user_rights['can_create_reference_request'] %}
<a class="dropdown-item" href="{{ url_for('event_reference_request_create', event_id=event.id) }}"><i class="fa fa-link"></i> {{ _('Request reference') }}</a>
{% endif %}
{% if user_rights['can_reference_event'] %}
<a class="dropdown-item" href="{{ url_for('event_reference_create', event_id=event.id) }}"><i class="fa fa-link"></i> {{ _('Reference event') }}</a>
{% endif %}
{% if can_add_to_list %}
<div class="dropdown-divider"></div>
<a class="dropdown-item" onclick="app.$bvModal.show('add-event-to-list-modal'); return false;" href="#"><i class="fa fa-plus-circle"></i> {{ _('Add to list') }}</a>
{% endif %}
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{{ url_for('event_actions', event_id=event.id) }}">{{ _('More') }}&hellip;</a>
</div>
</div>
{% endif %}
{% endmacro %}
{% macro render_jquery_steps_header() %}
<script src="{{ url_for('static', filename='ext/jquery.steps.1.1.0.min.js')}}"></script>
<script src="{{ url_for('static', filename='ext/jquery.validate.1.19.2.min.js')}}"></script>
<script src="{{ url_for('static', filename='ext/jquery-validate.1.19.2.additional-methods.min.js')}}"></script>
<script src="{{ url_for('static', filename='ext/jquery-validate.1.19.2.messages_de.min.js')}}"></script>
<script>
jQuery.validator.addMethod("dateRange", function(value, element, params) {
var start_id = params[0];
var end_id = params[1];
var start_val = $(start_id).val();
var end_val = $(end_id).val();
if (start_val == '' || end_val == '') {
return true;
}
var start = get_moment_with_time(start_id);
var end = get_moment_with_time(end_id);
return end >= start;
}, jQuery.validator.format("{{ _('The start must be before the end.') }}"));
jQuery.validator.addMethod("dateRangeDay", function(value, element, params) {
var start_id = params[0];
var end_id = params[1];
var start_val = $(start_id).val();
var end_val = $(end_id).val();
if (start_val == '' || end_val == '') {
return true;
}
var start = get_moment_with_time(start_id);
var end = get_moment_with_time(end_id);
var max = start.add(14, 'day');
return end <= max;
}, jQuery.validator.format("{{ _('An event can last a maximum of 14 days.') }}"));
$.validator.addMethod( "time", function( value, element ) {
return this.optional( element ) || /^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test( value );
}, jQuery.validator.format("{{ _('Please enter a valid time, between 00:00 and 23:59.') }}"));
jQuery.validator.setDefaults({
errorElement: 'div',
errorClass: 'invalid-feedback',
errorPlacement: function (error, element) {
element.closest('.input-group').after(error);
},
highlight: function (element, errorClass, validClass) {
$(element).closest('.input-group').find(':input').removeClass('is-valid').addClass('is-invalid');
},
unhighlight: function (element, errorClass, validClass) {
$(element).closest('.input-group').find(':input').removeClass('is-invalid').addClass('is-valid');
},
onclick: function (element, event) {
return true;
}
});
function createSelect2Tag(params) {
var term = $.trim(params.term);
if (term === '') {
return null;
}
return {
id: term,
tag_text: "{{ _('Just use %(term)s', term='%(term)s') }}".replace("%(term)s", '"' + term + '"'),
term: term,
text: term,
is_new_tag: true
}
}
function insertSelect2Tag(data, tag) {
data.push(tag);
}
function select2TemplateResult(state) {
if ("is_new_tag" in state) {
return $("<strong>" + state.tag_text + "</strong>");
}
return state.text;
}
function select2GetData(e) {
var dataArray = $(e.target).select2('data');
var data = {};
if (dataArray.length > 0) {
data = dataArray[0];
}
return data;
}
</script>
{% endmacro %}
{% macro render_end_container_handling() %}
$('#end-container').on('shown', function() {
var end_moment = get_moment_with_time('#start');
if ($('#allday').is(':checked')) {
end_moment = end_moment.endOf('day');
} else {
end_moment = end_moment.add(3, 'hours');
}
set_picker_date($('#end-user'), end_moment.toDate());
});
$('#end-container').on('hidden', function() {
set_picker_date($('#end-user'), null);
$('#allday').prop('checked', false).trigger("change");
});
$('#allday').on('change', function() {
if (this.checked && !$("#end-container").is(":visible")) {
showLink(null, $("#end-show-container a.show-link"));
}
});
{% endmacro %}
{% macro render_cropper_header() %}
<script src="{{ url_for('static', filename='ext/cropper.1.5.9.min.js')}}"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='ext/cropper.1.5.9.min.css')}}" />
<script src="{{ url_for('static', filename='ext/jquery-cropper.1.0.1.min.js')}}"></script>
{% endmacro %}
{% macro render_event_suggestion(event_suggestion, hide_review_status=False) %}
<div class="card mb-3">
<div class="card-header">
{{ _('Event suggestion') }}
</div>
<div class="card-body">
{% if event_suggestion.photo_id %}
<div class="">
{{ render_image(event_suggestion.photo, class='rounded', style='object-fit: cover; height: 20vh;') }}
</div>
{% elif event_suggestion.photo and event_suggestion.photo.image_base64 %}
<div class="mb-1"><img class="rounded" style="object-fit: cover; height: 20vh;" src="{{ event_suggestion.photo.image_base64 }}" /></div>
{% endif %}
<div class="text-highlight text-uppercase font-weight-bold">{{ render_event_date(event_suggestion.start, event_suggestion.end, event_suggestion.allday) }}</div>
<div class="font-weight-bold" style="font-size: 1.8rem;">{{ event_suggestion.name }}</div>
<div class="text-muted">{{ event_suggestion.event_place.name or event_suggestion.event_place_text }}</div>
<div class="mt-3"><i class="fa fa-fw fa-sitemap"></i> {{ event_suggestion.organizer.name or event_suggestion.organizer_text }}</div>
{{ render_link_prop(event_suggestion.external_link) }}
<div class="my-2">{{ event_suggestion.description }}</div>
<div class="mt-4">
{{ render_event_add_props(event_suggestion) }}
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-header">
{{ _('Contact') }}
</div>
<div class="card-body">
{{ render_string_prop(event_suggestion.contact_name, 'fa-user') }}
{{ render_email_prop(event_suggestion.contact_email) }}
{{ render_phone_prop(event_suggestion.contact_phone) }}
</div>
</div>
{% if not hide_review_status %}
<div class="card mb-3">
<div class="card-header">
{{ _('Review status') }}
</div>
<div class="card-body">
{{ render_event_review_status(event_suggestion) }}
</div>
</div>
{% endif %}
{% endmacro %}
{% macro render_widget_styles(styles) %}
<style>
body {
{% if 'background' in styles %}
background-color: {{ styles['background'] }};
{% endif %}
{% if 'font' in styles %}
font-family: {{ styles['font'] }};
{% endif %}
}
{% if 'background' in styles %}
.page-link, .page-item.disabled .page-link {
background-color: {{ styles['background'] }};
}
{% endif %}
{% if 'primary' in styles %}
.btn-primary,
.btn-primary:hover,
.btn-primary:active,
.btn-primary:not(:disabled):not(.disabled):active,
.btn-primary:focus {
background-color: {{ styles['primary'] }};
border-color: {{ styles['primary'] }};
}
{% endif %}
{% if 'link' in styles %}
.card-title, .page-link, .page-link:hover, a, a:hover {
color: {{ styles['link'] }};
}
{% endif %}
{% if 'primary' in styles %}
.wizard > .steps .current a,
.wizard > .steps .current a:hover,
.wizard > .steps .current a:active,
.wizard > .steps .current a,
.wizard > .steps .current a:hover,
.wizard > .steps .current a:active,
.wizard > .steps .done a,
.wizard > .steps .done a:hover,
.wizard > .steps .done a:active,
.wizard > .actions a,
.wizard > .actions a:hover,
.wizard > .actions a:active
{
background-color: {{ styles['primary'] }};
}
{% endif %}
</style>
{% endmacro %}
{% macro render_share_modal(share_links) %}
<div class="modal fade" id="shareModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{ _('Share') }}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="input-group mb-3">
<input id="copy_input" type="text" class="form-control" value="{{ share_links["url"] }}" />
<div class="input-group-append">
<button id="copy_input_button" class="btn btn-outline-secondary" type="button" data-toggle="tooltip" data-trigger="manual" data-title="{{ _('Link copied') }}">{{ _('Copy link') }}</button>
</div>
</div>
<div class="list-group">
<a class="list-group-item list-group-item-action" href="{{ share_links["facebook"] }}" target="_blank" rel="noopener noreferrer"><i class="fab fa-facebook"></i> Facebook</a>
<a class="list-group-item list-group-item-action" href="{{ share_links["twitter"] }}" target="_blank" rel="noopener noreferrer"><i class="fab fa-twitter"></i> Twitter</a>
<a class="list-group-item list-group-item-action" href="{{ share_links["email"] }}" target="_blank" rel="noopener noreferrer"><i class="fa fa-envelope"></i> {{ _('Email') }}</a>
<a class="list-group-item list-group-item-action" href="{{ share_links["whatsapp"] }}" target="_blank" rel="noopener noreferrer" data-action="share/whatsapp/share"><i class="fab fa-whatsapp"></i> Whatsapp</a>
<a class="list-group-item list-group-item-action" href="{{ share_links["telegram"] }}" target="_blank" rel="noopener noreferrer"><i class="fab fa-telegram"></i> Telegram</a>
</div>
</div>
</div>
</div>
</div>
{% endmacro %}
{% macro render_calendar_export_modal(calendar_links) %}
<div class="modal fade" id="calendarExportModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{ _('Add to calendar') }}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="list-group">
<a class="list-group-item list-group-item-action" href="{{ calendar_links["ics"] }}"><i class="fab fa-microsoft"></i> Outlook</a>
{% if "google" in calendar_links %}
<a class="list-group-item list-group-item-action" href="{{ calendar_links["google"] }}" target="_blank" rel="noopener noreferrer"><i class="fab fa-google"></i> {{ _('Google calendar') }}</a>
{% endif %}
<a class="list-group-item list-group-item-action" href="{{ calendar_links["ics"] }}"><i class="fab fa-apple"></i> {{ _('Apple calendar') }}</a>
<a class="list-group-item list-group-item-action" href="{{ calendar_links["ics"] }}"><i class="fab fa-yahoo"></i> {{ _('Yahoo calendar') }}</a>
<a class="list-group-item list-group-item-action" href="{{ calendar_links["ics"] }}"><i class="fa fa-calendar"></i> {{ _('Other calendar') }}</a>
</div>
</div>
</div>
</div>
</div>
{% endmacro %}
{% macro render_admin_unit_form_script(admin_unit=None) %}
<script>
$( function() {
jQuery.validator.addMethod("shortName", function(value, element) {
return this.optional(element) || /^\w+$/i.test(value);
}, jQuery.validator.format("{{ _('Short name must contain only letters numbers or underscore') }}"));
var form = $("#main-form");
var validator = form.validate({
rules: {
}
});
$("#name").rules("add", {
remote: {
param: {
url: "{{ url_for('js_check_org_name') }}",
type: "post"
{% if admin_unit %}
,data: {
admin_unit_id: function() {
return "{{ admin_unit.id }}";
}
}
{% endif %}
}
{% if admin_unit and admin_unit.name %}
,depends: function(element) {
return $('#name').val() !== '{{ admin_unit.name }}';
}
{% endif %}
}
});
$("#short_name").rules("add", "shortName");
$("#short_name").rules("add", {
remote: {
param: {
url: "{{ url_for('js_check_org_short_name') }}",
type: "post"
{% if admin_unit %}
,data: {
admin_unit_id: function() {
return "{{ admin_unit.id }}";
}
}
{% endif %}
}
{% if admin_unit.short_name %}
,depends: function(element) {
return $('#short_name').val() !== '{{ admin_unit.short_name }}';
}
{% endif %}
}
});
function suggest_short_name() {
if ($("#short_name").val().length == 0) {
var name = $("#name").val().toLowerCase().replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue').replace(/ß/g, 'ss');
var re = /\w/g;
var suggestion = (name.match(re) || []).join('');
$("#short_name").val(suggestion);
$("#short_name").valid();
}
}
$("#name").blur(function() {
suggest_short_name();
});
if ($("#name").val().length > 0) {
$("#name").valid();
suggest_short_name();
}
$('#location_search').on('place_changed', function() {
$('#location_search').closest('.card-body').find(':input').valid();
$('#location_search').removeClass('is-valid');
});
});
</script>
{% endmacro %}
{% macro render_form_scripts() %}
<script src="{{ url_for('static', filename='ext/jquery-ui.1.12.1/jquery-ui.min.js')}}"></script>
<script src="{{ url_for('static', filename='ext/jquery-ui-i18n.1.11.4.min.js')}}"></script>
<script src="{{ url_for('static', filename='ext/select2.4.0.13.min.js')}}"></script>
<script src="{{ url_for('static', filename='ext/select2.i18n.de.4.0.13.min.js')}}"></script>
<script src="{{ url_for('static', filename='ext/jquery.timepicker.1.13.18.min.js')}}"></script>
<script type="text/javascript">
$.datepicker.setDefaults($.datepicker.regional["de"]);
$.fn.select2.defaults.set("language", "de");
$(function () {
$(".autocomplete").select2({
width: "100%",
theme: "bootstrap4",
});
$(".autocomplete-multi").select2({
width: "100%",
});
});
</script>
{% endmacro %}
{% macro render_manage_form_scripts() %}
{{ render_form_scripts() }}
<script src="{{ url_for('static', filename='ext/jsrender.1.0.6.min.js')}}"></script>
<script src="{{ url_for('static', filename='jquery.recurrenceinput.js')}}"></script>
{% endmacro %}
{% macro render_form_styles() %}
<link rel="stylesheet" href="{{ url_for('static', filename='ext/jquery-ui.1.12.1/jquery-ui.min.css')}}">
<link rel="stylesheet" href="{{ url_for('static', filename='ext/select2.4.0.13.min.css')}}" />
<link rel="stylesheet" href="{{ url_for('static', filename='ext/select2-bootstrap4.1.5.2.min.css')}}" />
<link rel="stylesheet" href="{{ url_for('static', filename='ext/jquery.timepicker.1.13.18.min.css')}}" />
{% endmacro %}
{% macro render_manage_form_styles() %}
{{ render_form_styles() }}
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='jquery.recurrenceinput.css')}}" />
{% endmacro %}
{% macro render_event_date_defintion_code() %}
$('.date-definition-container').eventcallyDateDefinition();
var min_date_definition_index = $(".date-definition-container").length;
if (min_date_definition_index > 1) {
$('.date-definition-container button.remove-date-defintion-btn').removeClass("d-none");
}
$("#add-date-defintion-btn").click(function () {
var template = $(".date-definition-template");
var template_prefix = template.attr('data-prefix');
var last_container = $(".date-definition-container:last");
var last_prefix = last_container.attr('data-prefix');
var new_index = Math.max(min_date_definition_index, $(".date-definition-container").length);
min_date_definition_index++;
var new_prefix = last_prefix.replace(/-(\d+)-$/g, function(match, number) {
return '-' + new_index + '-';
});
var new_container = template.clone();
new_container.removeClass('date-definition-template');
new_container.removeClass('d-none');
new_container.addClass('date-definition-container');
new_container.attr('data-prefix', new_prefix);
new_container.find("*").each(function() {
var subelement = $(this);
$.each(this.attributes, function(i, attrib) {
subelement.attr(attrib.name, attrib.value.replace(template_prefix, new_prefix));
});
});
last_container.after(new_container);
new_container.eventcallyDateDefinition();
if ($(".date-definition-container").length > 1) {
$('.date-definition-container button.remove-date-defintion-btn').removeClass("d-none");
}
return false;
});
{% endmacro %}
{% macro render_date_definition_container(date_definition, container_class="date-definition-container") %}
<div class="{{ container_class }} card mb-3 bg-light" data-prefix="{{ date_definition.id }}-">
<div class="card-body">
<div id="{{ date_definition.id }}-single-event-container">
{{ date_definition.form.hidden_tag() }}
{{ render_field_with_errors(date_definition.form.start, **{"data-range-to":"#"+date_definition.form.end.id, "data-range-max-days": "14", "data-allday": "#"+date_definition.form.allday.id}) }}
{{ render_field_with_errors(date_definition.form.end, is_collapsible=1) }}
{{ render_field_with_errors(date_definition.form.allday, ri="checkbox") }}
<button type="button" id="{{ date_definition.id }}-recc-button" class="btn btn-outline-secondary"><i class="fas fa-history"></i> {{ _('Recurring event') }}</button>
<button type="button" class="btn btn-outline-secondary remove-date-defintion-btn d-none"><i class="fa fa-calendar-minus"></i> {{ _('Remove event date') }}</button>
</div>
<div id="{{ date_definition.id }}-recc-event-container" class="recc-event-container">
{{ render_field_with_errors(date_definition.form.recurrence_rule, label_hidden=True) }}
</div>
</div>
</div>
{% endmacro %}
{% macro render_co_organizer_select2(admin_unit_id) %}
$('#co_organizer_ids').select2({
width: '100%',
ajax: {
url: "{{ url_for('api_v1_organization_organizer_list', id=admin_unit_id) }}",
dataType: 'json',
delay: 250,
cache: true,
data: function (params) {
return {
name: params.term,
per_page: 5,
page: params.page || 1
};
},
processResults: function (data) {
return {
results: data.items.map(p => ({"id": p.id, "text": p.name})),
pagination: {
more: data.has_next
}
};
}
},
placeholder: "{{ _('Enter organizer') }}"
});
{% endmacro %}
{% macro render_event_list_select2(admin_unit_id) %}
$('#event_list_ids').select2({
width: '100%',
ajax: {
url: "{{ url_for('api_v1_organization_event_list_list', id=admin_unit_id) }}",
dataType: 'json',
delay: 250,
cache: true,
data: function (params) {
return {
name: params.term,
per_page: 5,
page: params.page || 1
};
},
processResults: function (data) {
return {
results: data.items.map(p => ({"id": p.id, "text": p.name})),
pagination: {
more: data.has_next
}
};
}
},
placeholder: "{{ _('Enter list name') }}"
});
{% endmacro %}