From 67ce54e992dd94d397c81b029aee299691434286 Mon Sep 17 00:00:00 2001 From: trotFunky Date: Tue, 23 Jul 2024 21:51:51 +0100 Subject: [PATCH 01/43] v1.1: Add weekly introductions - Create a new migration adding a Weeks table, allowing for new weekly introductions and paving the way for multiple week handling. - Add route to update the weekly introduction - Move the week rendering to a specific week file - Update the templates to use the week number from the week data - Update templates to render and edit weekly introductions --- Cargo.lock | 2 +- Cargo.toml | 2 +- db/03_create-week-table.sql | 10 +++ src/auth.rs | 1 - src/database_records.rs | 9 +++ src/main.rs | 69 +++--------------- src/vote.rs | 1 - src/week.rs | 116 +++++++++++++++++++++++++++++++ static_files/style.css | 2 +- templates/editable_truth.tera | 2 +- templates/index.html.tera | 20 +++++- templates/truth_editor.html.tera | 2 +- 12 files changed, 165 insertions(+), 71 deletions(-) create mode 100644 db/03_create-week-table.sql create mode 100644 src/week.rs diff --git a/Cargo.lock b/Cargo.lock index ae3db85..14afd09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -578,7 +578,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fabula_votes_server" -version = "1.0.0" +version = "1.1.0" dependencies = [ "argon2", "blake2", diff --git a/Cargo.toml b/Cargo.toml index 27aca85..57936af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "fabula_votes_server" license = "MPL-2.0" readme = "README.md" authors = ["trotFunky"] -version = "1.0.0" +version = "1.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/db/03_create-week-table.sql b/db/03_create-week-table.sql new file mode 100644 index 0000000..1b24dd7 --- /dev/null +++ b/db/03_create-week-table.sql @@ -0,0 +1,10 @@ +CREATE TABLE IF NOT EXISTS Weeks ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + number INTEGER NOT NULL CHECK (number > 0), + is_last_week INTEGER NOT NULL, + rendered_text VARCHAR NOT NULL, + raw_text VARCHAR NOT NULL +); + +-- This is to upgrade from version 1.0 to 1.1 with an existing database +INSERT INTO Weeks (number, is_last_week, rendered_text, raw_text) VALUES (1, 1, "", ""); diff --git a/src/auth.rs b/src/auth.rs index 4b9df6c..1902291 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -8,7 +8,6 @@ use std::time::{SystemTime, UNIX_EPOCH}; use argon2::{Argon2, PasswordHash, PasswordVerifier}; use blake2::{Blake2b512, Digest}; use blake2::digest::FixedOutput; -use sqlx::Error; use crate::database_records::{AuthTokens, PlayerLoginInfo, Vote}; use crate::database; use database::Db; diff --git a/src/database_records.rs b/src/database_records.rs index 89c116a..b647a2c 100644 --- a/src/database_records.rs +++ b/src/database_records.rs @@ -58,3 +58,12 @@ pub struct VotingData { pub struct AuthTokens { pub token: String, } + +#[derive(sqlx::FromRow, Deserialize, Serialize)] +#[serde(crate = "rocket::serde")] +pub struct Week { + pub number: u8, + pub is_last_week: bool, + pub rendered_text: String, + pub raw_text: String, +} diff --git a/src/main.rs b/src/main.rs index 60bfd1f..da44b02 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,76 +9,23 @@ use rocket::serde::{Serialize, Deserialize, json::Json}; use rocket_dyn_templates::{Template, context}; use rocket_db_pools::{sqlx, sqlx::Row, Database, Connection}; +use sqlx::Error; -mod database_records; mod auth; -mod vote; mod truth; +mod vote; +mod week; + mod database; +mod database_records; use database::Db; use database_records::*; use auth::User; -#[get("/")] -async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<'_>) -> Template { - let user: User = auth::get_user(week_number, &mut db, cookies).await; - - let other_players = if user.logged_in { - match sqlx::query_as("SELECT id, name FROM Players WHERE id <> $1 AND is_admin == 0 ORDER BY name") - .bind(user.id) - .fetch_all(&mut **db).await { - Ok(v) => v, - Err(error) => { - println!("Some error while getting players : {error}"); - Vec::::new() - } - } - } else { - Vec::::new() - }; - - // FIXME : This is fucking *trash* but fucking hell mate - if user.is_admin { - let truths: Vec = match sqlx::query_as("SELECT * FROM Truths WHERE week == $1 ORDER BY number") - .bind(week_number) - .fetch_all(&mut **db).await { - Ok(v) => v, - Err(error) => { - error!("Error while getting truths : {error}"); - Vec::::new() - } - }; - - Template::render("index", context! { - week_number: week_number, - truths: truths, - user: user, - other_players: other_players, - }) - } else { - let truths: Vec = match sqlx::query_as("SELECT id, number, author_id, rendered_text FROM Truths WHERE week == $1 ORDER BY number") - .bind(week_number) - .fetch_all(&mut **db).await { - Ok(v) => v, - Err(error) => { - error!("Error while getting truths : {error}"); - Vec::::new() - } - }; - - Template::render("index", context! { - week_number: week_number, - truths: truths, - user: user, - other_players: other_players, - }) - } -} - #[get("/")] async fn index(mut db: Connection) -> Redirect { - let current_week: u8 = match sqlx::query("SELECT max(week) AS last_week FROM Truths;") + let current_week: u8 = match sqlx::query("SELECT number FROM Weeks WHERE is_last_week == 1;") .fetch_one(&mut **db).await { Ok(v) => v.try_get(0).ok().unwrap_or_else(|| 1), // If error, go back to 1 Err(error) => { @@ -87,14 +34,14 @@ async fn index(mut db: Connection) -> Redirect { } }; - Redirect::to(uri!("/", week(week_number = if current_week == 0 {1} else {current_week}))) + Redirect::to(uri!(week::week(week_number = if current_week == 0 {1} else {current_week}))) } #[launch] 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, auth::login]) + .mount("/", routes![index, vote::fetch_vote_data, vote::vote, truth::create_truth, truth::edit_truth, week::week, week::update_week, auth::login]) .attach(database::stage()) .attach(Template::fairing()) } diff --git a/src/vote.rs b/src/vote.rs index e5426df..395c06c 100644 --- a/src/vote.rs +++ b/src/vote.rs @@ -10,7 +10,6 @@ use rocket::serde::json::Json; use rocket_db_pools::{sqlx, Connection}; use crate::{auth, database}; -use crate::database::Db; use crate::database_records::{Vote, VotingData}; #[derive(FromForm)] diff --git a/src/week.rs b/src/week.rs new file mode 100644 index 0000000..cbc2e9e --- /dev/null +++ b/src/week.rs @@ -0,0 +1,116 @@ +use pulldown_cmark::{Options, Parser}; +use rocket::fairing::AdHoc; +use rocket::form::Form; +use rocket::http::CookieJar; +use rocket::response::Redirect; + +use rocket_db_pools::{sqlx, Connection}; +use rocket_dyn_templates::{context, Template}; +use crate::auth; +use crate::auth::User; +use crate::database::Db; +use crate::database_records::{DisplayTruth, Player, Truth, Week}; + +#[get("/")] +pub async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<'_>) -> Template { + let user: User = auth::get_user(week_number, &mut db, cookies).await; + + let other_players = if user.logged_in { + match sqlx::query_as("SELECT id, name FROM Players WHERE id <> $1 AND is_admin == 0 ORDER BY name") + .bind(user.id) + .fetch_all(&mut **db).await { + Ok(v) => v, + Err(error) => { + println!("Some error while getting players : {error}"); + Vec::::new() + } + } + } else { + Vec::::new() + }; + + let week_data: Week = match sqlx::query_as("SELECT number, is_last_week, rendered_text, raw_text FROM Weeks WHERE number == $1") + .bind(week_number) + .fetch_one(&mut **db) + .await { + Ok(week) => week, + Err(error) => { + error!("Error while retrieving week data : {error}"); + Week {number: 0, is_last_week: true, rendered_text: "".to_string(), raw_text: "".to_string() } + } + }; + + // FIXME : This is fucking *trash* but fucking hell mate + if user.is_admin { + let truths: Vec = match sqlx::query_as("SELECT * FROM Truths WHERE week == $1 ORDER BY number") + .bind(week_number) + .fetch_all(&mut **db).await { + Ok(v) => v, + Err(error) => { + error!("Error while getting truths : {error}"); + Vec::::new() + } + }; + + Template::render("index", context! { + week_data: week_data, + truths: truths, + user: user, + other_players: other_players, + }) + } else { + let truths: Vec = match sqlx::query_as("SELECT id, number, author_id, rendered_text FROM Truths WHERE week == $1 ORDER BY number") + .bind(week_number) + .fetch_all(&mut **db).await { + Ok(v) => v, + Err(error) => { + error!("Error while getting truths : {error}"); + Vec::::new() + } + }; + + Template::render("index", context! { + week_data: week_data, + truths: truths, + user: user, + other_players: other_players, + }) + } +} + +#[post("//edit", data="")] +pub async fn update_week(week: u8, raw_intro: Form, + 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!("/")); + } + + let mut options = Options::empty(); + options.insert(Options::ENABLE_STRIKETHROUGH); + options.insert(Options::ENABLE_FOOTNOTES); + options.insert(Options::ENABLE_MATH); + options.insert(Options::ENABLE_TABLES); + let markdown_parser = Parser::new_ext(raw_intro.as_str(), options); + + let mut rendered_markdown = String::new(); + pulldown_cmark::html::push_html(&mut rendered_markdown, markdown_parser); + + match sqlx::query("UPDATE Weeks SET raw_text = $1, rendered_text = $2 WHERE number == $3;") + .bind(&raw_intro.as_str()) + .bind(rendered_markdown) + .bind(week) + .fetch_optional(&mut **db) + .await { + Ok(_) => { + debug!("Week successfully updated") + } + Err(error) => { + error!("Error while updating week {week} data : {error}"); + cookies.add(("toast_error", "Il y a eu un problème lors du changement de la semaine")); + } + }; + + Redirect::to(uri!("/")) +} diff --git a/static_files/style.css b/static_files/style.css index 7482b04..3de7065 100644 --- a/static_files/style.css +++ b/static_files/style.css @@ -23,7 +23,7 @@ padding-bottom: 2em; } -.truth_editor { +.editor { width: 100%; height: 6eM; font-size: large; diff --git a/templates/editable_truth.tera b/templates/editable_truth.tera index 0b94cb6..22d3470 100644 --- a/templates/editable_truth.tera +++ b/templates/editable_truth.tera @@ -2,7 +2,7 @@

Vérité {{ truth.number }}

{{ truth.rendered_text | safe }}


-
+ {% include "truth_editor" %}
diff --git a/templates/index.html.tera b/templates/index.html.tera index 851acce..ae99a96 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -33,11 +33,25 @@ {% endif %} -

Semaine {{ week_number }}

+

Semaine {{ week_data.number }}

+
+ {{ week_data.rendered_text | safe }} + {%- if user.is_admin == true -%} +
+
+ + +
+ {% endif %} +
{% if user.logged_in == true and user.is_admin == false %} -
+ {% endif %} {# Truths start at 1 but the array starts at 0 #} @@ -77,7 +91,7 @@ {% if user.is_admin == true %}

Nouvelle vérité

- + {% include "truth_editor" %}
diff --git a/templates/truth_editor.html.tera b/templates/truth_editor.html.tera index 894dac4..615ed3e 100644 --- a/templates/truth_editor.html.tera +++ b/templates/truth_editor.html.tera @@ -1,4 +1,4 @@ - - - - {% endif %} -
- {% if user.logged_in == true and user.is_admin == false and not lock_truth_form %} -
- {% endif %} - - {# Truths start at 1 but the array starts at 0 #} - {% set index_delta = 1 %} - {% for truth in truths %} - {# - The truths are in an ordered array, but one of them might be the user's. - In this case, we need to stop the array index from incrementing if the current - truth is the user's, as they cannot have voted for themselves, leading to one - less votes than there are truths. - #} - {%- if truth.author_id == user.id -%} - {%- set_global index_delta = 2 -%} - {% endif %} - {% set truth_index = truth.number - index_delta %} - - {% if user.is_admin == true %} - {% include "weeks/editable_truth" %} - {% else %} - {% include "weeks/truth" %} - {% endif %} - {% endfor %} - - {% if user.logged_in == true and user.is_admin == false and not lock_truth_form %} -
- -
- {% endif %} - - {# If admin, show an additional box for creating a new Truth. #} - {% if user.is_admin == true %} -
-

Nouvelle vérité

-
- {% include "weeks/truth_editor" %} -
-
- {% endif %} -
- -
-
- -
-
- - - - diff --git a/templates/weeks/index.html.tera b/templates/weeks/index.html.tera new file mode 100644 index 0000000..ddf8c70 --- /dev/null +++ b/templates/weeks/index.html.tera @@ -0,0 +1,120 @@ +{% extends "base_page" %} + +{% block scripts %} + {% if user.logged_in == true and not user.is_admin %} + + {% endif %} + + +{% endblock %} + +{#{% 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 -%} + +{# Remove the form if all votes are locked, to reduce confusion. #} +{% set lock_truth_form = user.votes | length + 1 == truths | length and week_data.is_last_week != true %} + +{% block body %} + + {# Apparently needs to be inside the block ? #} + {% 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 %} + +

{{- 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 -%} +
+
+ + +
+ {% endif %} +
+ {% if user.logged_in == true and user.is_admin == false and not lock_truth_form %} +
+ {% endif %} + + {# Truths start at 1 but the array starts at 0 #} + {% set index_delta = 1 %} + {% for truth in truths %} + {# + The truths are in an ordered array, but one of them might be the user's. + In this case, we need to stop the array index from incrementing if the current + truth is the user's, as they cannot have voted for themselves, leading to one + less votes than there are truths. + #} + {%- if truth.author_id == user.id -%} + {%- set_global index_delta = 2 -%} + {% endif %} + {% set truth_index = truth.number - index_delta %} + + {% if user.is_admin == true %} + {% include "weeks/editable_truth" %} + {% else %} + {% include "weeks/truth" %} + {% endif %} + {% endfor %} + + {% if user.logged_in == true and user.is_admin == false and not lock_truth_form %} +
+ +
+ {% endif %} + + {# If admin, show an additional box for creating a new Truth. #} + {% if user.is_admin == true %} +
+

Nouvelle vérité

+
+ {% include "weeks/truth_editor" %} +
+
+ {% endif %} +
+ +
+
+ +
+
+
+{% endblock %} From 1419bb6d51a0e1c3e2dd623b954b15b4c0d9b324 Mon Sep 17 00:00:00 2001 From: trotFunky Date: Sat, 27 Jul 2024 23:20:20 +0100 Subject: [PATCH 31/43] tempates/base: Change language, update title Now that we have the name of the world, we can show it in the title. The base I used supposed an english language page, which is incorrect here. Set language as French. --- templates/base_page.html.tera | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/base_page.html.tera b/templates/base_page.html.tera index 42f0895..f56242b 100644 --- a/templates/base_page.html.tera +++ b/templates/base_page.html.tera @@ -1,6 +1,6 @@ - -{% set title = "Vérités Fabula Ultima" %} + +{% set title = "Vérités Nova Borealis" %} {{ title }} From 1b4a934398c355fffe22a13ac00ca73b11063797 Mon Sep 17 00:00:00 2001 From: trotFunky Date: Sun, 28 Jul 2024 14:36:52 +0100 Subject: [PATCH 32/43] auth: Split off vote data from the user Now that the application is going to have multiple pages, vote data makes no sense to keep with the user. The user struct will be used everywhere to check for authentication, which is not the case for previous votes. Create a new struct and function in src/vote.rs to retrieve existing votes and use them in places where user.votes was used previously. Remove vote-related code from src/auth.rs and the week number dependence that it required. --- README.md | 1 + src/auth.rs | 23 ++--------------------- src/truth.rs | 4 ++-- src/vote.rs | 31 ++++++++++++++++++++++++++++--- src/week.rs | 15 ++++++++++----- templates/weeks/index.html.tera | 4 ++-- templates/weeks/truth.html.tera | 4 ++-- 7 files changed, 47 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index e289d5b..949ac31 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ A list of things that could be implemented/added to the application, some of the - [x] Use fairings for the different elements - [ ] Use guards for User calls ? - [ ] Use SQLite Row ID for User IDs rather than regular IDs, for randomness ? + - [x] Split user from vote data # Dependencies diff --git a/src/auth.rs b/src/auth.rs index 34c0bec..672b79d 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -9,7 +9,7 @@ use argon2::{Argon2, PasswordHash, PasswordVerifier}; use blake2::{Blake2b512, Digest}; use blake2::digest::FixedOutput; use rocket::fairing::AdHoc; -use crate::database_records::{AuthTokens, PlayerLoginInfo, Vote}; +use crate::database_records::{AuthTokens, PlayerLoginInfo}; use crate::{database, week}; use database::Db; @@ -21,11 +21,9 @@ pub struct User { pub is_admin: bool, pub id: u16, pub name: String, - pub has_week_vote: bool, - pub votes: Vec } -pub async fn get_user(week: u8, db: &mut Connection, cookies: &CookieJar<'_>) -> User { +pub async fn get_user(db: &mut Connection, cookies: &CookieJar<'_>) -> User { let auth_token: Option = match cookies.get_private("auth_token") { Some(cookie) => Some(cookie.value().to_string()), None => None @@ -87,27 +85,12 @@ pub async fn get_user(week: u8, db: &mut Connection, cookies: &CookieJar<'_> (String::new(), false) }; - // TODO: Move to src/vote.rs - let votes: Vec = if logged_in && !is_admin { - sqlx::query_as("SELECT Votes.* FROM Votes JOIN Truths ON Votes.truth_id == Truths.id AND Truths.week == $1 WHERE voter_id == $2 ORDER BY Truths.number;") - .bind(week) - .bind(&id_str) - .fetch_all(&mut ***db).await.unwrap_or_else(|error| { - error!("Error while getting votes : {error}"); - Vec::::new() - }) - } else { - Vec::::new() - }; - if logged_in { User { logged_in, is_admin, id: id_str.parse::().unwrap(), name, - has_week_vote: if votes.is_empty() { false } else { true }, - votes } } else { User { @@ -115,8 +98,6 @@ pub async fn get_user(week: u8, db: &mut Connection, cookies: &CookieJar<'_> is_admin: false, id: 0, name, - has_week_vote: false, - votes } } } diff --git a/src/truth.rs b/src/truth.rs index b9df46a..f3b6add 100644 --- a/src/truth.rs +++ b/src/truth.rs @@ -18,7 +18,7 @@ pub struct TruthUpdateForm { #[post("//edit/", data="
")] pub async fn edit_truth(week: u8, truth_number: u8, form: Form, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { - let user = auth::get_user(week, &mut db, cookies).await; + let user = auth::get_user(&mut db, cookies).await; if !user.is_admin { cookies.add(("toast_error", "Vous n'avez pas la permission de changer la vérité.")); return Redirect::to(uri!(week::week(week))); @@ -57,7 +57,7 @@ pub async fn edit_truth(week: u8, truth_number: u8, form: Form, #[post("//new_truth", data="")] pub async fn create_truth(week: u8, form: Form, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { - let user = auth::get_user(week, &mut db, cookies).await; + let user = auth::get_user(&mut db, cookies).await; if !user.is_admin { cookies.add(("toast_error", "Vous n'avez pas la permission d'ajouter de vérité.")); return Redirect::to(uri!(week::week(week))); diff --git a/src/vote.rs b/src/vote.rs index ff1e555..550707c 100644 --- a/src/vote.rs +++ b/src/vote.rs @@ -12,6 +12,29 @@ use rocket_db_pools::{sqlx, Connection}; use crate::{auth, database, week}; use crate::database_records::{Vote, VotingData}; +#[derive(Serialize, Deserialize)] +#[serde(crate = "rocket::serde")] +pub struct WeeklyUserVotes { + pub has_week_vote: bool, + pub votes: Vec +} + +pub async fn get_weekly_user_votes(week: u8, user: &auth::User, db: &mut Connection) -> WeeklyUserVotes { + let votes: Vec = if user.logged_in && !user.is_admin { + sqlx::query_as("SELECT Votes.* FROM Votes JOIN Truths ON Votes.truth_id == Truths.id AND Truths.week == $1 WHERE voter_id == $2 ORDER BY Truths.number;") + .bind(week) + .bind(user.id) + .fetch_all(&mut ***db).await.unwrap_or_else(|error| { + error!("Error while getting votes : {error}"); + Vec::::new() + }) + } else { + Vec::::new() + }; + + WeeklyUserVotes {has_week_vote: if votes.is_empty() { false } else { true }, votes} +} + #[derive(FromForm)] pub struct VoteForm { truth_votes: HashMap @@ -20,7 +43,7 @@ pub struct VoteForm { #[post("//vote", data="")] pub async fn vote(week: u8, form: Form, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { - let user = auth::get_user(week, &mut db, cookies).await; + let user = auth::get_user(&mut db, cookies).await; if !user.logged_in { cookies.add(("toast_error", "Vous n'avez pas la permission de changer de vote.")); @@ -37,9 +60,11 @@ pub async fn vote(week: u8, form: Form, } ); + let existing_votes = get_weekly_user_votes(week, &user, &mut db).await; + let mut had_error = false; for (truth_id, voted_id) in filtered_votes { - match user.votes.iter().find(|vote: &&Vote| {vote.truth_id == *truth_id}) { + match existing_votes.votes.iter().find(|vote: &&Vote| {vote.truth_id == *truth_id}) { Some(vote) => { if *voted_id == vote.voted_id { continue; @@ -97,7 +122,7 @@ pub struct VoteData { // TODO: Cache vote count ? Maintain in state ? #[get("//votes", format = "application/json")] pub async fn fetch_vote_data(week: u8, mut db: Connection, cookies: &CookieJar<'_>) -> Option> { - let user = auth::get_user(week, &mut db, cookies).await; + let user = auth::get_user(&mut db, cookies).await; let raw_votes: Vec = sqlx::query_as(" SELECT Players.name as votes_for, Truths.number as truth_number, count(*) as votes FROM Votes JOIN Players ON Votes.voted_id == Players.id diff --git a/src/week.rs b/src/week.rs index 5168b1c..06bbbb6 100644 --- a/src/week.rs +++ b/src/week.rs @@ -7,14 +7,15 @@ 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, vote}; use crate::auth::User; use crate::database::Db; use crate::database_records::{DisplayTruth, Player, Truth, Week}; +use crate::vote::WeeklyUserVotes; #[get("/")] pub async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<'_>) -> Template { - let user: User = auth::get_user(week_number, &mut db, cookies).await; + let user: User = auth::get_user(&mut db, cookies).await; let other_players = if user.logged_in { match sqlx::query_as("SELECT id, name FROM Players WHERE id <> $1 AND is_admin == 0 ORDER BY name") @@ -41,6 +42,8 @@ pub async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<' } }; + let vote_data: WeeklyUserVotes = vote::get_weekly_user_votes(week_number,&user, &mut db).await; + // FIXME : This is fucking *trash* but fucking hell mate if user.is_admin { let truths: Vec = match sqlx::query_as("SELECT * FROM Truths WHERE week == $1 ORDER BY number") @@ -58,6 +61,7 @@ pub async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<' truths: truths, user: user, other_players: other_players, + vote_data: vote_data }) } else { let truths: Vec = match sqlx::query_as("SELECT id, number, author_id, rendered_text FROM Truths WHERE week == $1 ORDER BY number") @@ -75,6 +79,7 @@ pub async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<' truths: truths, user: user, other_players: other_players, + vote_data: vote_data }) } } @@ -82,7 +87,7 @@ pub async fn week(week_number: u8, mut db: Connection, cookies: &CookieJar<' #[post("//edit", data="")] pub async fn update_week(week: u8, raw_intro: Form, mut db: Connection, cookies: &CookieJar<'_>) -> Redirect { - let user = auth::get_user(week, &mut db, cookies).await; + let user = auth::get_user(&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))); @@ -118,7 +123,7 @@ pub async fn update_week(week: u8, raw_intro: Form, #[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; + let user = auth::get_user(&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))); @@ -173,7 +178,7 @@ pub async fn set_last_week(week: u8, mut db: Connection, cookies: &CookieJar #[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; + let user = auth::get_user(&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))); diff --git a/templates/weeks/index.html.tera b/templates/weeks/index.html.tera index ddf8c70..b3527d5 100644 --- a/templates/weeks/index.html.tera +++ b/templates/weeks/index.html.tera @@ -22,7 +22,7 @@ {%- endmacro display -%} {# Remove the form if all votes are locked, to reduce confusion. #} -{% set lock_truth_form = user.votes | length + 1 == truths | length and week_data.is_last_week != true %} +{% set lock_truth_form = vote_data.votes | length + 1 == truths | length and week_data.is_last_week != true %} {% block body %} @@ -91,7 +91,7 @@ {% if user.logged_in == true and user.is_admin == false and not lock_truth_form %}
- - {% else %} - - {% endif %} +
+

{{ title }}

+ +
+
+ {% block top_bar_side %} +
+ {% if user.logged_in == true %} + + {% else %} + + {% endif %} +
+ {% endblock %} +
{% endblock %} diff --git a/templates/tags/filtered_truths.html.tera b/templates/tags/filtered_truths.html.tera new file mode 100644 index 0000000..ad2ffb9 --- /dev/null +++ b/templates/tags/filtered_truths.html.tera @@ -0,0 +1,28 @@ +{% extends "base_page" %} + +{% block top_bar_side %} +{% endblock %} + +{% block body %} + {% if tags | length == 0 %} +

Ensemble des vérités à ce jour

+ {% elif tags | length == 1 %} +

Vérités correponsdantes au thème

+ {% else %} +

Vérités correponsdantes aux thèmes

+ {% endif %} + +
+ {% for tag in tags %} + {{ tag.name }} + {% endfor %} +
+ + {% for truth in truths %} +
+

Semaine {{ truth.week }} - Vérité {{ truth.number }}

+

{{ truth.rendered_text | safe }}

+
+ {% endfor %} +{% endblock %} diff --git a/templates/tags/index.html.tera b/templates/tags/index.html.tera new file mode 100644 index 0000000..5e423d4 --- /dev/null +++ b/templates/tags/index.html.tera @@ -0,0 +1,42 @@ +{% extends "base_page" %} + +{% block top_bar_side %} +{% endblock %} + +{% block body %} +

Liste des thèmes de Vérité

+ +
+ {% for tag in tags %} +
+ +
+ {% endfor %} +
+ + + {% if user.is_admin %} +
+ +

Éditer les thèmes

+ +
+ {% for tag in tags %} +
+ + + + +
+ {% endfor %} +
+ +
+
+ + +
+ +
+ {% endif %} +{% endblock %} diff --git a/templates/weeks/editable_truth.tera b/templates/weeks/editable_truth.tera index 501302a..3c2c968 100644 --- a/templates/weeks/editable_truth.tera +++ b/templates/weeks/editable_truth.tera @@ -1,8 +1,30 @@

Vérité {{ truth.number }}

{{ truth.rendered_text | safe }}

+
+ {% for tag in truth.tags %} +
+ +
+ + {{ tag.name }} + + {% endfor %} +

-
+ {% include "weeks/truth_editor" %}
+
+ + +
diff --git a/templates/weeks/truth.html.tera b/templates/weeks/truth.html.tera index ca52998..5a420e6 100644 --- a/templates/weeks/truth.html.tera +++ b/templates/weeks/truth.html.tera @@ -7,6 +7,12 @@

Vérité {{ truth.number }}

{{ truth.rendered_text | safe }}

+
+
+ {% for tag in truth.tags %} + {{ tag.name }} + {% endfor %} +
{% if user.logged_in %}