forked from Ruderverein-Donau-Linz/rowt
		
	Merge commit '769bc7f1770230a51896073ee440f7f68b8e51be'
This commit is contained in:
		@@ -2,10 +2,6 @@
 | 
				
			|||||||
- [ ] Allow sign-outs only >2h before event
 | 
					- [ ] Allow sign-outs only >2h before event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Notes / Bugfixes
 | 
					# Notes / Bugfixes
 | 
				
			||||||
- [ ] Allow cox to edit own trip
 | 
					 | 
				
			||||||
	- [x] Nobody has registered yet -> deletable
 | 
					 | 
				
			||||||
	- [ ] Change max_people (to be settable to 0)
 | 
					 | 
				
			||||||
	- [ ] Change note
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Frontend Process 
 | 
					# Frontend Process 
 | 
				
			||||||
´cd frontend´
 | 
					´cd frontend´
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -112,6 +112,45 @@ FROM user_trip WHERE trip_details_id = (SELECT trip_details_id FROM trip WHERE i
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Cox decides to update own trip.
 | 
				
			||||||
 | 
					    pub async fn update_own(
 | 
				
			||||||
 | 
					        db: &SqlitePool,
 | 
				
			||||||
 | 
					        cox_id: i64,
 | 
				
			||||||
 | 
					        trip_id: i64,
 | 
				
			||||||
 | 
					        max_people: i32,
 | 
				
			||||||
 | 
					        notes: Option<String>,
 | 
				
			||||||
 | 
					    ) -> Result<(), TripUpdateError> {
 | 
				
			||||||
 | 
					        if !Self::is_trip_from_user(db, cox_id, trip_id).await {
 | 
				
			||||||
 | 
					            return Err(TripUpdateError::NotYourTrip);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let trip_details = sqlx::query!(
 | 
				
			||||||
 | 
					            "SELECT trip_details_id as id FROM trip WHERE id = ?",
 | 
				
			||||||
 | 
					            trip_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .fetch_one(db)
 | 
				
			||||||
 | 
					        .await
 | 
				
			||||||
 | 
					        .unwrap(); //TODO: fixme
 | 
				
			||||||
 | 
					        let trip_details_id = match trip_details.id {
 | 
				
			||||||
 | 
					            Some(id) => id,
 | 
				
			||||||
 | 
					            None => {
 | 
				
			||||||
 | 
					                return Err(TripUpdateError::TripDoesNotExist);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sqlx::query!(
 | 
				
			||||||
 | 
					            "UPDATE trip_details SET max_people = ?, notes = ? WHERE id = ?",
 | 
				
			||||||
 | 
					            max_people,
 | 
				
			||||||
 | 
					            notes,
 | 
				
			||||||
 | 
					            trip_details_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .execute(db)
 | 
				
			||||||
 | 
					        .await
 | 
				
			||||||
 | 
					        .unwrap(); //TODO: fixme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub async fn delete_by_planned_event_id(db: &SqlitePool, user_id: i64, planned_event_id: i64) {
 | 
					    pub async fn delete_by_planned_event_id(db: &SqlitePool, user_id: i64, planned_event_id: i64) {
 | 
				
			||||||
        let _ = sqlx::query!(
 | 
					        let _ = sqlx::query!(
 | 
				
			||||||
            "DELETE FROM trip WHERE cox_id = ? AND planned_event_id = ?",
 | 
					            "DELETE FROM trip WHERE cox_id = ? AND planned_event_id = ?",
 | 
				
			||||||
@@ -133,11 +172,7 @@ FROM user_trip WHERE trip_details_id = (SELECT trip_details_id FROM trip WHERE i
 | 
				
			|||||||
            return Err(TripDeleteError::SomebodyAlreadyRegistered);
 | 
					            return Err(TripDeleteError::SomebodyAlreadyRegistered);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let trip_cox = sqlx::query!("SELECT cox_id FROM trip WHERE id = ?", trip_id)
 | 
					        if !Self::is_trip_from_user(db, user_id, trip_id).await {
 | 
				
			||||||
            .fetch_one(db)
 | 
					 | 
				
			||||||
            .await
 | 
					 | 
				
			||||||
            .unwrap(); //TODO: fixme
 | 
					 | 
				
			||||||
        if trip_cox.cox_id != user_id {
 | 
					 | 
				
			||||||
            return Err(TripDeleteError::NotYourTrip);
 | 
					            return Err(TripDeleteError::NotYourTrip);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -152,6 +187,14 @@ FROM user_trip WHERE trip_details_id = (SELECT trip_details_id FROM trip WHERE i
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async fn is_trip_from_user(db: &SqlitePool, user_id: i64, trip_id: i64) -> bool {
 | 
				
			||||||
 | 
					        let trip_cox = sqlx::query!("SELECT cox_id FROM trip WHERE id = ?", trip_id)
 | 
				
			||||||
 | 
					            .fetch_one(db)
 | 
				
			||||||
 | 
					            .await
 | 
				
			||||||
 | 
					            .unwrap(); //TODO: fixme
 | 
				
			||||||
 | 
					        trip_cox.cox_id == user_id
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub enum CoxHelpError {
 | 
					pub enum CoxHelpError {
 | 
				
			||||||
@@ -163,3 +206,8 @@ pub enum TripDeleteError {
 | 
				
			|||||||
    SomebodyAlreadyRegistered,
 | 
					    SomebodyAlreadyRegistered,
 | 
				
			||||||
    NotYourTrip,
 | 
					    NotYourTrip,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub enum TripUpdateError {
 | 
				
			||||||
 | 
					    NotYourTrip,
 | 
				
			||||||
 | 
					    TripDoesNotExist,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ use rocket::{
 | 
				
			|||||||
use sqlx::SqlitePool;
 | 
					use sqlx::SqlitePool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::model::{
 | 
					use crate::model::{
 | 
				
			||||||
    trip::{CoxHelpError, Trip, TripDeleteError},
 | 
					    trip::{CoxHelpError, Trip, TripDeleteError, TripUpdateError},
 | 
				
			||||||
    tripdetails::TripDetails,
 | 
					    tripdetails::TripDetails,
 | 
				
			||||||
    user::CoxUser,
 | 
					    user::CoxUser,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -36,7 +36,31 @@ async fn create(db: &State<SqlitePool>, data: Form<AddTripForm>, cox: CoxUser) -
 | 
				
			|||||||
    //TODO: fix clone()
 | 
					    //TODO: fix clone()
 | 
				
			||||||
    Trip::new_own(db, cox.id, trip_details_id).await;
 | 
					    Trip::new_own(db, cox.id, trip_details_id).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Flash::success(Redirect::to("/"), "Successfully planned the event")
 | 
					    Flash::success(Redirect::to("/"), "Ausfahrt erfolgreich erstellt.")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(FromForm)]
 | 
				
			||||||
 | 
					struct EditTripForm {
 | 
				
			||||||
 | 
					    max_people: i32,
 | 
				
			||||||
 | 
					    notes: Option<String>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[post("/trip/<trip_id>", data = "<data>")]
 | 
				
			||||||
 | 
					async fn update(
 | 
				
			||||||
 | 
					    db: &State<SqlitePool>,
 | 
				
			||||||
 | 
					    data: Form<EditTripForm>,
 | 
				
			||||||
 | 
					    trip_id: i64,
 | 
				
			||||||
 | 
					    cox: CoxUser,
 | 
				
			||||||
 | 
					) -> Flash<Redirect> {
 | 
				
			||||||
 | 
					    match Trip::update_own(db, cox.id, trip_id, data.max_people, data.notes.clone()).await {
 | 
				
			||||||
 | 
					        Ok(_) => Flash::success(Redirect::to("/"), "Ausfahrt erfolgreich aktualisiert."),
 | 
				
			||||||
 | 
					        Err(TripUpdateError::NotYourTrip) => {
 | 
				
			||||||
 | 
					            Flash::error(Redirect::to("/"), "Nicht deine Ausfahrt!")
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Err(TripUpdateError::TripDoesNotExist) => {
 | 
				
			||||||
 | 
					            Flash::error(Redirect::to("/"), "Ausfahrt gibt's nicht")
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[get("/join/<planned_event_id>")]
 | 
					#[get("/join/<planned_event_id>")]
 | 
				
			||||||
@@ -75,5 +99,5 @@ async fn remove(db: &State<SqlitePool>, planned_event_id: i64, cox: CoxUser) ->
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn routes() -> Vec<Route> {
 | 
					pub fn routes() -> Vec<Route> {
 | 
				
			||||||
    routes![create, join, remove, remove_trip]
 | 
					    routes![create, join, remove, remove_trip, update]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,10 +29,11 @@ async fn index(db: &State<SqlitePool>, user: User, flash: Option<FlashMessage<'_
 | 
				
			|||||||
        let end_of_year = NaiveDate::from_ymd_opt(Local::now().year(), 12, 31).unwrap();
 | 
					        let end_of_year = NaiveDate::from_ymd_opt(Local::now().year(), 12, 31).unwrap();
 | 
				
			||||||
        show_next_n_days = end_of_year
 | 
					        show_next_n_days = end_of_year
 | 
				
			||||||
            .signed_duration_since(Local::now().date_naive())
 | 
					            .signed_duration_since(Local::now().date_naive())
 | 
				
			||||||
            .num_days();
 | 
					            .num_days()
 | 
				
			||||||
 | 
					            + 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for i in 0..show_next_n_days + 1 {
 | 
					    for i in 0..show_next_n_days {
 | 
				
			||||||
        let date = (Local::now() + Duration::days(i)).date_naive();
 | 
					        let date = (Local::now() + Duration::days(i)).date_naive();
 | 
				
			||||||
        days.push(Day::new(db, date).await);
 | 
					        days.push(Day::new(db, date).await);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -180,23 +180,35 @@
 | 
				
			|||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
          <div class="px-2 pt-2" style="margin-top: 63px; margin-bottom: 157px">
 | 
					          <div class="px-2 pt-2" style="margin-top: 63px; margin-bottom: 157px">
 | 
				
			||||||
            {% if trip.max_people > 0 %}
 | 
					            {% if trip.max_people > 0 %}
 | 
				
			||||||
            <div class="text-primay-900 bg-primary-100 text-center p-1 mt-1 rounded-t-md">{{ trip.max_people }} - {{
 | 
							    <div class="text-primay-900 bg-primary-100 text-center p-1 mt-1 rounded-t-md">{{ trip.max_people }} - {{
 | 
				
			||||||
              trip.rower | length }} Ruderer können teilnehmen ({{ trip.max_people }})</div>
 | 
							      trip.rower | length }} Ruderer können teilnehmen ({{ trip.max_people }})</div>
 | 
				
			||||||
            <div class="p-2 border border-t-0 border-primary-100 mb-4 rounded-b-md">
 | 
							    <div class="p-2 border border-t-0 border-primary-100 mb-4 rounded-b-md">
 | 
				
			||||||
              {% if trip.rower | length > 0 %}
 | 
							      {% if trip.rower | length > 0 %}
 | 
				
			||||||
              {% for rower in trip.rower %}
 | 
							      {% for rower in trip.rower %}
 | 
				
			||||||
              {{ rower.name }} <span class="hidden">(angemeldet seit {{ rower.registered_at }})</span><br />
 | 
							      {{ rower.name }} <span class="hidden">(angemeldet seit {{ rower.registered_at }})</span><br />
 | 
				
			||||||
              {% endfor %}
 | 
							      {% endfor %}
 | 
				
			||||||
              {% else %}
 | 
							      {% else %}
 | 
				
			||||||
              Keine Ruderer angemeldet
 | 
							      Keine Ruderer angemeldet
 | 
				
			||||||
              <div class="text-right mt-2">
 | 
							      {% endif %}
 | 
				
			||||||
                <a href="/cox/remove/trip/{{ trip.id }}" class="inline-block btn btn-alert">
 | 
							    </div>
 | 
				
			||||||
                  {% include "includes/delete-icon" %}
 | 
							    {% if trip.cox_id == loggedin_user.id %}
 | 
				
			||||||
                  Termin löschen
 | 
								{% if trip.rower | length == 0 %}
 | 
				
			||||||
                </a>
 | 
								      <div class="text-right mt-2">
 | 
				
			||||||
              </div>
 | 
									<a href="/cox/remove/trip/{{ trip.id }}" class="inline-block btn btn-alert">
 | 
				
			||||||
              {% endif %}
 | 
									  {% include "includes/delete-icon" %}
 | 
				
			||||||
            </div>
 | 
									  Termin löschen
 | 
				
			||||||
 | 
									</a>
 | 
				
			||||||
 | 
								      </div>
 | 
				
			||||||
 | 
								{% endif %}
 | 
				
			||||||
 | 
								    <div>
 | 
				
			||||||
 | 
									<h3>Edit trip</h3>
 | 
				
			||||||
 | 
									<form action="/cox/trip/{{ trip.id }}" method="post">
 | 
				
			||||||
 | 
										Ruderer: <input type="number" name="max_people" required value="{{ trip.max_people }}" /><br />
 | 
				
			||||||
 | 
										Notes: <input type="text" name="notes" required value="{{ trip.notes }}" /><br />
 | 
				
			||||||
 | 
										<input type="submit" />
 | 
				
			||||||
 | 
									</form>
 | 
				
			||||||
 | 
								    </div>
 | 
				
			||||||
 | 
							    {% endif %}
 | 
				
			||||||
            {% endif %}
 | 
					            {% endif %}
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user