From 85a9e9d44006da8924db1cf92827dda51d2b584e Mon Sep 17 00:00:00 2001 From: gabatxo1312 Date: Wed, 28 Jan 2026 23:26:37 +0100 Subject: [PATCH] Add paginate --- src/models/book.rs | 28 ++++++++++++++++++++++++++++ src/routes/book.rs | 26 ++++++++++++++++++++++---- templates/index.html | 22 ++++++++++++++++++++++ 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/models/book.rs b/src/models/book.rs index 1493798..b449723 100644 --- a/src/models/book.rs +++ b/src/models/book.rs @@ -51,6 +51,13 @@ pub struct BookOperator { pub state: AppState, } +#[derive(Debug, Clone)] +pub struct BooksPaginate { + pub books: Vec, + pub current_page: u64, + pub total_page: u64, +} + impl BookOperator { pub fn new(state: AppState) -> Self { Self { state } @@ -64,6 +71,27 @@ impl BookOperator { .context(DBSnafu) } + pub async fn list_paginate(&self, page: u64) -> Result { + let page = if page > 0 { page } else { 1 }; // keep 1-indexed + let page_0indexed = page - 1; // convert for SeaORM (0-based index) + + let book_pages = Entity::find() + .order_by_desc(Column::Id) + .paginate(&self.state.db, 100); + + let books = book_pages + .fetch_page(page_0indexed) + .await + .context(DBSnafu)?; + let total_page = book_pages.num_pages().await.context(DBSnafu)?; + + Ok(BooksPaginate { + books, + current_page: page, + total_page, + }) + } + pub async fn find_by_id(&self, id: i32) -> Result { let book_by_id = Entity::find_by_id(id) .one(&self.state.db) diff --git a/src/routes/book.rs b/src/routes/book.rs index b23b541..ea977d5 100644 --- a/src/routes/book.rs +++ b/src/routes/book.rs @@ -4,7 +4,7 @@ use askama::Template; use askama_web::WebTemplate; use axum::{ Form, - extract::{Path, State}, + extract::{Path, Query, State}, response::{IntoResponse, Redirect}, }; use serde::Deserialize; @@ -26,6 +26,8 @@ use crate::{ #[template(path = "index.html")] struct BookIndexTemplate { books_with_user: Vec, + current_page: u64, + total_page: u64, } // Book list with the owner and the current holder inside @@ -35,21 +37,35 @@ struct BookWithUser { pub current_holder: Option, } +#[derive(Deserialize)] +pub struct Pagination { + pub page: Option, +} + pub async fn index( State(state): State, + Query(pagination): Query, ) -> Result { + let page: u64 = pagination + .page + .map(|p| p.max(1) as u64) // Minimum 1 + .unwrap_or(1); + let users = UserOperator::new(state.clone()) .list() .await .context(UserSnafu)?; - let books = BookOperator::new(state).list().await.context(BookSnafu)?; + let books_paginate = BookOperator::new(state) + .list_paginate(page) + .await + .context(BookSnafu)?; let user_by_id: HashMap = users.into_iter().map(|user| (user.id, user)).collect(); - let mut result: Vec = Vec::with_capacity(books.len()); + let mut result: Vec = Vec::with_capacity(books_paginate.books.len()); - for book in books { + for book in books_paginate.books { let owner = user_by_id.get(&book.owner_id).cloned().unwrap(); let current_holder = if let Some(current_holder_id) = book.current_holder_id { user_by_id.get(¤t_holder_id).cloned() @@ -66,6 +82,8 @@ pub async fn index( Ok(BookIndexTemplate { books_with_user: result, + current_page: books_paginate.current_page, + total_page: books_paginate.total_page, }) } diff --git a/templates/index.html b/templates/index.html index 1b18927..152029b 100644 --- a/templates/index.html +++ b/templates/index.html @@ -40,5 +40,27 @@ {% endfor %} + + {% if total_page > 1 %} + + {% endif %} {% endcall %} {% endblock %}