Skip to content

Commit

Permalink
feat: add basic pagination to vote table
Browse files Browse the repository at this point in the history
  • Loading branch information
JacksonVirgo committed Aug 4, 2024
1 parent a517555 commit 41920dc
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 9 deletions.
27 changes: 24 additions & 3 deletions src/models/votes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,19 @@ pub async fn get_vote(state: &Data<AppState>, id: i32) -> Option<Vote> {
}
}

pub async fn get_votes(state: &Data<AppState>, thread_id: &str) -> Option<Vec<Vote>> {
pub async fn get_votes(
state: &Data<AppState>,
thread_id: &str,
take: i64,
skip: i64,
) -> Option<Vec<Vote>> {
let db = &state.db;
match sqlx::query_as!(
Vote,
r#"SELECT id, author, target, post_number, target_correction, thread_id FROM votes WHERE thread_id = $1"#,
thread_id
r#"SELECT id, author, target, post_number, target_correction, thread_id FROM votes WHERE thread_id = $1 ORDER BY id DESC LIMIT $2 OFFSET $3"#,
thread_id,
take,
skip
)
.fetch_all(db)
.await
Expand All @@ -59,6 +66,20 @@ pub async fn get_votes(state: &Data<AppState>, thread_id: &str) -> Option<Vec<Vo
}
}

pub async fn get_votes_amt(state: &Data<AppState>, thread_id: &str) -> Option<i64> {
let db = &state.db;
match sqlx::query!(
"SELECT COUNT(*) as amount FROM votes WHERE thread_id = $1",
thread_id
)
.fetch_one(db)
.await
{
Ok(votes) => votes.amount,
_ => None,
}
}

pub async fn create_vote(state: &Data<AppState>, vote: NewVote) -> Option<PgQueryResult> {
let db = &state.db;
match sqlx::query!(
Expand Down
65 changes: 60 additions & 5 deletions src/routes/api/dashboard/vote_data.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use std::thread::current;

use crate::{ components::buttons::{gen_button, ButtonType, FormSubmitButton}, models::votes::{create_vote, get_votes, NewVote}, scraping::scraper::Vote, utils::{app_state::AppState, url::ForumURL}};
use crate::{ components::buttons::{gen_button, ButtonType, FormSubmitButton}, models::votes::{create_vote, get_votes, get_votes_amt, NewVote}, scraping::scraper::Vote, utils::{app_state::AppState, url::ForumURL}};
use actix_web::{get, post, web::{self, Data}, HttpResponse, Responder};
use maud::{html, Markup};
use serde::Deserialize;

#[derive(Deserialize, Debug)]
struct UrlQuery {
take: Option<i64>,
skip: Option<i64>,
}

struct TableRow {
author: String,
Expand Down Expand Up @@ -34,14 +39,37 @@ fn format_table_row(row: TableRow) -> Markup {
}

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

let all_votes = match get_votes(&state, &thread_id).await {
let take = match query.take {
Some(take) => take,
None => 10
};

let skip = match query.skip {
Some(skip) => skip,
None => 0
};

let all_votes = match get_votes(&state, &thread_id, take, skip).await {
Some(votes) => votes,
None => Vec::new()
};

let vote_count = match get_votes_amt(&state, &thread_id).await {
Some(vote_count) => vote_count,
None => 0
};

let current_page = (skip / take) + 1;
let last_page = (vote_count as f64 / take as f64).ceil() as i64;

let next_page_url = format!("/api/dashboard/votes/{}?take={}&skip={}", thread_id, take, skip + take);
let prev_page_url = format!("/api/dashboard/votes/{}?take={}&skip={}", thread_id, take, skip - take);

println!("{} {}", next_page_url, prev_page_url);

HttpResponse::Ok().body(
html! {
div."w-full h-full flex flex-col p-4" id="vote-wrapper" {
Expand Down Expand Up @@ -81,6 +109,33 @@ async fn vote_data(state: Data<AppState>, path: web::Path<String>) -> impl Respo
}
}
}
div."w-full flex flex-col justify-center items-center" {
div {
span."pagination-page" {
(format!("Page {} / {}, {} total votes", current_page, last_page, vote_count))
}
}

div {
@if current_page > 1 {
button."text-lg bg-white border-1 border-zinc-400 rounded py px-2 mt-4 select-none w-fit hover:cursor-pointer hover:bg-zinc-300 text-black" hx-get=(prev_page_url) hx-target="#vote-wrapper" hx-swap="outerHTML" hx-trigger="click" {
"Previous Page"
}
}

@if current_page > 1 && current_page < last_page {
span."text-xl px-2 text-white select-none" {
"•"
}
}

@if current_page < last_page {
button."text-lg bg-white border-1 border-zinc-400 rounded py px-2 mt-4 select-none w-fit hover:cursor-pointer hover:bg-zinc-300 text-black" hx-get=(next_page_url) hx-target="#vote-wrapper" hx-swap="outerHTML" hx-trigger="click" {
"Next Page"
}
}
}
}
}
}
.into_string(),
Expand Down
1 change: 0 additions & 1 deletion src/routes/pages/dashboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ async fn dashboard(
});

let gen_url = |url: &str| format!("/api/dashboard/{}/{}", url, thread_id);

let get_url_param = |param: &str| format!("/dashboard/{}?d={}", thread_id, param);

let tabs: Vec<(&str, &str)> = vec![("setup", "1"), ("players", "2"), ("votes", "3")];
Expand Down

0 comments on commit 41920dc

Please sign in to comment.