Added the ability to fetch multiple members on register

This commit is contained in:
xeovalyte 2024-09-24 21:17:49 +02:00
parent 91824dc82b
commit a503726b42
Signed by: xeovalyte
SSH Key Fingerprint: SHA256:kSQDrQDmKzljJzfGYcd3m9RqHi4h8rSwkZ3sQ9kBURo
7 changed files with 729 additions and 566 deletions

1198
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ dioxus = { version = "0.5", features = ["fullstack", "router"] }
tokio = { version = "1.38", features = ["macros", "rt-multi-thread"], optional = true }
axum = { version = "0.7", optional = true }
once_cell = { version = "1.19", optional = true }
surrealdb = { version = "1.5", features = ["kv-speedb"], optional = true }
surrealdb = { version = "2.0", features = ["kv-rocksdb"], optional = true }
csv = { version = "1.3", optional = true }

View File

@ -2188,12 +2188,12 @@ input.tab:checked + .tab-content,
}
}
.badge-lg {
height: 1.5rem;
font-size: 1rem;
line-height: 1.5rem;
padding-left: 0.688rem;
padding-right: 0.688rem;
.badge-md {
height: 1.25rem;
font-size: 0.875rem;
line-height: 1.25rem;
padding-left: 0.563rem;
padding-right: 0.563rem;
}
.btn-wide {
@ -2547,11 +2547,6 @@ input.tab:checked + .tab-content,
gap: 1.25rem;
}
.gap-x-2 {
-moz-column-gap: 0.5rem;
column-gap: 0.5rem;
}
.overflow-auto {
overflow: auto;
}

View File

@ -2,6 +2,7 @@ use dioxus::prelude::*;
use crate::components::layout::icons;
use crate::util::model::member::Member;
use std::collections::HashMap;
pub fn Auth() -> Element {
let mut register = use_signal(|| false);
@ -80,7 +81,7 @@ fn Login() -> Element {
}
fn Register() -> Element {
let mut members: Signal<Vec<Member>> = use_signal(|| vec![]);
let mut members: Signal<HashMap<String, Member>> = use_signal(|| HashMap::new());
let mut input_registration_token = use_signal(|| "".to_string());
rsx! {
@ -102,7 +103,7 @@ fn Register() -> Element {
class: "btn join-item btn-neutral",
onclick: move |_| async move {
if let Ok(res) = fetch_member(input_registration_token()).await {
members.push(res);
members.write().insert(res.id.clone(), res);
input_registration_token.set("".to_string());
}
},
@ -111,10 +112,13 @@ fn Register() -> Element {
}
}
div {
class: "flex gap-x-2 mt-2 overflow-x-auto pb-3",
for member in &*members.read() {
class: "flex gap-1 mt-2 flex-wrap pb-3",
for (id, member) in members() {
div {
class: "badge badge-lg badge-neutral h-8 gap-1 hover:cursor-pointer hover:line-through whitespace-nowrap",
class: "badge badge-md badge-neutral h-8 gap-1 hover:cursor-pointer hover:line-through whitespace-nowrap",
onclick: move |_| {
members.write().remove(&id);
},
"{member.name.full}"
icons::XMark {},
}

View File

@ -31,7 +31,7 @@ pub struct MembersMigration {
#[cfg(feature = "server")]
impl Member {
pub async fn fetch_all() -> Result<Vec<Self>, surrealdb::Error> {
let mut res = DB.query("SELECT meta::id(id) as id, name.first, name.full, hours, groups, diploma, registration_token FROM member").await?;
let mut res = DB.query("SELECT record::id(id) as id, name.first, name.full, hours, groups, diploma, registration_token FROM member").await?;
let members: Vec<Self> = res.take(0)?;
@ -43,11 +43,12 @@ impl Member {
pub async fn fetch_from_registration_token(
registration_token: String,
) -> Result<Option<Self>, surrealdb::Error> {
let _ = Self::fetch_all().await?;
let query = format!("SELECT record::id(id) as id, name.first, name.full, hours, groups, diploma, registration_token FROM ONLY member WHERE registration_token = $registration_token LIMIT 1");
let query = format!("SELECT meta::id(id) as id, name.first, name.full, hours, groups, diploma, registration_token FROM ONLY member WHERE registration_token = {} LIMIT 1", registration_token);
let mut res = DB.query(query).await?;
let mut res = DB
.query(query)
.bind(("registration_token", registration_token))
.await?;
let member: Option<Self> = res.take(0)?;

View File

@ -4,6 +4,7 @@ use super::{Member, MembersMigration};
use once_cell::sync::Lazy;
use std::collections::HashMap;
use surrealdb::sql::statements::{BeginStatement, CommitStatement};
use tokio::sync::Mutex;
// Create a store for saving information when migrating to a new members list
@ -135,12 +136,6 @@ impl MembersMigration {
new_members_list: Vec<Member>,
current_members_list: Vec<Member>,
) -> MembersMigration {
tracing::info!(
"Current: {}, New: {}",
current_members_list.len(),
new_members_list.len()
);
let current_members_map: HashMap<String, Member> = current_members_list
.clone()
.into_iter()
@ -214,37 +209,45 @@ impl MembersMigration {
None => return Err("Could not get members from store".into()),
};
let mut query = String::from("BEGIN TRANSACTION;");
let mut transaction = DB.query(BeginStatement::default());
for member in members_migration.updated.clone() {
// TODO add hours and diploma support
query = query
+ format!(
"UPDATE member:{} SET name.first = \"{}\", name.full = \"{}\", hours = {:?}, groups = {:?};",
member.id, member.name.first, member.name.full, member.hours, member.groups
)
.as_str();
let id = member.id.clone();
transaction = transaction.query(format!("UPDATE type::thing('member', $id_{id}) SET name.first = $name_first_{id}, name.full = $name_full_{id}, hours = $hours_{id}, groups = $groups_{id};"))
.bind((format!("id_{id}"), member.id))
.bind((format!("name_first_{id}"), member.name.first))
.bind((format!("name_full_{id}"), member.name.full))
.bind((format!("hours_{id}"), member.hours))
.bind((format!("groups_{id}"), member.groups));
}
for member in members_migration.inserted.clone() {
// TODO add hours and diploma support
let id = member.id.clone();
query = query
+ format!(
"CREATE member:{} SET name.first = \"{}\", name.full = \"{}\", hours = {:?}, groups = {:?}, registration_token = rand::string(16);",
member.id, member.name.first, member.name.full, member.hours, member.groups
)
.as_str();
transaction = transaction.query(format!("CREATE type::thing('member', $id_{id}) SET name.first = $name_first_{id}, name.full = $name_full_{id}, hours = $hours_{id}, groups = $groups_{id}, registration_token = rand::string(16);"))
.bind((format!("id_{id}"), member.id))
.bind((format!("name_first_{id}"), member.name.first))
.bind((format!("name_full_{id}"), member.name.full))
.bind((format!("hours_{id}"), member.hours))
.bind((format!("groups_{id}"), member.groups));
}
for member in members_migration.removed.clone() {
// TODO add hours and diploma support
query = query + format!("DELETE member:{};", member.id).as_str();
let id = member.id.clone();
transaction = transaction
.query(format!("DELETE type::thing('member', $id_{id});"))
.bind((format!("id_{id}"), member.id));
}
query = query + "COMMIT TRANSACTION;";
DB.query(query).await?;
transaction
.query(CommitStatement::default())
.await?
.check()?;
Ok(())
}

View File

@ -1,11 +1,11 @@
use once_cell::sync::Lazy;
use surrealdb::engine::local::{Db, SpeeDb};
use surrealdb::engine::local::{Db, RocksDb};
use surrealdb::Surreal;
pub static DB: Lazy<Surreal<Db>> = Lazy::new(|| Surreal::init());
pub async fn initialize() -> surrealdb::Result<()> {
DB.connect::<SpeeDb>("./database").await?;
DB.connect::<RocksDb>("./database").await?;
DB.use_ns("xvmcmm").use_db("xvmcmm").await?;