Compare commits
2 Commits
38a30e1898
...
e6d4619641
Author | SHA1 | Date | |
---|---|---|---|
e6d4619641 | |||
8b65f7dd17 |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "PostgreSQL",
|
"db_name": "PostgreSQL",
|
||||||
"query": "\n SELECT\n event.id AS eventId,\n event.startTimestamp,\n event.endTimestamp,\n event.name,\n event.locationId,\n event.voluntaryWachhabender,\n event.voluntaryFuehrungsassistent,\n event.amountOfPosten,\n event.clothing,\n event.canceled,\n event.note,\n location.id,\n location.name AS locationName,\n location.areaId AS locationAreaId,\n clothing.id AS clothingId,\n clothing.name AS clothingName\n FROM event\n JOIN location ON event.locationId = location.id\n JOIN clothing ON event.clothing = clothing.id\n WHERE starttimestamp::date >= $1\n AND starttimestamp::date <= $2\n AND location.areaId = $3;\n ",
|
"query": "\n SELECT\n event.id AS eventId,\n event.startTimestamp,\n event.endTimestamp,\n event.name,\n event.locationId,\n event.voluntaryWachhabender,\n event.voluntaryFuehrungsassistent,\n event.amountOfPosten,\n event.clothing,\n event.canceled,\n event.note,\n location.id,\n location.name AS locationName,\n location.areaId AS locationAreaId,\n clothing.id AS clothingId,\n clothing.name AS clothingName\n FROM event\n JOIN location ON event.locationId = location.id\n JOIN clothing ON event.clothing = clothing.id\n WHERE starttimestamp::date >= $1\n AND starttimestamp::date <= $2\n AND location.areaId = $3\n ORDER BY event.starttimestamp;\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@ -110,5 +110,5 @@
|
|||||||
false
|
false
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "10b4b80f351b66ac5e778a3031288ac5dc66efd0a66b38b7e30f4c954df91bdf"
|
"hash": "65367483e39e07cd0aa142f9bb76c7a5d6dd0611e6b41edd5a593c9f955b5d04"
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "PostgreSQL",
|
"db_name": "PostgreSQL",
|
||||||
"query": "\n SELECT\n availability.id,\n availability.userId,\n availability.startTimestamp,\n availability.endTimestamp,\n availability.comment\n FROM availability\n WHERE availability.userId = $1\n AND availability.starttimestamp::date >= $2\n AND availability.endtimestamp::date <= $3;\n ",
|
"query": "\n SELECT\n availability.id,\n availability.userId,\n availability.startTimestamp,\n availability.endTimestamp,\n availability.comment\n FROM availability\n WHERE availability.userId = $1\n AND availability.starttimestamp::date >= $2\n AND availability.endtimestamp::date <= $3\n ORDER BY availability.starttimestamp;\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@ -44,5 +44,5 @@
|
|||||||
true
|
true
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "f60053118df6a791d31fa258ee3737881f8f97ca41cbebd92eb22c967292d2ee"
|
"hash": "66638de4a321ba610206a9f5c237cb17eb5221c1dbe4d4c5e83167b2d2807db4"
|
||||||
}
|
}
|
59
db/.sqlx/query-6788747f70812d6a87833d821c9845f59b4338bc42a40050a68736ba30d937d5.json
generated
Normal file
59
db/.sqlx/query-6788747f70812d6a87833d821c9845f59b4338bc42a40050a68736ba30d937d5.json
generated
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "\n SELECT\n assignment.eventId,\n assignment.availabilityId,\n assignment.function AS \"function: Function\",\n assignment.startTimestamp,\n assignment.endTimestamp\n FROM assignment\n JOIN availability ON assignment.availabilityId = availability.id\n WHERE assignment.starttimestamp::date >= $1\n AND assignment.starttimestamp::date <= $2\n AND availability.userId = $3\n ORDER BY assignment.starttimestamp;\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"ordinal": 0,
|
||||||
|
"name": "eventid",
|
||||||
|
"type_info": "Int4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 1,
|
||||||
|
"name": "availabilityid",
|
||||||
|
"type_info": "Int4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 2,
|
||||||
|
"name": "function: Function",
|
||||||
|
"type_info": {
|
||||||
|
"Custom": {
|
||||||
|
"name": "function",
|
||||||
|
"kind": {
|
||||||
|
"Enum": [
|
||||||
|
"posten",
|
||||||
|
"fuehrungsassistent",
|
||||||
|
"wachhabender"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 3,
|
||||||
|
"name": "starttimestamp",
|
||||||
|
"type_info": "Timestamptz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ordinal": 4,
|
||||||
|
"name": "endtimestamp",
|
||||||
|
"type_info": "Timestamptz"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"Date",
|
||||||
|
"Date",
|
||||||
|
"Int4"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "6788747f70812d6a87833d821c9845f59b4338bc42a40050a68736ba30d937d5"
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
use chrono::NaiveDateTime;
|
use chrono::{NaiveDate, NaiveDateTime};
|
||||||
use sqlx::{PgPool, query};
|
use sqlx::{PgPool, query};
|
||||||
|
|
||||||
use super::{AssignmentChangeset, Function, Result};
|
use super::{AssignmentChangeset, Function, Result};
|
||||||
@ -101,6 +101,47 @@ impl Assignment {
|
|||||||
Ok(assignemnets)
|
Ok(assignemnets)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn read_all_by_daterange_and_user(
|
||||||
|
pool: &PgPool,
|
||||||
|
date_range: (&NaiveDate, &NaiveDate),
|
||||||
|
user_id: i32,
|
||||||
|
) -> Result<Vec<Assignment>> {
|
||||||
|
let records = query!(
|
||||||
|
r##"
|
||||||
|
SELECT
|
||||||
|
assignment.eventId,
|
||||||
|
assignment.availabilityId,
|
||||||
|
assignment.function AS "function: Function",
|
||||||
|
assignment.startTimestamp,
|
||||||
|
assignment.endTimestamp
|
||||||
|
FROM assignment
|
||||||
|
JOIN availability ON assignment.availabilityId = availability.id
|
||||||
|
WHERE assignment.starttimestamp::date >= $1
|
||||||
|
AND assignment.starttimestamp::date <= $2
|
||||||
|
AND availability.userId = $3
|
||||||
|
ORDER BY assignment.starttimestamp;
|
||||||
|
"##,
|
||||||
|
date_range.0,
|
||||||
|
date_range.1,
|
||||||
|
user_id
|
||||||
|
)
|
||||||
|
.fetch_all(pool)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let assignemnets = records
|
||||||
|
.iter()
|
||||||
|
.map(|r| Assignment {
|
||||||
|
event_id: r.eventid,
|
||||||
|
availability_id: r.availabilityid,
|
||||||
|
function: r.function,
|
||||||
|
start: r.starttimestamp.naive_utc(),
|
||||||
|
end: r.endtimestamp.naive_utc(),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(assignemnets)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn read(
|
pub async fn read(
|
||||||
pool: &PgPool,
|
pool: &PgPool,
|
||||||
event_id: i32,
|
event_id: i32,
|
||||||
|
@ -357,7 +357,8 @@ impl Availability {
|
|||||||
FROM availability
|
FROM availability
|
||||||
WHERE availability.userId = $1
|
WHERE availability.userId = $1
|
||||||
AND availability.starttimestamp::date >= $2
|
AND availability.starttimestamp::date >= $2
|
||||||
AND availability.endtimestamp::date <= $3;
|
AND availability.endtimestamp::date <= $3
|
||||||
|
ORDER BY availability.starttimestamp;
|
||||||
"##,
|
"##,
|
||||||
user_id,
|
user_id,
|
||||||
date_range.0,
|
date_range.0,
|
||||||
|
@ -124,7 +124,8 @@ impl Event {
|
|||||||
JOIN clothing ON event.clothing = clothing.id
|
JOIN clothing ON event.clothing = clothing.id
|
||||||
WHERE starttimestamp::date >= $1
|
WHERE starttimestamp::date >= $1
|
||||||
AND starttimestamp::date <= $2
|
AND starttimestamp::date <= $2
|
||||||
AND location.areaId = $3;
|
AND location.areaId = $3
|
||||||
|
ORDER BY event.starttimestamp;
|
||||||
"#,
|
"#,
|
||||||
date_range.0,
|
date_range.0,
|
||||||
date_range.1,
|
date_range.1,
|
||||||
|
@ -7,11 +7,11 @@ use crate::{
|
|||||||
filters,
|
filters,
|
||||||
utils::{
|
utils::{
|
||||||
ApplicationError,
|
ApplicationError,
|
||||||
DateTimeFormat::{DayMonthYearHourMinute, HourMinute, WeekdayDayMonthYear},
|
DateTimeFormat::{HourMinute, WeekdayDayMonthYearHourMinute},
|
||||||
TemplateResponse,
|
TemplateResponse,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use brass_db::models::{Assignment, Availability, Event, Function, Role, User};
|
use brass_db::models::{Assignment, Availability, Event, Role, User};
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "overview.html")]
|
#[template(path = "overview.html")]
|
||||||
@ -19,6 +19,7 @@ struct OverviewTemplate {
|
|||||||
user: User,
|
user: User,
|
||||||
events: Vec<Event>,
|
events: Vec<Event>,
|
||||||
availabilities: Vec<Availability>,
|
availabilities: Vec<Availability>,
|
||||||
|
assignments: Vec<(Assignment, String)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::get("/")]
|
#[actix_web::get("/")]
|
||||||
@ -28,22 +29,36 @@ async fn get(
|
|||||||
) -> Result<impl Responder, ApplicationError> {
|
) -> Result<impl Responder, ApplicationError> {
|
||||||
let today = Utc::now().date_naive();
|
let today = Utc::now().date_naive();
|
||||||
let next_month = today.checked_add_months(Months::new(1)).unwrap();
|
let next_month = today.checked_add_months(Months::new(1)).unwrap();
|
||||||
|
let date_range = (&today, &next_month);
|
||||||
|
|
||||||
let events = Event::read_all_by_daterange_and_area_including_location(
|
let events = Event::read_all_by_daterange_and_area_including_location(
|
||||||
pool.get_ref(),
|
pool.get_ref(),
|
||||||
(&today, &next_month),
|
date_range,
|
||||||
user.area_id,
|
user.area_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let availabilities =
|
let availabilities =
|
||||||
Availability::read_by_user_and_daterange(pool.get_ref(), user.id, (&today, &next_month))
|
Availability::read_by_user_and_daterange(pool.get_ref(), user.id, date_range).await?;
|
||||||
.await?;
|
|
||||||
|
let assignments =
|
||||||
|
Assignment::read_all_by_daterange_and_user(pool.get_ref(), date_range, user.id)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.map(|a| {
|
||||||
|
if let Some(e) = events.iter().find(|e| e.id == a.event_id) {
|
||||||
|
(a, e.name.clone())
|
||||||
|
} else {
|
||||||
|
(a, String::new())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let template = OverviewTemplate {
|
let template = OverviewTemplate {
|
||||||
user: user.into_inner(),
|
user: user.into_inner(),
|
||||||
events,
|
events,
|
||||||
availabilities,
|
availabilities,
|
||||||
|
assignments,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(template.to_response()?)
|
Ok(template.to_response()?)
|
||||||
|
@ -8,6 +8,7 @@ pub enum DateTimeFormat {
|
|||||||
HourMinute,
|
HourMinute,
|
||||||
WeekdayDayMonth,
|
WeekdayDayMonth,
|
||||||
WeekdayDayMonthYear,
|
WeekdayDayMonthYear,
|
||||||
|
WeekdayDayMonthYearHourMinute,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DateTimeFormat> for &'static str {
|
impl From<DateTimeFormat> for &'static str {
|
||||||
@ -21,6 +22,7 @@ impl From<DateTimeFormat> for &'static str {
|
|||||||
DateTimeFormat::HourMinute => "%H:%M",
|
DateTimeFormat::HourMinute => "%H:%M",
|
||||||
DateTimeFormat::WeekdayDayMonth => "%A, %d.%m.",
|
DateTimeFormat::WeekdayDayMonth => "%A, %d.%m.",
|
||||||
DateTimeFormat::WeekdayDayMonthYear => "%A, %d.%m.%Y",
|
DateTimeFormat::WeekdayDayMonthYear => "%A, %d.%m.%Y",
|
||||||
|
DateTimeFormat::WeekdayDayMonthYearHourMinute => "%A, %d.%m.%Y %H:%M",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,5 +23,5 @@ pub fn get_return_url_for_date(date: &NaiveDate) -> String {
|
|||||||
return String::from("/");
|
return String::from("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
format!("/?date={}", date)
|
format!("/calendar?date={}", date)
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<a class="button is-link is-light" hx-boost="true" href="/?date={{ date }}">
|
<a class="button is-link is-light" hx-boost="true" href="/calendar?date={{ date }}">
|
||||||
<svg class="icon">
|
<svg class="icon">
|
||||||
<use href="/static/feather-sprite.svg#arrow-left" />
|
<use href="/static/feather-sprite.svg#arrow-left" />
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<div class="level is-hidden-mobile">
|
<div class="level is-hidden-mobile">
|
||||||
<div class="level-left">
|
<div class="level-left">
|
||||||
<a hx-boost="true" class="button is-link level-item"
|
<a hx-boost="true" class="button is-link level-item"
|
||||||
href="/?date={{ date.pred() }}{{ selected_area|show_area_query(false) }}">
|
href="/calendar?date={{ date.pred() }}{{ selected_area|show_area_query(false) }}">
|
||||||
<svg class="icon">
|
<svg class="icon">
|
||||||
<use href="/static/feather-sprite.svg#arrow-left" />
|
<use href="/static/feather-sprite.svg#arrow-left" />
|
||||||
</svg>
|
</svg>
|
||||||
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
<div class="level-right">
|
<div class="level-right">
|
||||||
<a hx-boost="true" class="button is-link level-item"
|
<a hx-boost="true" class="button is-link level-item"
|
||||||
href="/?date={{ date.succ() }}{{ selected_area|show_area_query(false) }}">
|
href="/calendar?date={{ date.succ() }}{{ selected_area|show_area_query(false) }}">
|
||||||
<svg class="icon">
|
<svg class="icon">
|
||||||
<use href="/static/feather-sprite.svg#arrow-right" />
|
<use href="/static/feather-sprite.svg#arrow-right" />
|
||||||
</svg>
|
</svg>
|
||||||
@ -49,7 +49,7 @@
|
|||||||
<div class="level is-hidden-tablet is-mobile">
|
<div class="level is-hidden-tablet is-mobile">
|
||||||
<div class="level-left">
|
<div class="level-left">
|
||||||
<a hx-boost="true" class="button is-link level-item"
|
<a hx-boost="true" class="button is-link level-item"
|
||||||
href="/?date={{ date.pred() }}{{ selected_area|show_area_query(false) }}">
|
href="/calendar?date={{ date.pred() }}{{ selected_area|show_area_query(false) }}">
|
||||||
<svg class="icon">
|
<svg class="icon">
|
||||||
<use href="/static/feather-sprite.svg#arrow-left" />
|
<use href="/static/feather-sprite.svg#arrow-left" />
|
||||||
</svg>
|
</svg>
|
||||||
@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
<div class="level-right">
|
<div class="level-right">
|
||||||
<a hx-boost="true" class="button is-link level-item"
|
<a hx-boost="true" class="button is-link level-item"
|
||||||
href="/?date={{ date.succ() }}{{ selected_area|show_area_query(false) }}">
|
href="/calendar?date={{ date.succ() }}{{ selected_area|show_area_query(false) }}">
|
||||||
<svg class="icon">
|
<svg class="icon">
|
||||||
<use href="/static/feather-sprite.svg#arrow-right" />
|
<use href="/static/feather-sprite.svg#arrow-right" />
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -225,7 +225,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<a class="button is-link is-light" hx-boost="true" href="/?date={{ date }}">
|
<a class="button is-link is-light" hx-boost="true" href="/calendar?date={{ date }}">
|
||||||
<svg class="icon">
|
<svg class="icon">
|
||||||
<use href="/static/feather-sprite.svg#arrow-left" />
|
<use href="/static/feather-sprite.svg#arrow-left" />
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<a class="button is-link is-light" hx-boost="true" href="/?date={{ event.start.date() }}">
|
<a class="button is-link is-light" hx-boost="true" href="/calendar?date={{ event.start.date() }}">
|
||||||
<svg class="icon">
|
<svg class="icon">
|
||||||
<use href="/static/feather-sprite.svg#arrow-left" />
|
<use href="/static/feather-sprite.svg#arrow-left" />
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -1,9 +1,95 @@
|
|||||||
{% extends "nav.html" %}
|
{% extends "nav.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section id="progress" class="section">
|
<section class="section">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
Übersicht
|
<h1 class="title is-1">Übersicht</h1>
|
||||||
|
<h3 class="title is-3">geplante Veranstaltungen</h3>
|
||||||
|
<p class="subtitle is-5">in den nächsten 31 Tagen</p>
|
||||||
|
{% if events.len() == 0 %}
|
||||||
|
<div class="notification">
|
||||||
|
Keine Veranstaltungen für diesen Zeitraum geplant.
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="panel p-2">
|
||||||
|
{% for e in events %}
|
||||||
|
<div class="panel-block is-justify-content-space-between">
|
||||||
|
<span>
|
||||||
|
<b>{{ e.name }}</b> {{ e.start|fmt_datetime(WeekdayDayMonthYearHourMinute) }} - {{
|
||||||
|
e.end|fmt_datetime(HourMinute) }}
|
||||||
|
</span>
|
||||||
|
<a class="button is-small is-link is-light" href="/calendar?date={{ e.start.date() }}">
|
||||||
|
<svg class="icon">
|
||||||
|
<use href="/static/feather-sprite.svg#calendar" />
|
||||||
|
</svg>
|
||||||
|
<span>im Kalender anzeigen</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h3 class="title is-3">Deine Verfügbarkeiten</h3>
|
||||||
|
<p class="subtitle is-5">in den nächsten 31 Tagen</p>
|
||||||
|
{% if availabilities.len() == 0 %}
|
||||||
|
<div class="notification">
|
||||||
|
Keine Verfügbarkeiten für diesen Zeitraum hinterlegt.
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="panel p-2">
|
||||||
|
{% for a in availabilities %}
|
||||||
|
<div class="panel-block is-justify-content-space-between">
|
||||||
|
<span>
|
||||||
|
{{ a.start|fmt_datetime(WeekdayDayMonthYearHourMinute) }} - {{
|
||||||
|
a.end|fmt_datetime(HourMinute) }} {% if let Some(comment) = a.comment %} Kommentar: {{ comment }}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
<div class="buttons are-small">
|
||||||
|
<a class="button is-primary is-light" href="/availability/edit/{{ a.id }}">
|
||||||
|
<svg class="icon">
|
||||||
|
<use href="/static/feather-sprite.svg#edit" />
|
||||||
|
</svg>
|
||||||
|
<span>Bearbeiten</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a class="button is-link is-light" href="/calendar?date={{ a.start.date() }}">
|
||||||
|
<svg class="icon">
|
||||||
|
<use href="/static/feather-sprite.svg#calendar" />
|
||||||
|
</svg>
|
||||||
|
<span>im Kalender anzeigen</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h3 class="title is-3">Deine Einteilungen</h3>
|
||||||
|
<p class="subtitle is-5">in den nächsten 31 Tagen</p>
|
||||||
|
{% if assignments.len() == 0 %}
|
||||||
|
<div class="notification">
|
||||||
|
Keine Einteilungen für diesen Zeitraum vorhanden.
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="panel p-2">
|
||||||
|
{% for (a, event_name) in assignments %}
|
||||||
|
<div class="panel-block is-justify-content-space-between">
|
||||||
|
<span>
|
||||||
|
{{ a.start|fmt_datetime(WeekdayDayMonthYearHourMinute) }} - {{
|
||||||
|
a.end|fmt_datetime(HourMinute) }} bei {{ event_name }} als {{ a.function }}
|
||||||
|
</span>
|
||||||
|
<a class="button is-small is-link is-light" href="/calendar?date={{ a.start.date() }}">
|
||||||
|
<svg class="icon">
|
||||||
|
<use href="/static/feather-sprite.svg#calendar" />
|
||||||
|
</svg>
|
||||||
|
<span>im Kalender anzeigen</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user