Skip to content

Commit

Permalink
feat: add player table
Browse files Browse the repository at this point in the history
  • Loading branch information
JacksonVirgo committed Jul 26, 2024
1 parent 28c0658 commit 1310a13
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 25 deletions.
19 changes: 19 additions & 0 deletions migrations/0001_initial.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,22 @@ CREATE TABLE IF NOT EXISTS logs (
message TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
);

DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'alignment') THEN
EXECUTE 'CREATE TYPE alignment AS ENUM (''Town'', ''Mafia'', ''Werewolf'', ''Cult'', ''SelfAlignedKilling'', ''SelfAlignedOther'', ''Unknown'')';
END IF;
END
$$;

CREATE TABLE IF NOT EXISTS players (
id SERIAL PRIMARY KEY,
name VARCHAR(32) NOT NULL,
alignment alignment,
role VARCHAR(128),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
thread_id VARCHAR(32) NOT NULL,
FOREIGN KEY (thread_id) REFERENCES threads(thread_id) ON DELETE CASCADE
);

1 change: 1 addition & 0 deletions src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod logs;
pub mod players;
pub mod thread;
74 changes: 74 additions & 0 deletions src/models/players.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use crate::AppState;
use actix_web::web::Data;
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
use sqlx::{self, FromRow};

#[derive(Debug, Clone, Serialize, Deserialize, sqlx::Type)]
pub enum PlayerAlignment {
Town,
Mafia,
Werewolf,
Cult,
SelfAlignedKilling,
SelfAlignedOther,
Unknown,
}

// Convert to String
impl ToString for PlayerAlignment {
fn to_string(&self) -> String {
match self {
PlayerAlignment::Town => "Town",
PlayerAlignment::Mafia => "Mafia",
PlayerAlignment::Werewolf => "Werewolf",
PlayerAlignment::Cult => "Cult",
PlayerAlignment::SelfAlignedKilling => "Self-Aligned (Killing)",
PlayerAlignment::SelfAlignedOther => "Self-Aligned (Other)",
PlayerAlignment::Unknown => "Unknown",
}
.to_string()
}
}

// Convert from String
impl From<String> for PlayerAlignment {
fn from(s: String) -> Self {
match s.as_str() {
"Town" => PlayerAlignment::Town,
"Mafia" => PlayerAlignment::Mafia,
"Werewolf" => PlayerAlignment::Werewolf,
"Cult" => PlayerAlignment::Cult,
"Self-Aligned (Killing)" => PlayerAlignment::SelfAlignedKilling,
"Self-Aligned (Other)" => PlayerAlignment::SelfAlignedOther,
_ => PlayerAlignment::Unknown,
}
}
}

#[derive(Serialize, Deserialize, FromRow, Debug)]
pub struct Player {
pub id: i32,
pub name: String,
pub role: Option<String>,
pub created_at: Option<NaiveDateTime>,
pub alignment: Option<PlayerAlignment>,

// FKs
pub thread_id: Option<String>,
}

pub async fn get_players(app_state: &Data<AppState>, thread_id: &str) -> Option<Vec<Player>> {
let db = &app_state.db;
match sqlx::query_as!(
Player,
r#"SELECT id, name, alignment as "alignment: PlayerAlignment", role, created_at, thread_id FROM players WHERE thread_id = $1"#,
thread_id
)
.fetch_all(db)
.await
{
Ok(thread) => Some(thread),
_ => None,
}
}
85 changes: 60 additions & 25 deletions src/routes/api/dashboard/player_data.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
use crate::components::{
buttons::{gen_button, ButtonType, FormSubmitButton},
forms::input::select_menu::SelectMenuBuilder,
use crate::{
components::{
buttons::{gen_button, ButtonType, FormSubmitButton},
forms::input::select_menu::SelectMenuBuilder,
},
models::players::get_players,
AppState,
};
use actix_web::{
get,
web::{self, Data},
HttpResponse, Responder,
};
use actix_web::{get, HttpResponse, Responder};
use maud::{html, Markup};

struct TableRow {
Expand All @@ -22,8 +30,44 @@ fn format_table_row(row: TableRow) -> Markup {
})
}

#[get("/players")]
async fn player_data() -> impl Responder {
#[get("/players/{thread_id}")]
async fn player_data(state: Data<AppState>, raw_thread_id: web::Path<String>) -> impl Responder {
let raw_thread_id = raw_thread_id.into_inner();
let thread_id = match raw_thread_id.parse::<String>() {
Ok(id) => id,
Err(_) => {
return HttpResponse::Found()
.insert_header(("HX-Location", format!("/")))
.finish();
}
};

let players = match get_players(&state, &thread_id).await {
Some(thread) => thread,
None => {
return HttpResponse::Found()
.insert_header(("HX-Location", format!("/")))
.finish();
}
};

let player_rows: Vec<Markup> = players
.iter()
.map(|p| {
format_table_row(TableRow {
name: p.name.clone(),
alignment: match p.alignment.clone() {
Some(a) => a.to_string(),
None => "Not Set".to_string(),
},
role: p.role.clone().unwrap_or("None".to_string()),
replacements: p.role.clone().unwrap_or("None".to_string()),
})
})
.collect();

let player_row_count = player_rows.len();

let game_queue = SelectMenuBuilder::new()
.name("game_queue")
.placeholder("Select the game queue")
Expand Down Expand Up @@ -51,7 +95,8 @@ async fn player_data() -> impl Responder {
text: "Save".to_string(),
})))
}
table."min-w-full bg-zinc-700 text-white" {
div."min-w-full" {
table."w-full bg-zinc-700 text-white" {
thead {
tr {
th."px-4 py-2 border-gray-200 bg-zinc-800" { "Player Name" }
Expand All @@ -61,26 +106,16 @@ async fn player_data() -> impl Responder {
}
}
tbody id="player-table-body" {
(format_table_row(TableRow {
name: "Player 1".to_string(),
alignment: "Town".to_string(),
role: "Cop".to_string(),
replacements: "None".to_string(),
}))
(format_table_row(TableRow {
name: "Player 2".to_string(),
alignment: "Mafia".to_string(),
role: "Goon".to_string(),
replacements: "Player 4".to_string(),
}))
(format_table_row(TableRow {
name: "Player 3".to_string(),
alignment: "Town".to_string(),
role: "Cop".to_string(),
replacements: "None".to_string(),
}))
@for row in player_rows {
(row)
}
}
}
@if player_row_count == 0 {
div."bg-zinc-700 w-full" {
div."px-4 py-2 text-center w-full"{ "No players found" }
}
}}
}
}
.into_string(),
Expand Down

0 comments on commit 1310a13

Please sign in to comment.