Skip to content

Commit

Permalink
feat: add vote model + display votes in table
Browse files Browse the repository at this point in the history
  • Loading branch information
JacksonVirgo committed Aug 3, 2024
1 parent 6359cfb commit 7dea228
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod logs;
pub mod players;
pub mod thread;
pub mod votes;
85 changes: 85 additions & 0 deletions src/models/votes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use crate::AppState;
use actix_web::web::Data;
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use sqlx::{self, postgres::PgQueryResult};

#[derive(Serialize, Deserialize, FromRow, Debug)]
pub struct Vote {
pub id: i32,
pub author: String,
pub target: String,
pub post_number: i32,
pub target_correction: Option<String>,

// FKs
pub thread_id: String,
pub player_id: i32,
}

pub enum VoteQuery {
Thread(String),
Player(i32),
}

pub async fn get_vote(state: &Data<AppState>, id: i32) -> Option<Vote> {
let db = &state.db;
match sqlx::query_as!(
Vote,
r#"SELECT id, author, target, post_number, target_correction, thread_id, player_id FROM votes WHERE id = $1"#,
id
)
.fetch_one(db)
.await
{
Ok(vote) => Some(vote),
_ => None,
}
}

pub async fn get_votes(state: &Data<AppState>, query: VoteQuery) -> Option<Vec<Vote>> {
let db = &state.db;
match query {
VoteQuery::Thread(thread_id) => match sqlx::query_as!(
Vote,
r#"SELECT id, author, target, post_number, target_correction, thread_id, player_id FROM votes WHERE thread_id = $1"#,
thread_id
)
.fetch_all(db)
.await
{
Ok(votes) => Some(votes),
_ => None,
},
VoteQuery::Player(player_id) => match sqlx::query_as!(
Vote,
r#"SELECT id, author, target, post_number, target_correction, thread_id, player_id FROM votes WHERE player_id = $1"#,
player_id
)
.fetch_all(db)
.await
{
Ok(votes) => Some(votes),
_ => None,
}
}
}

pub async fn create_vote(state: &Data<AppState>, vote: Vote) -> Option<PgQueryResult> {
let db = &state.db;
match sqlx::query!(
"INSERT INTO votes (author, target, post_number, target_correction, thread_id, player_id) VALUES ($1, $2, $3, $4, $5, $6)",
vote.author,
vote.target,
vote.post_number,
vote.target_correction,
vote.thread_id,
vote.player_id
)
.execute(db)
.await
{
Ok(query) => Some(query),
_ => None,
}
}
57 changes: 37 additions & 20 deletions src/routes/api/dashboard/vote_data.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,45 @@
use crate::{components::buttons::{gen_button, ButtonType, FormSubmitButton}, scraping::scraper, AppState};
use crate::{components::buttons::{gen_button, ButtonType, FormSubmitButton}, models::votes::get_votes, scraping::scraper, AppState};
use actix_web::{get, post, web::{self, Data}, HttpResponse, Responder};
use maud::{html, Markup};

struct TableRow {
author: String,
target: String,
corrected_target: String,
corrected_target: Option<String>,
post_number: i32,
validity: bool
validity: Option<bool>
}
fn format_table_row(row: TableRow) -> Markup {
html!({
tr."even:bg-zinc-600" {
td."px-4 py-2" { (row.author) }
td."px-4 py-2 border-l border-gray-200" { (row.target) }
td."px-4 py-2 border-l border-gray-200" { (row.corrected_target) }
td."px-4 py-2 border-l border-gray-200" {
(match row.corrected_target {
Some(corrected_target) => corrected_target,
None => "N/A".to_string()
})
}
td."px-4 py-2 border-l border-gray-200" { (row.post_number) }
td."px-4 py-2 border-l border-gray-200" { (row.validity) }
td."px-4 py-2 border-l border-gray-200" {
(match row.validity {
Some(validity) => if validity { "Yes" } else { "No" }.to_string(),
None => "N/A".to_string()
})
}
}
})
}

#[get("/votes/{thread_id}")]
async fn vote_data(_: Data<AppState>, path: web::Path<String>) -> impl Responder {
async fn vote_data(state: Data<AppState>, path: web::Path<String>) -> impl Responder {
let thread_id = path.into_inner();

let all_votes = match get_votes(&state, crate::models::votes::VoteQuery::Thread(thread_id.clone())).await {
Some(votes) => votes,
None => Vec::new()
};

HttpResponse::Ok().body(
html! {
div."w-full h-full flex flex-col p-4" id="vote-wrapper" {
Expand All @@ -46,20 +62,21 @@ async fn vote_data(_: Data<AppState>, path: web::Path<String>) -> impl Responder
}
}
tbody id="player-table-body" {
(format_table_row(TableRow {
author: "Bob Smith".to_string(),
target: "Jaen Doe".to_string(),
corrected_target: "Jane Doe".to_string(),
post_number: 1,
validity: true
}))
(format_table_row(TableRow {
author: "Deadpool".to_string(),
target: "Spiderman".to_string(),
corrected_target: "Spider-Man".to_string(),
post_number: 2,
validity: false
}))
@if all_votes.is_empty() {
tr."even:bg-zinc-600" {
td."px-4 py-2" { "No votes found" }
}
} else {
@for vote in all_votes {
(format_table_row(TableRow {
author: vote.author,
target: vote.target,
corrected_target: vote.target_correction,
post_number: vote.post_number,
validity: None
}))
}
}
}
}
}
Expand Down

0 comments on commit 7dea228

Please sign in to comment.