diff --git a/backend/api/src/lib.rs b/backend/api/src/lib.rs index 8adae4b..ddd78df 100644 --- a/backend/api/src/lib.rs +++ b/backend/api/src/lib.rs @@ -327,8 +327,15 @@ async fn list_users( } return Json(users); } - async fn login_handler(mut auth: AuthContext, Json(user_sent): Json) -> impl IntoResponse { - auth.login(&user_sent).await.unwrap(); + async fn login_handler(mut auth: AuthContext, Extension(ref conn): Extension, Json(user_sent): Json) -> impl IntoResponse { + let userdb : user::Model = QueryCore::find_userid_by_name(conn, user_sent.name.clone()).await.unwrap().unwrap(); + let userid = userdb.id; + let corrected_user = booksman_orm::AxumUser { + id: userid, + name: user_sent.name.clone(), + password_hash: user_sent.password_hash.clone() + }; + auth.login(&corrected_user).await.unwrap(); return "success"; } @@ -621,8 +628,9 @@ async fn list_book( let page: usize = params.get("page").unwrap().parse().unwrap(); let userid: usize = params.get("userid").unwrap().parse().unwrap(); + let sort: String = params.get("sort").unwrap().to_string(); - let books = QueryCore::find_books_plus_meta_in_page(conn,page,userid,12) + let books = QueryCore::find_books_plus_meta_in_page(conn,page,userid,12, sort) .await .expect("could not list books"); diff --git a/backend/orm/src/query.rs b/backend/orm/src/query.rs index 255b119..8545ed0 100644 --- a/backend/orm/src/query.rs +++ b/backend/orm/src/query.rs @@ -27,6 +27,11 @@ impl Query { } + pub async fn find_userid_by_name(db: &DbConn, name: String) -> Result, DbErr> { + User::find().filter(user::Column::UserName.eq(name)).one(db).await + } + + pub async fn find_user_by_id(db: &DbConn, id: i32) -> Result, DbErr> { User::find_by_id(id).one(db).await } @@ -48,16 +53,26 @@ impl Query { page: u64, posts_per_page: u64, userid: i32, + sort: String, ) -> Result<(Vec, u64), DbErr> { // Setup paginator - let paginator = Book::find() - .filter(book::Column::UserId.eq(userid)) - .order_by_asc(book::Column::Id) - .paginate(db, posts_per_page); - let num_pages = paginator.num_pages().await?; + if sort == "desc".to_string() { + let paginator = Book::find() + .filter(book::Column::UserId.eq(userid)) + .order_by_desc(book::Column::Id) + .paginate(db, posts_per_page); + let num_pages = paginator.num_pages().await?; + return paginator.fetch_page(page - 1).await.map(|p| (p, num_pages)) + } else { + let paginator = Book::find() + .filter(book::Column::UserId.eq(userid)) + .order_by_asc(book::Column::Id) + .paginate(db, posts_per_page); + let num_pages = paginator.num_pages().await?; + return paginator.fetch_page(page - 1).await.map(|p| (p, num_pages)) + } // Fetch paginated posts - paginator.fetch_page(page - 1).await.map(|p| (p, num_pages)) } pub async fn find_books_plus_meta_in_page( @@ -65,9 +80,10 @@ pub async fn find_books_plus_meta_in_page( page: usize, posts_per_page: usize, userid: i32, + sort: String, ) -> Result<(Vec, u64), DbErr> { // Setup paginator - let books = Self::find_books_in_page(db,page.try_into().unwrap(),posts_per_page.try_into().unwrap(),userid).await?; + let books = Self::find_books_in_page(db,page.try_into().unwrap(),posts_per_page.try_into().unwrap(),userid, sort).await?; let book_ids: Vec = books.0.clone().into_iter().map(|b| b.id).collect(); let mut resbooks: Vec = Vec::with_capacity(book_ids.len()); for book in books.0.iter() { diff --git a/frontend/src/main.rs b/frontend/src/main.rs index dcb3b26..3a70508 100644 --- a/frontend/src/main.rs +++ b/frontend/src/main.rs @@ -45,6 +45,11 @@ pub struct BookUIProp { bookitem: BookUI, } +#[derive(Prop, Debug, Clone, PartialEq, Hash, Eq)] +pub struct StringProp { + value: String, +} + #[derive(Deserialize, Serialize, Debug, Clone)] struct PaginatedBookUIList { num_pages: u32, @@ -146,11 +151,11 @@ async fn fetch_books(search: String) -> Result, reqwasm::Error> { Ok(body) } -async fn search_books(search: String, page: u32) -> Result { +async fn search_books(search: String, page: u32, userid:i32) -> Result { let backend_url : &'static str = dotenv!("BACKEND_URL"); //"http://localhost:8081"; //env::var("BACKEND_URL").expect("BACKEND_URL is not set in .env file"); - let url = format!("{}/api/list_search?search={}&page={}",backend_url, search, page); + let url = format!("{}/api/list_search?search={}&page={}&userid={}",backend_url, search, page, userid); let resp = Request::get(&url).send().await?; println!("Fetching books\n"); let body = resp.json::().await?; @@ -191,10 +196,10 @@ async fn delete_book(id: i32) -> Result Ok(resp) } -async fn list_books(page: u32) -> Result { +async fn list_books(page: u32, userid: i32, sort: String) -> Result { let backend_url : &'static str = dotenv!("BACKEND_URL"); //env::var("BACKEND_URL").expect("BACKEND_URL is not set in .env file"); - let url = format!("{}/api/list?page={}", backend_url, page); + let url = format!("{}/api/list?page={}&userid={}&sort={}", backend_url, page, userid, sort); let resp = Request::get(&url).send().await?; println!("Fetching books\n"); info!("BACKEND{}",backend_url); @@ -309,6 +314,7 @@ pub fn Header(cx: Scope) -> View { }; let dropdown_userselect = |_| { + let app_state = app_state.clone(); spawn_local(async move { app_state.userlist.set(list_users() .await.expect("Couldn't list user")); @@ -316,8 +322,10 @@ pub fn Header(cx: Scope) -> View { app_state.dropdownselect.set(true); }; +// let users = create_memo(cx, || app_state.userlist.get().keys().cloned().map(|x| StringProp{value: x}).collect::>()); let users = create_memo(cx, || app_state.userlist.get().keys().cloned().collect::>()); + view! { cx, header(class="header") { div(class="header-button"){ @@ -361,9 +369,9 @@ pub fn Header(cx: Scope) -> View { Keyed( iterable=users, view=move |cx, x| view! { cx, - DropDownUser(user=x) + DropDownUser(value=x) }, - key =|x| x ) + key =|x| x.clone() ) } } } else { @@ -406,16 +414,18 @@ pub fn Header(cx: Scope) -> View { } #[component(inline_props)] -pub fn DropDownUser(cx: Scope, user: String) -> View { +pub fn DropDownUser(cx: Scope, value: StringProp) -> View { let app_state = use_context::(cx); + let buttontext = value.clone().value.clone(); + let valueclosure = value.clone(); let handle_select_user = move |_| { - app_state.userid.set( *(*app_state.userlist.get()).get(&(user).clone()).unwrap_or(&0)); + app_state.userid.set( *(*app_state.userlist.get()).get(&(valueclosure.value).clone()).unwrap_or(&0)); app_state.dropdownselect.set(false); }; view! { cx, - button(class="delete", on:click=handle_select_user){ format!("{}",user) } + button(class="delete", on:click=handle_select_user){ (buttontext) } } } @@ -447,7 +457,7 @@ async fn ListDB(cx: Scope<'_>) -> View { info!("DB triggered"); spawn_local(async move { - let res = list_books(*app_state.pagenum.get()) + let res = list_books(*app_state.pagenum.get(), *app_state.userid.get(), "desc".to_string()) .await.unwrap(); app_state.books.set( res.books @@ -460,7 +470,7 @@ async fn ListDB(cx: Scope<'_>) -> View { info!("IntSearch triggered"); spawn_local(async move { - let res = search_books(app_state.search.get().to_string(), *app_state.pagenum.get()) + let res = search_books(app_state.search.get().to_string(), *app_state.pagenum.get(), *app_state.userid.get()) .await.unwrap(); app_state.books.set( res.books