cox not allowed to set always_show; cargo clippy
This commit is contained in:
		| @@ -575,10 +575,8 @@ ORDER BY departure DESC | ||||
|             return Err(LogbookUpdateError::ArrivalNotAfterDeparture); | ||||
|         } | ||||
|  | ||||
|         if !boat.external { | ||||
|             if boat.on_water_between(db, dep, arr).await { | ||||
|                 return Err(LogbookUpdateError::BoatAlreadyOnWater); | ||||
|             }; | ||||
|         if !boat.external && boat.on_water_between(db, dep, arr).await { | ||||
|             return Err(LogbookUpdateError::BoatAlreadyOnWater); | ||||
|         } | ||||
|  | ||||
|         let duration_in_mins = (arr.and_utc().timestamp() - dep.and_utc().timestamp()) / 60; | ||||
| @@ -594,14 +592,13 @@ ORDER BY departure DESC | ||||
|         let today = Local::now().date_naive(); | ||||
|         let day_diff = today - arr.date(); | ||||
|         let day_diff = day_diff.num_days(); | ||||
|         if day_diff >= 7 { | ||||
|             if !user.has_role_tx(db, "admin").await | ||||
|                 && !user | ||||
|                     .has_role_tx(db, "allow-retroactive-logbookentries") | ||||
|                     .await | ||||
|             { | ||||
|                 return Err(LogbookUpdateError::OnlyAllowedToEndTripsEndingToday); | ||||
|             } | ||||
|         if day_diff >= 7 | ||||
|             && !user.has_role_tx(db, "admin").await | ||||
|             && !user | ||||
|                 .has_role_tx(db, "allow-retroactive-logbookentries") | ||||
|                 .await | ||||
|         { | ||||
|             return Err(LogbookUpdateError::OnlyAllowedToEndTripsEndingToday); | ||||
|         } | ||||
|         if day_diff < 0 && !user.has_role_tx(db, "admin").await { | ||||
|             return Err(LogbookUpdateError::OnlyAllowedToEndTripsEndingToday); | ||||
|   | ||||
| @@ -40,7 +40,6 @@ pub struct TripUpdate<'a> { | ||||
|     pub max_people: i32, | ||||
|     pub notes: Option<&'a str>, | ||||
|     pub trip_type: Option<i64>, //TODO: Move to `TripType` | ||||
|     pub always_show: bool, | ||||
|     pub is_locked: bool, | ||||
| } | ||||
|  | ||||
| @@ -210,11 +209,10 @@ WHERE day=? | ||||
|         let was_already_cancelled = tripdetails.max_people == 0; | ||||
|  | ||||
|         sqlx::query!( | ||||
|             "UPDATE trip_details SET max_people = ?, notes = ?, trip_type_id = ?, always_show = ?, is_locked = ? WHERE id = ?", | ||||
|             "UPDATE trip_details SET max_people = ?, notes = ?, trip_type_id = ?, is_locked = ? WHERE id = ?", | ||||
|             update.max_people, | ||||
|             update.notes, | ||||
|             update.trip_type, | ||||
|             update.always_show, | ||||
|             update.is_locked, | ||||
|             trip_details_id | ||||
|         ) | ||||
| @@ -338,6 +336,20 @@ WHERE day=? | ||||
|         self.cox_id == user_id | ||||
|     } | ||||
|  | ||||
|     pub(crate) async fn toggle_always_show(&self, db: &SqlitePool) { | ||||
|         if let Some(trip_details) = self.trip_details_id { | ||||
|             let new_state = !self.always_show; | ||||
|             sqlx::query!( | ||||
|                 "UPDATE trip_details SET always_show = ? WHERE id = ?", | ||||
|                 new_state, | ||||
|                 trip_details | ||||
|             ) | ||||
|             .execute(db) | ||||
|             .await | ||||
|             .unwrap(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub(crate) async fn get_pinned_for_day( | ||||
|         db: &sqlx::Pool<sqlx::Sqlite>, | ||||
|         day: NaiveDate, | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| use crate::model::user::User; | ||||
| use chrono::NaiveDate; | ||||
| use chrono::{Local, NaiveDate}; | ||||
| use rocket::FromForm; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use sqlx::{FromRow, SqlitePool}; | ||||
| @@ -33,7 +33,6 @@ pub struct TripDetailsToAdd<'r> { | ||||
|     pub notes: Option<&'r str>, | ||||
|     pub trip_type: Option<i64>, | ||||
|     pub allow_guests: bool, | ||||
|     pub always_show: bool, | ||||
| } | ||||
|  | ||||
| impl TripDetails { | ||||
| @@ -59,6 +58,24 @@ WHERE id like ? | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn date(&self) -> NaiveDate { | ||||
|         NaiveDate::parse_from_str(&self.day, "%Y-%m-%d").unwrap() | ||||
|     } | ||||
|  | ||||
|     pub(crate) async fn user_sees_trip(&self, db: &SqlitePool, user: &User) -> bool { | ||||
|         let today = Local::now().date_naive(); | ||||
|         let day_diff = self.date() - today; | ||||
|         let day_diff = day_diff.num_days(); | ||||
|         if day_diff < 0 { | ||||
|             // tripdetails is in past | ||||
|             return false; | ||||
|         } | ||||
|         if day_diff <= user.amount_days_to_show(db).await { | ||||
|             return true; | ||||
|         } | ||||
|         self.always_show | ||||
|     } | ||||
|  | ||||
|     pub async fn find_by_startingdatetime( | ||||
|         db: &SqlitePool, | ||||
|         day: String, | ||||
| @@ -142,14 +159,13 @@ WHERE day = ? AND planned_starting_time = ? | ||||
|     /// Creates a new entry in `trip_details` and returns its id. | ||||
|     pub async fn create(db: &SqlitePool, tripdetails: TripDetailsToAdd<'_>) -> i64 { | ||||
|         let query = sqlx::query!( | ||||
|             "INSERT INTO trip_details(planned_starting_time, max_people, day, notes, allow_guests, trip_type_id, always_show) VALUES(?, ?, ?, ?, ?, ?, ?)" , | ||||
|             "INSERT INTO trip_details(planned_starting_time, max_people, day, notes, allow_guests, trip_type_id) VALUES(?, ?, ?, ?, ?, ?)" , | ||||
|             tripdetails.planned_starting_time, | ||||
|             tripdetails.max_people, | ||||
|             tripdetails.day, | ||||
|             tripdetails.notes, | ||||
|             tripdetails.allow_guests, | ||||
|             tripdetails.trip_type, | ||||
|             tripdetails.always_show | ||||
|         ) | ||||
|         .execute(db) | ||||
|         .await | ||||
| @@ -305,7 +321,6 @@ mod test { | ||||
|                     notes: None, | ||||
|                     allow_guests: false, | ||||
|                     trip_type: None, | ||||
|                     always_show: false | ||||
|                 } | ||||
|             ) | ||||
|             .await, | ||||
| @@ -321,7 +336,6 @@ mod test { | ||||
|                     notes: None, | ||||
|                     allow_guests: false, | ||||
|                     trip_type: None, | ||||
|                     always_show: false | ||||
|                 } | ||||
|             ) | ||||
|             .await, | ||||
|   | ||||
| @@ -450,6 +450,12 @@ ASKÖ Ruderverein Donau Linz", self.name), | ||||
|         false | ||||
|     } | ||||
|  | ||||
|     pub async fn allowed_to_update_always_show_trip(&self, db: &SqlitePool) -> bool { | ||||
|         AllowedToUpdateTripToAlwaysBeShownUser::new(db, self.clone()) | ||||
|             .await | ||||
|             .is_some() | ||||
|     } | ||||
|  | ||||
|     pub async fn has_membership_pdf(&self, db: &SqlitePool) -> bool { | ||||
|         match sqlx::query_scalar!("SELECT membership_pdf FROM user WHERE id = ?", self.id) | ||||
|             .fetch_one(db) | ||||
| @@ -879,7 +885,7 @@ ORDER BY last_access DESC | ||||
|         days | ||||
|     } | ||||
|  | ||||
|     async fn amount_days_to_show(&self, db: &SqlitePool) -> i64 { | ||||
|     pub(crate) async fn amount_days_to_show(&self, db: &SqlitePool) -> i64 { | ||||
|         if self.has_role(db, "cox").await { | ||||
|             let end_of_year = NaiveDate::from_ymd_opt(Local::now().year(), 12, 31).unwrap(); //Ok, | ||||
|                                                                                              //december | ||||
| @@ -890,7 +896,7 @@ ORDER BY last_access DESC | ||||
|                 .num_days() | ||||
|                 + 1; | ||||
|  | ||||
|             if days_left_in_year < 30 { | ||||
|             if days_left_in_year <= 31 { | ||||
|                 let end_of_next_year = | ||||
|                     NaiveDate::from_ymd_opt(Local::now().year() + 1, 12, 31).unwrap(); //Ok, | ||||
|                                                                                        //december | ||||
| @@ -1028,6 +1034,7 @@ special_user!(VorstandUser, +"Vorstand"); | ||||
| special_user!(EventUser, +"manage_events"); | ||||
| special_user!(AllowedToEditPaymentStatusUser, +"kassier", +"admin"); | ||||
| special_user!(ManageUserUser, +"admin", +"schriftfuehrer"); | ||||
| special_user!(AllowedToUpdateTripToAlwaysBeShownUser, +"admin"); | ||||
|  | ||||
| #[derive(FromRow, Serialize, Deserialize, Clone, Debug)] | ||||
| pub struct UserWithRolesAndMembershipPdf { | ||||
|   | ||||
| @@ -24,6 +24,10 @@ impl UserTrip { | ||||
|             return Err(UserTripError::GuestNotAllowedForThisEvent); | ||||
|         } | ||||
|  | ||||
|         if !trip_details.user_sees_trip(db, user).await { | ||||
|             return Err(UserTripError::NotVisibleToUser); | ||||
|         } | ||||
|  | ||||
|         //TODO: Check if user sees the event (otherwise she could forge trip_details_id) | ||||
|  | ||||
|         let is_cox = trip_details.user_is_cox(db, user).await; | ||||
| @@ -96,6 +100,10 @@ impl UserTrip { | ||||
|             return Err(UserTripDeleteError::DetailsLocked); | ||||
|         } | ||||
|  | ||||
|         if !trip_details.user_sees_trip(db, user).await { | ||||
|             return Err(UserTripDeleteError::NotVisibleToUser); | ||||
|         } | ||||
|  | ||||
|         if let Some(name) = name { | ||||
|             if !trip_details.user_allowed_to_change(db, user).await { | ||||
|                 return Err(UserTripDeleteError::NotAllowedToDeleteGuest); | ||||
| @@ -137,6 +145,7 @@ pub enum UserTripError { | ||||
|     CantRegisterAtOwnEvent, | ||||
|     GuestNotAllowedForThisEvent, | ||||
|     NotAllowedToAddGuest, | ||||
|     NotVisibleToUser, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, PartialEq)] | ||||
| @@ -144,6 +153,7 @@ pub enum UserTripDeleteError { | ||||
|     DetailsLocked, | ||||
|     GuestNotParticipating, | ||||
|     NotAllowedToDeleteGuest, | ||||
|     NotVisibleToUser, | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
|   | ||||
| @@ -374,7 +374,7 @@ async fn create_scheckbuch( | ||||
|     if mail.parse::<Address>().is_err() { | ||||
|         return Flash::error( | ||||
|             Redirect::to("/admin/user/scheckbuch"), | ||||
|             format!("Keine gültige Mailadresse"), | ||||
|             "Keine gültige Mailadresse".to_string(), | ||||
|         ); | ||||
|     } | ||||
|  | ||||
| @@ -383,9 +383,8 @@ async fn create_scheckbuch( | ||||
|     if User::find_by_name(db, name).await.is_some() { | ||||
|         return Flash::error( | ||||
|             Redirect::to("/admin/user/scheckbuch"), | ||||
|             format!( | ||||
|                 "Kann kein Scheckbuch erstellen, der Name wird bereits von einem User verwendet" | ||||
|             ), | ||||
|             "Kann kein Scheckbuch erstellen, der Name wird bereits von einem User verwendet" | ||||
|                 .to_string(), | ||||
|         ); | ||||
|     } | ||||
|  | ||||
| @@ -418,14 +417,14 @@ async fn schnupper_to_scheckbuch( | ||||
|     let Some(user) = User::find_by_id(db, id).await else { | ||||
|         return Flash::error( | ||||
|             Redirect::to("/admin/schnupper"), | ||||
|             format!("user id not found"), | ||||
|             "user id not found".to_string(), | ||||
|         ); | ||||
|     }; | ||||
|  | ||||
|     if !user.has_role(db, "schnupperant").await { | ||||
|         return Flash::error( | ||||
|             Redirect::to("/admin/schnupper"), | ||||
|             format!("kein schnupperant..."), | ||||
|             "kein schnupperant...".to_string(), | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ use crate::model::{ | ||||
|     log::Log, | ||||
|     trip::{self, CoxHelpError, Trip, TripDeleteError, TripHelpDeleteError, TripUpdateError}, | ||||
|     tripdetails::{TripDetails, TripDetailsToAdd}, | ||||
|     user::CoxUser, | ||||
|     user::{AllowedToUpdateTripToAlwaysBeShownUser, CoxUser}, | ||||
| }; | ||||
|  | ||||
| #[post("/trip", data = "<data>")] | ||||
| @@ -42,7 +42,6 @@ struct EditTripForm<'r> { | ||||
|     max_people: i32, | ||||
|     notes: Option<&'r str>, | ||||
|     trip_type: Option<i64>, | ||||
|     always_show: bool, | ||||
|     is_locked: bool, | ||||
| } | ||||
|  | ||||
| @@ -60,7 +59,6 @@ async fn update( | ||||
|             max_people: data.max_people, | ||||
|             notes: data.notes, | ||||
|             trip_type: data.trip_type, | ||||
|             always_show: data.always_show, | ||||
|             is_locked: data.is_locked, | ||||
|         }; | ||||
|         match Trip::update_own(db, &update).await { | ||||
| @@ -80,6 +78,23 @@ async fn update( | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[get("/trip/<trip_id>/toggle-always-show")] | ||||
| async fn toggle_always_show( | ||||
|     db: &State<SqlitePool>, | ||||
|     trip_id: i64, | ||||
|     _user: AllowedToUpdateTripToAlwaysBeShownUser, | ||||
| ) -> Flash<Redirect> { | ||||
|     if let Some(trip) = Trip::find_by_id(db, trip_id).await { | ||||
|         trip.toggle_always_show(db).await; | ||||
|         Flash::success( | ||||
|             Redirect::to("/planned"), | ||||
|             "'Immer anzeigen' erfolgreich gesetzt!", | ||||
|         ) | ||||
|     } else { | ||||
|         Flash::error(Redirect::to("/planned"), "Ausfahrt gibt's nicht") | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[get("/join/<planned_event_id>")] | ||||
| async fn join(db: &State<SqlitePool>, planned_event_id: i64, cox: CoxUser) -> Flash<Redirect> { | ||||
|     if let Some(planned_event) = Event::find_by_id(db, planned_event_id).await { | ||||
| @@ -164,7 +179,14 @@ async fn remove(db: &State<SqlitePool>, planned_event_id: i64, cox: CoxUser) -> | ||||
| } | ||||
|  | ||||
| pub fn routes() -> Vec<Route> { | ||||
|     routes![create, join, remove, remove_trip, update] | ||||
|     routes![ | ||||
|         create, | ||||
|         join, | ||||
|         remove, | ||||
|         remove_trip, | ||||
|         update, | ||||
|         toggle_always_show | ||||
|     ] | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
|   | ||||
| @@ -131,13 +131,13 @@ async fn new_blogpost( | ||||
|     blogpost: Form<NewBlogpostForm<'_>>, | ||||
|     config: &State<Config>, | ||||
| ) -> String { | ||||
|     if blogpost.pw == &config.wordpress_key { | ||||
|         let member = Role::find_by_name(&db, "Donau Linz").await.unwrap(); | ||||
|     if blogpost.pw == config.wordpress_key { | ||||
|         let member = Role::find_by_name(db, "Donau Linz").await.unwrap(); | ||||
|         Notification::create_for_role( | ||||
|             db, | ||||
|             &member, | ||||
|             &urlencoding::decode(blogpost.article_title).expect("UTF-8"), | ||||
|             &format!("Neuer Blogpost"), | ||||
|             "Neuer Blogpost", | ||||
|             Some(blogpost.article_url), | ||||
|             None, | ||||
|         ) | ||||
| @@ -160,9 +160,9 @@ async fn blogpost_unpublished( | ||||
|     blogpost: Form<BlogpostUnpublishedForm<'_>>, | ||||
|     config: &State<Config>, | ||||
| ) -> String { | ||||
|     if blogpost.pw == &config.wordpress_key { | ||||
|     if blogpost.pw == config.wordpress_key { | ||||
|         Notification::delete_by_link( | ||||
|             &db, | ||||
|             db, | ||||
|             &urlencoding::decode(blogpost.article_url).expect("UTF-8"), | ||||
|         ) | ||||
|         .await; | ||||
|   | ||||
| @@ -37,6 +37,10 @@ async fn index( | ||||
|         context.insert("flash", &msg.into_inner()); | ||||
|     } | ||||
|  | ||||
|     context.insert( | ||||
|         "allowed_to_update_always_show_trip", | ||||
|         &user.allowed_to_update_always_show_trip(db).await, | ||||
|     ); | ||||
|     context.insert("fee", &user.fee(db).await); | ||||
|     context.insert("loggedin_user", &UserWithDetails::from_user(user, db).await); | ||||
|     context.insert("days", &days); | ||||
| @@ -99,6 +103,10 @@ async fn join( | ||||
|             Redirect::to("/planned"), | ||||
|             "Du darfst keine Gäste hinzufügen.", | ||||
|         ), | ||||
|         Err(UserTripError::NotVisibleToUser) => Flash::error( | ||||
|             Redirect::to("/planned"), | ||||
|             "Du kannst dich nicht registrieren, weil du die Ausfahrt gar nicht sehen solltest.", | ||||
|         ), | ||||
|         Err(UserTripError::DetailsLocked) => Flash::error( | ||||
|             Redirect::to("/planned"), | ||||
|             "Die Bootseinteilung wurde bereits gemacht. Wenn du noch mitrudern möchtest, frag bitte bei einer angemeldeten Steuerperson nach, ob das noch möglich ist.", | ||||
| @@ -147,6 +155,10 @@ async fn remove_guest( | ||||
|         Err(UserTripDeleteError::GuestNotParticipating) => { | ||||
|             Flash::error(Redirect::to("/planned"), "Gast nicht angemeldet.") | ||||
|         } | ||||
|         Err(UserTripDeleteError::NotVisibleToUser) => Flash::error( | ||||
|             Redirect::to("/planned"), | ||||
|             "Du kannst dich nicht abmelden, weil du die Ausfahrt gar nicht sehen solltest.", | ||||
|         ), | ||||
|         Err(UserTripDeleteError::NotAllowedToDeleteGuest) => Flash::error( | ||||
|             Redirect::to("/planned"), | ||||
|             "Keine Berechtigung um den Gast zu entfernen.", | ||||
| @@ -191,6 +203,18 @@ async fn remove( | ||||
|  | ||||
|             Flash::error(Redirect::to("/planned"), "Das Boot ist bereits eingeteilt. Bitte kontaktiere den Schiffsführer (Nummern siehe Signalgruppe) falls du dich doch abmelden willst.") | ||||
|         } | ||||
|         Err(UserTripDeleteError::NotVisibleToUser) => { | ||||
|             Log::create( | ||||
|                 db, | ||||
|                 format!( | ||||
|                     "User {} tried to unregister for not-yet-seeable trip_details.id={}", | ||||
|                     user.name, trip_details_id | ||||
|                 ), | ||||
|             ) | ||||
|             .await; | ||||
|  | ||||
|             Flash::error(Redirect::to("/planned"), "Abmeldung nicht möglich, da du dieses Event eigentlich gar nicht sehen solltest...") | ||||
|         } | ||||
|         Err(_) => { | ||||
|             panic!("Not possible to be here"); | ||||
|         } | ||||
|   | ||||
| @@ -5,7 +5,6 @@ | ||||
|         {{ macros::input(label='Startzeit (zB "10:00")', name='planned_starting_time', type='time', required=true) }} | ||||
|         {{ macros::input(label='Anzahl Ruderer (ohne Steuerperson)', name='max_people', type='number', required=true, min='0') }} | ||||
|         {{ macros::checkbox(label='Scheckbuch-Anmeldungen erlauben', name='allow_guests') }} | ||||
|         {{ macros::checkbox(label='Immer anzeigen', name='always_show') }} | ||||
|         {{ macros::input(label='Anmerkungen', name='notes', type='input') }} | ||||
|         {{ macros::select(label='Typ', data=trip_types, name='trip_type', default='Reguläre Ausfahrt') }} | ||||
|         <input value="Erstellen" class="w-full btn btn-primary" type="submit" /> | ||||
|   | ||||
| @@ -67,7 +67,8 @@ | ||||
|                     {% endif %} | ||||
|                 {% endfor %} | ||||
|             {% endif %} | ||||
|             <div id="{{ day.day| date(format="%Y-%m-%d") }}" class="bg-white dark:bg-primary-900 rounded-md flex justify-between flex-col shadow reset-js" | ||||
|             <div id="{{ day.day| date(format="%Y-%m-%d") }}" | ||||
|                  class="bg-white dark:bg-primary-900 rounded-md flex justify-between flex-col shadow reset-js" | ||||
|                  style="min-height: 10rem" | ||||
|                  data-trips="{{ amount_trips }}" | ||||
|                  data-month="{{ day.day| date(format='%m') }}" | ||||
| @@ -346,7 +347,6 @@ | ||||
|                                                 <form action="/cox/trip/{{ trip.id }}" method="post" class="grid gap-3"> | ||||
|                                                     {{ macros::input(label='Anzahl Ruderer', name='max_people', type='number', required=true, value=trip.max_people, min=trip.rower | length) }} | ||||
|                                                     {{ macros::input(label='Anmerkungen', name='notes', type='input', value=trip.notes) }} | ||||
|                                                     {{ macros::checkbox(label='Immer anzeigen', name='always_show', id=trip.id,checked=trip.always_show) }} | ||||
|                                                     {{ macros::checkbox(label='Gesperrt', name='is_locked', id=trip.id,checked=trip.is_locked) }} | ||||
|                                                     {{ macros::select(label='Typ', name='trip_type', data=trip_types, default='Reguläre Ausfahrt', selected_id=trip.trip_type_id) }} | ||||
|                                                     <input value="Speichern" class="btn btn-primary" type="submit" /> | ||||
| @@ -369,7 +369,6 @@ | ||||
|                                                         <form action="/cox/trip/{{ trip.id }}" method="post" class="grid"> | ||||
|                                                             {{ macros::input(label='', name='max_people', type='hidden', value=0) }} | ||||
|                                                             {{ macros::input(label='Grund der Absage', name='notes', type='input', value='') }} | ||||
|                                                             {{ macros::input(label='', name='always_show', type='hidden', value=trip.always_show) }} | ||||
|                                                             {{ macros::input(label='', name='is_locked', type='hidden', value=trip.is_locked) }} | ||||
|                                                             {{ macros::input(label='', name='trip_type', type='hidden', value=trip.trip_type_id) }} | ||||
|                                                             <input value="Ausfahrt absagen" class="btn btn-alert" type="submit" /> | ||||
| @@ -379,6 +378,20 @@ | ||||
|                                             {% endif %} | ||||
|                                         {% endif %} | ||||
|                                         {# --- END Edit Form --- #} | ||||
|                                         {# --- START Admin Form --- #} | ||||
|                                         {% if allowed_to_update_always_show_trip %} | ||||
|                                             <div class="bg-gray-100 dark:bg-primary-900 p-3 mt-4 rounded-md"> | ||||
|                                                 <h3 class="text-primary-950 dark:text-white font-bold uppercase tracking-wide mb-2">Admin-Modus</h3> | ||||
|                                                 <form action="/cox/trip/{{ trip.id }}/toggle-always-show" | ||||
|                                                       method="get" | ||||
|                                                       class="grid gap-3"> | ||||
|                                                     <input value="{% if trip.always_show %}Normal anzeigen{% else %}Immer anzeigen{% endif %}" | ||||
|                                                            class="btn btn-primary" | ||||
|                                                            type="submit" /> | ||||
|                                                 </form> | ||||
|                                             </div> | ||||
|                                         {% endif %} | ||||
|                                         {# --- END Admin Form --- #} | ||||
|                                     </div> | ||||
|                                 </div> | ||||
|                                 {# --- END Sidebar Content --- #} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user