diff --git a/app/Cargo.toml b/app/Cargo.toml index 687a74f..1127962 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -37,3 +37,6 @@ hex.workspace = true default = [] hydrate = ["leptos/hydrate"] ssr = ["leptos/ssr", "leptos_meta/ssr", "leptos_router/ssr", "dep:leptos_axum"] + +[lints] +workspace = true diff --git a/app/src/components/app.rs b/app/src/components/app.rs new file mode 100644 index 0000000..84c3784 --- /dev/null +++ b/app/src/components/app.rs @@ -0,0 +1,30 @@ +use leptos::prelude::*; +use leptos_meta::{provide_meta_context, Stylesheet, Title}; +use leptos_router::{ + components::{Route, Router, Routes}, + StaticSegment, +}; + +use crate::components::homepage::HomePage; + +#[component] +pub fn App() -> impl IntoView { + // Provides context that manages stylesheets, titles, meta tags, etc. + provide_meta_context(); + + view! { + + + // sets the document title + + + // content for this welcome page + <Router> + <main> + <Routes fallback=|| "Page not found.".into_view()> + <Route path=StaticSegment("") view=HomePage /> + </Routes> + </main> + </Router> + } +} diff --git a/app/src/components/homepage.rs b/app/src/components/homepage.rs new file mode 100644 index 0000000..140458b --- /dev/null +++ b/app/src/components/homepage.rs @@ -0,0 +1,14 @@ +use leptos::prelude::*; + +/// Renders the home page of your application. +#[component] +pub fn HomePage() -> impl IntoView { + // Creates a reactive value to update the button + let count = RwSignal::new(0); + let on_click = move |_| *count.write() += 1; + + view! { + <h1>"Welcome to Leptos!"</h1> + <button on:click=on_click>"Click Me: " {count}</button> + } +} diff --git a/app/src/components/mod.rs b/app/src/components/mod.rs new file mode 100644 index 0000000..3dd0bf8 --- /dev/null +++ b/app/src/components/mod.rs @@ -0,0 +1,3 @@ +pub mod app; +mod homepage; +mod register; diff --git a/app/src/components/register.rs b/app/src/components/register.rs new file mode 100644 index 0000000..b44c3c2 --- /dev/null +++ b/app/src/components/register.rs @@ -0,0 +1,75 @@ +use leptos::prelude::*; + +use crate::server_fn::auth::register_user; + +#[component] +pub fn RegisterPage() -> impl IntoView { + let (username, set_username) = signal(String::new()); + let register_action = Action::new(|input: &RegisterUserForm| { + let input = input.clone(); + async move { register_user(input).await } + }); + + let response = register_action.value(); + let pending = register_action.pending(); + + view! { + <div class="container"> + <form on:submit=move |ev| { + ev.prevent_default(); + register_action + .dispatch(RegisterUserForm { + username: username.get(), + }); + }> + <h1>"Register"</h1> + <div class="input-group"> + <label for="username">"Username"</label> + <input + type="text" + id="username" + name="username" + on:input=move |ev| { + set_username(event_target_value(&ev)); + } + prop:value=username + /> + <div class="error"> + {move || { + response + .get() + .and_then(|result| result.err()) + .map(|err| err.to_string()) + }} + </div> + </div> + <button type="submit" disabled=pending> + {move || { + response + .with(|r| { + r.as_ref() + .and_then(|result| result.as_ref().err()) + .map(|err| err.to_string()) + }) + }} + "Register" + </button> + </form> + {move || { + response + .with(|r| { + r.as_ref() + .and_then(|result| result.as_ref().ok()) + .map(|res| { + view! { + <div class="success"> + <p>"Reistration successful!"</p> + <p>"Your code ir: "{res.code.clone()}</p> + </div> + } + }) + }) + }} + </div> + } +} diff --git a/app/src/server_fn/auth.rs b/app/src/server_fn/auth.rs index ebd7b6d..d557cf1 100644 --- a/app/src/server_fn/auth.rs +++ b/app/src/server_fn/auth.rs @@ -5,11 +5,12 @@ use crate::{models::response::RegisterResponse, startup::AppState}; use leptos::{prelude::*, server}; #[server(RegisterUser, "/api/v1/users")] -pub async fn register_user(username: String) -> Result<RegisterResponse, ServerFnError<String>> { +pub async fn register_user( + form: RegisterUserForm, +) -> Result<RegisterResponse, ServerFnError<String>> { let state = use_context::<AppState>() .ok_or_else(|| ServerFnError::ServerError("AppState not found".into()))?; - let form = RegisterUserForm { username }; let new_user = form.try_into().map_err(|e| ServerFnError::ServerError(e))?; match insert_user(&state.pool, &new_user).await { @@ -20,9 +21,7 @@ pub async fn register_user(username: String) -> Result<RegisterResponse, ServerF ))), Err(e) => { tracing::error!("Failed to register user: {}", e); - Err(ServerFnError::ServerError( - "Internal server error".to_string(), - )) + Err(ServerFnError::ServerError("Internal server error".into())) } } } diff --git a/app/src/server_fn/mod.rs b/app/src/server_fn/mod.rs index 12bc9de..0e4a05d 100644 --- a/app/src/server_fn/mod.rs +++ b/app/src/server_fn/mod.rs @@ -1 +1 @@ -mod auth; +pub mod auth; diff --git a/frontend/Cargo.toml b/frontend/Cargo.toml index 5eac1bb..af0df23 100644 --- a/frontend/Cargo.toml +++ b/frontend/Cargo.toml @@ -14,3 +14,6 @@ leptos = { workspace = true, features = ["hydrate"] } tracing.workspace = true wasm-bindgen.workspace = true + +[lints] +workspace = true diff --git a/justfile b/justfile index 8305c08..aa4cc1e 100644 --- a/justfile +++ b/justfile @@ -18,7 +18,7 @@ setup: # Start development server with hot reload dev: kill-server db-migrate - cargo leptos watch | bunyan + RUST_BACKTRACE=full cargo leptos watch | bunyan # Run cargo check on both native and wasm targets check: diff --git a/server/Cargo.toml b/server/Cargo.toml index e5b5910..4c91c2d 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -17,3 +17,6 @@ tower-http.workspace = true tracing.workspace = true tracing-log.workspace = true uuid.workspace = true + +[lints] +workspace = true