diff --git a/README.md b/README.md index 800fc5e..ac48cb6 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ vote and who we think wrote them and see some stats ! A list of things that could be implemented/added to the application, some of them are needed for "feature completeness" ! - - [ ] Being able to change from one week to the next - - [ ] Create new weeks for the admin + - [x] Being able to change from one week to the next + - [x] Create new weeks for the admin - [ ] Proper week redirection - [ ] Correctly handle non-existing week number - [x] Add introduction to the weekly truths diff --git a/src/main.rs b/src/main.rs index 6915128..655d9af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,7 +42,11 @@ async fn index(mut db: Connection) -> Redirect { fn rocket() -> _ { rocket::build() .mount("/", FileServer::from(relative!("static_files"))) - .mount("/", routes![index, vote::fetch_vote_data, vote::vote, truth::create_truth, truth::edit_truth, week::week, week::update_week, auth::login]) + .mount("/", routes![index, + vote::fetch_vote_data, vote::vote, + truth::create_truth, truth::edit_truth, + week::week, week::update_week, week::set_last_week, week::create_week, + auth::login]) .attach(database::stage()) .attach(Template::fairing()) } diff --git a/src/week.rs b/src/week.rs index cbc2e9e..6e6de1a 100644 --- a/src/week.rs +++ b/src/week.rs @@ -6,6 +6,7 @@ use rocket::response::Redirect; use rocket_db_pools::{sqlx, Connection}; use rocket_dyn_templates::{context, Template}; +use sqlx::{Acquire, Executor}; use crate::auth; use crate::auth::User; use crate::database::Db; @@ -114,3 +115,98 @@ pub async fn update_week(week: u8, raw_intro: Form, Redirect::to(uri!("/")) } + +#[post("//set_last")] +pub async fn set_last_week(week: u8, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { + let user = auth::get_user(week, &mut db, cookies).await; + if !user.is_admin { + cookies.add(("toast_error", "Vous n'avez pas la permission de changer la semaine.")); + return Redirect::to(uri!(week(week))); + } + + let add_error_cookie = || + cookies.add(("toast_error", "Erreur lors du changement d'état de la semaine.")); + + let db_transaction_connection = db.begin().await; + if db_transaction_connection.is_err() { + error!("Could not start database transaction for last week change : {:?}", db_transaction_connection.unwrap_err()); + add_error_cookie(); + return Redirect::to(uri!(week(week))); + } + let mut db_transaction = db_transaction_connection.unwrap(); + + // Remove the last flag from other weeks, if set. + match db_transaction.execute("UPDATE Weeks SET is_last_week = 0 WHERE is_last_week == 1;") + .await { + Ok(_) => debug!("Succesfully cleared is_last_week"), + Err(error) => { + error!("Failed to clear last week status : {error}"); + add_error_cookie(); + return Redirect::to(uri!(week(week))); + } + }; + + // We should set one week, if not there's something wrong : rollback. + if match sqlx::query("UPDATE Weeks SET is_last_week = 1 WHERE number == $1;") + .bind(week) + .execute(&mut *db_transaction) + .await { + Ok(result) => result.rows_affected(), + Err(error) => { + error!("Error while setting last week status : {error}"); + 0 + } + } == 1 { + db_transaction.commit().await.unwrap_or_else(|error| { + error!("Error while committing week is last transaction : {error}"); + add_error_cookie(); + }) + } else { + db_transaction.rollback().await.unwrap_or_else(|error| { + error!("Error while rolling back week is last transaction : {error}"); + add_error_cookie(); + }) + } + + Redirect::to(uri!(week(week))) +} + +#[get("//create")] +pub async fn create_week(week: u8, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { + let user = auth::get_user(week, &mut db, cookies).await; + if !user.is_admin { + cookies.add(("toast_error", "Vous n'avez pas la permission de changer la semaine.")); + return Redirect::to(uri!(week(week - 1))); + } + + let week_check: Result, sqlx::Error> = sqlx::query_scalar("SELECT number from Weeks WHERE number == $1;") + .bind(week) + .fetch_optional(&mut **db) + .await; + + if week_check.is_err() { + error!("Error while checking week existence : {:?}", week_check.unwrap_err()); + cookies.add(("toast_error", "Erreur en vérifiant que la semaine n'existe pas déjà")); + return Redirect::to(uri!(week(week - 1))); + } + + if week_check.unwrap().is_some() { + debug!("Week {week} already exists, not creating."); + return Redirect::to(uri!(week(week))); + } + + match sqlx::query("INSERT INTO Weeks (number, is_last_week, rendered_text, raw_text) VALUES ($1, 0, \"\", \"\");") + .bind(week) + .execute(&mut **db) + .await { + Ok(_) => { + debug!("Succesfully created new week {week}"); + Redirect::to(uri!(week(week))) + }, + Err(error) => { + error!("Error while creating new week {week} : {error}"); + cookies.add(("toast_error", "Erreur en créant la nouvelle selmaine.")); + Redirect::to(uri!(week(week - 1))) + } + } +} diff --git a/static_files/style.css b/static_files/style.css index 57eb5dc..f6cc018 100644 --- a/static_files/style.css +++ b/static_files/style.css @@ -47,6 +47,22 @@ top: 25%; } +.week_change:link, .week_change:visited { + color: black; + text-decoration: none; + transition: all .2s ease-in-out; +} + +.week_change:hover, .week_change:focus { + color: mediumpurple; + text-shadow: 0 2px 2px slategray; +} + +.week_change_hidden { + padding-left: 0.5eM; + padding-right: 0.5eM; +} + @media (orientation: portrait) { .truth_list { width: 60vw; diff --git a/templates/index.html.tera b/templates/index.html.tera index f3c3c42..cd11ae4 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -12,6 +12,30 @@ +{#{% import "week_change_arrows" as week_macro %}#} +{# For some reason the import does not work ? Figure it out at some point... #} +{%- macro display(display_character, to, enabled) -%} + {%- set class = "week_change" -%} + {%- if enabled == true %} + {% set target = ("href=/" ~ to) %} + {%- else -%} + {% set class = class ~ " week_change_hidden" -%} + {% set target = "" %} + {%- endif -%} + {%- if enabled == true -%}{{- display_character -}}{%- endif -%} +{%- endmacro display -%} + + +{% set back_arrow_enabled = week_data.number > 1 %} +{% set next_arrow_enabled = (week_data.is_last_week != true or user.is_admin == true) %} +{% set next_arrow_href = (week_data.number + 1) %} +{% if user.is_admin == true %} + {% set next_arrow_href = next_arrow_href ~ "/create" %} + {% set next_arrow_chara = '⥅' %} +{% else %} + {% set next_arrow_chara = '⟹' %} +{% endif %} +

{{ title }}

@@ -26,9 +50,18 @@ {% endif %}
-

Semaine {{ week_data.number }}

+

{{- self::display(display_character='⟸', to=(week_data.number - 1), enabled=back_arrow_enabled) }} + Semaine {{ week_data.number }} + {{- self::display(display_character=next_arrow_chara, to=next_arrow_href, enabled=next_arrow_enabled) -}}

+ {% if user.is_admin == true and week_data.is_last_week != true %} +
+ +
+ {% endif %}
{{ week_data.rendered_text | safe }} {%- if user.is_admin == true -%}