From 224db2aa05087b8a552d7044727fc76dff973fa7 Mon Sep 17 00:00:00 2001 From: Ryan Mwangi Date: Thu, 5 Dec 2024 16:50:25 +0300 Subject: [PATCH] feat: wire components together --- Cargo.lock | 2 + Cargo.toml | 2 + end2end/package-lock.json | 7 +++ end2end/package.json | 3 ++ src/app.rs | 80 ++++++++++---------------------- src/components/item_form.rs | 7 +-- src/components/items_list.rs | 1 + src/components/mod.rs | 2 + src/lib.rs | 3 ++ src/main.rs | 66 ++------------------------ src/models/{items.rs => item.rs} | 0 src/models/mod.rs | 1 + 12 files changed, 53 insertions(+), 121 deletions(-) create mode 100644 src/components/mod.rs rename src/models/{items.rs => item.rs} (100%) create mode 100644 src/models/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 30b0d2a..ec279b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -503,6 +503,8 @@ dependencies = [ "leptos_actix", "leptos_meta", "leptos_router", + "serde", + "uuid", "wasm-bindgen", ] diff --git a/Cargo.toml b/Cargo.toml index 7dc7644..fad2dda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,8 @@ leptos_meta = { version = "0.6" } leptos_actix = { version = "0.6", optional = true } leptos_router = { version = "0.6" } wasm-bindgen = "=0.2.96" +uuid = { version = "1.3", features = ["v4"] } +serde = { version = "1.0", features = ["derive"] } [features] csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"] diff --git a/end2end/package-lock.json b/end2end/package-lock.json index 3e0dc8a..8b63923 100644 --- a/end2end/package-lock.json +++ b/end2end/package-lock.json @@ -8,6 +8,9 @@ "name": "end2end", "version": "1.0.0", "license": "ISC", + "dependencies": { + "end2end": "file:" + }, "devDependencies": { "@playwright/test": "^1.44.1", "@types/node": "^20.12.12", @@ -40,6 +43,10 @@ "undici-types": "~5.26.4" } }, + "node_modules/end2end": { + "resolved": "", + "link": true + }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", diff --git a/end2end/package.json b/end2end/package.json index a80ac59..da2e766 100644 --- a/end2end/package.json +++ b/end2end/package.json @@ -11,5 +11,8 @@ "@playwright/test": "^1.44.1", "@types/node": "^20.12.12", "typescript": "^5.4.5" + }, + "dependencies": { + "end2end": "file:" } } diff --git a/src/app.rs b/src/app.rs index ab4ff29..46cb744 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,63 +1,33 @@ use leptos::*; -use leptos_meta::*; -use leptos_router::*; +use crate::components::{item_form::ItemForm, items_list::ItemsList}; +use crate::models::item::Item; +use std::thread::Scope; -#[component] -pub fn App() -> impl IntoView { - // Provides context that manages stylesheets, titles, meta tags, etc. - provide_meta_context(); - - view! { - // injects a stylesheet into the document - // id=leptos means cargo-leptos will hot-reload this stylesheet - - - // sets the document title - - - // content for this welcome page - <Router> - <main> - <Routes> - <Route path="" view=HomePage/> - <Route path="/*any" view=NotFound/> - </Routes> - </main> - </Router> - } +// Define the props struct +#[derive(Debug, Clone)] +pub struct AppProps { } -/// Renders the home page of your application. #[component] -fn HomePage() -> impl IntoView { - // Creates a reactive value to update the button - let (count, set_count) = create_signal(0); - let on_click = move |_| set_count.update(|count| *count += 1); +pub fn App(cx: Scope<'_, '_>) -> impl IntoView { + let items = create_signal(Vec::<Item>::new()); - view! { - <h1>"Welcome to Leptos!"</h1> - <button on:click=on_click>"Click Me: " {count}</button> - } -} - -/// 404 - Not Found -#[component] -fn NotFound() -> impl IntoView { - // set an HTTP status code 404 - // this is feature gated because it can only be done during - // initial server-side rendering - // if you navigate to the 404 page subsequently, the status - // code will not be set because there is not a new HTTP request - // to the server - #[cfg(feature = "ssr")] - { - // this can be done inline because it's synchronous - // if it were async, we'd use a server function - let resp = expect_context::<leptos_actix::ResponseOptions>(); - resp.set_status(actix_web::http::StatusCode::NOT_FOUND); - } - - view! { - <h1>"Not Found"</h1> + let add_item = move |name: String, description: String, tags: Vec<(String, String)>| { + items.update(|items| { + items.push(Item { + id: uuid::Uuid::new_v4().to_string(), + name, + description, + tags, + }); + }); + }; + + view! { cx, + <div> + <h1>{ "CompareWare" }</h1> + <ItemForm on_submit=add_item /> + <ItemsList items=items.get().clone() /> + </div> } } diff --git a/src/components/item_form.rs b/src/components/item_form.rs index 517f35f..deefdcc 100644 --- a/src/components/item_form.rs +++ b/src/components/item_form.rs @@ -1,10 +1,11 @@ use leptos::*; +use std::thread::Scope; #[component] pub fn ItemForm(cx: Scope, on_submit: Box<dyn Fn(String, String, Vec<(String, String)>)>) -> impl IntoView { - let name = create_signal(cx, String::new()); - let description = create_signal(cx, String::new()); - let tags = create_signal(cx, vec![]); + let name = create_signal(String::new()); + let description = create_signal(String::new()); + let tags = create_signal(vec![]); let handle_submit = move |_| { on_submit(name.get().clone(), description.get().clone(), tags.get().clone()); diff --git a/src/components/items_list.rs b/src/components/items_list.rs index 898a98e..95cd90e 100644 --- a/src/components/items_list.rs +++ b/src/components/items_list.rs @@ -1,5 +1,6 @@ use leptos::*; use crate::models::item::Item; +use std::thread::Scope; #[component] pub fn ItemsList(cx: Scope, items: Vec<Item>) -> impl IntoView { diff --git a/src/components/mod.rs b/src/components/mod.rs new file mode 100644 index 0000000..6d4b027 --- /dev/null +++ b/src/components/mod.rs @@ -0,0 +1,2 @@ +pub mod item_form; +pub mod items_list; diff --git a/src/lib.rs b/src/lib.rs index daa8cfb..4e3b8f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,7 @@ pub mod app; +pub mod components; +pub mod models; + #[cfg(feature = "hydrate")] #[wasm_bindgen::prelude::wasm_bindgen] diff --git a/src/main.rs b/src/main.rs index 535b829..804644f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,66 +1,6 @@ -#[cfg(feature = "ssr")] -#[actix_web::main] -async fn main() -> std::io::Result<()> { - use actix_files::Files; - use actix_web::*; - use leptos::*; - use leptos_actix::{generate_route_list, LeptosRoutes}; - use compareware::app::*; - - let conf = get_configuration(None).await.unwrap(); - let addr = conf.leptos_options.site_addr; - // Generate the list of routes in your Leptos App - let routes = generate_route_list(App); - println!("listening on http://{}", &addr); - - HttpServer::new(move || { - let leptos_options = &conf.leptos_options; - let site_root = &leptos_options.site_root; - - App::new() - // serve JS/WASM/CSS from `pkg` - .service(Files::new("/pkg", format!("{site_root}/pkg"))) - // serve other assets from the `assets` directory - .service(Files::new("/assets", site_root)) - // serve the favicon from /favicon.ico - .service(favicon) - .leptos_routes(leptos_options.to_owned(), routes.to_owned(), App) - .app_data(web::Data::new(leptos_options.to_owned())) - //.wrap(middleware::Compress::default()) - }) - .bind(&addr)? - .run() - .await -} - -#[cfg(feature = "ssr")] -#[actix_web::get("favicon.ico")] -async fn favicon( - leptos_options: actix_web::web::Data<leptos::LeptosOptions>, -) -> actix_web::Result<actix_files::NamedFile> { - let leptos_options = leptos_options.into_inner(); - let site_root = &leptos_options.site_root; - Ok(actix_files::NamedFile::open(format!( - "{site_root}/favicon.ico" - ))?) -} - -#[cfg(not(any(feature = "ssr", feature = "csr")))] -pub fn main() { - // no client-side main function - // unless we want this to work with e.g., Trunk for pure client-side testing - // see lib.rs for hydration function instead - // see optional feature `csr` instead -} - -#[cfg(all(not(feature = "ssr"), feature = "csr"))] -pub fn main() { - // a client-side main function is required for using `trunk serve` - // prefer using `cargo leptos serve` instead - // to run: `trunk serve --open --features csr` - use compareware::app::*; - - console_error_panic_hook::set_once(); +use leptos::*; +use crate::app::App; +fn main() { leptos::mount_to_body(App); } diff --git a/src/models/items.rs b/src/models/item.rs similarity index 100% rename from src/models/items.rs rename to src/models/item.rs diff --git a/src/models/mod.rs b/src/models/mod.rs new file mode 100644 index 0000000..a35e98d --- /dev/null +++ b/src/models/mod.rs @@ -0,0 +1 @@ +pub mod item;