From d0263ce46160cd4152c67381fab2ee557f3aa483 Mon Sep 17 00:00:00 2001 From: Benedikt Peetz Date: Tue, 30 Sep 2025 09:15:56 +0200 Subject: feat(treewide): Switch to tailwindcss and add more components --- .gitignore | 4 + Cargo.lock | 284 ++--------- Cargo.toml | 5 +- README.md | 81 ---- Trunk.toml | 47 +- flake.nix | 1 + index.html | 27 +- input.css | 3 + public/logo.svg | 949 ------------------------------------- public/styles.scss | 52 -- src/api/mod.rs | 50 ++ src/components/async_fetch.rs | 50 ++ src/components/container.rs | 47 +- src/components/icon_p.rs | 18 + src/components/inventory.rs | 55 +++ src/components/mod.rs | 6 +- src/components/product_overview.rs | 71 ++- src/components/recipies.rs | 12 + src/components/side_header.rs | 22 - src/components/site_header.rs | 29 ++ src/lib.rs | 41 +- src/main.rs | 5 + src/pages/home.rs | 24 +- stalwart/Trunk.toml | 4 - stalwart/index.html | 32 -- stalwart/input.css | 3 - stalwart/package.json | 18 - stalwart/tailwind.config.js | 36 -- tailwind.config.js | 21 + 29 files changed, 422 insertions(+), 1575 deletions(-) delete mode 100644 README.md create mode 100644 input.css delete mode 100644 public/logo.svg delete mode 100644 public/styles.scss create mode 100644 src/api/mod.rs create mode 100644 src/components/async_fetch.rs create mode 100644 src/components/icon_p.rs create mode 100644 src/components/inventory.rs create mode 100644 src/components/recipies.rs delete mode 100644 src/components/side_header.rs create mode 100644 src/components/site_header.rs delete mode 100644 stalwart/Trunk.toml delete mode 100644 stalwart/index.html delete mode 100644 stalwart/input.css delete mode 100644 stalwart/package.json delete mode 100644 stalwart/tailwind.config.js create mode 100644 tailwind.config.js diff --git a/.gitignore b/.gitignore index d801e9f..f608a06 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ /target /dist +/public/tailwindcss-output.css + +/references + /.direnv /result /result-* diff --git a/Cargo.lock b/Cargo.lock index 1e9e619..ad62a73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "addr2line" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] @@ -52,15 +52,6 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" -[[package]] -name = "approx" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" -dependencies = [ - "num-traits", -] - [[package]] name = "async-lock" version = "3.4.1" @@ -133,9 +124,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "backtrace" -version = "0.3.75" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", @@ -143,7 +134,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets", + "windows-link", ] [[package]] @@ -179,12 +170,6 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" -[[package]] -name = "by_address" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" - [[package]] name = "bytes" version = "1.10.1" @@ -199,9 +184,9 @@ checksum = "e1de8bc0aa9e9385ceb3bf0c152e3a9b9544f6c4a912c8ae504e80c1f0368603" [[package]] name = "cc" -version = "1.2.38" +version = "1.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9" +checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" dependencies = [ "find-msvc-tools", "shlex", @@ -220,10 +205,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "iana-time-zone", - "js-sys", "num-traits", "serde", - "wasm-bindgen", "windows-link", ] @@ -519,12 +502,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "fast-srgb8" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" - [[package]] name = "find-msvc-tools" version = "0.1.2" @@ -660,23 +637,11 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "getset" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf0fc11e47561d47397154977bc219f4cf809b2974facc3ccb3b89e2436f912" -dependencies = [ - "proc-macro-error2", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "gloo-net" @@ -881,19 +846,19 @@ dependencies = [ ] [[package]] -name = "icondata_ai" -version = "0.0.10" +name = "icondata_core" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bf3a9c196a6a169f790639ecc8fdd4396660b1d53b905230bf0b364776a56fc" -dependencies = [ - "icondata_core", -] +checksum = "6c97be924215abd5e630d84e95a47c710138a6559b4c55039f4f33aa897fa859" [[package]] -name = "icondata_core" +name = "icondata_io" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c97be924215abd5e630d84e95a47c710138a6559b4c55039f4f33aa897fa859" +checksum = "7886629becd205d6f035dc084b68d2b9cc5ba8b03714f2c533c921ed98c6525a" +dependencies = [ + "icondata_core", +] [[package]] name = "icu_collections" @@ -1175,6 +1140,16 @@ dependencies = [ "walkdir", ] +[[package]] +name = "leptos_icons" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68bb2db144efbf0c0ae03c15143ff98b5d456093a64112bb8dd72c29c3ba730b" +dependencies = [ + "icondata_core", + "leptos", +] + [[package]] name = "leptos_macro" version = "0.8.8" @@ -1269,17 +1244,6 @@ dependencies = [ "tachys", ] -[[package]] -name = "leptos_transition_group" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb1c87b92e7df414c6d2d5dc033a0b413797ffad5c379b996b68cf5695a9bce" -dependencies = [ - "leptos", - "send_wrapper", - "web-sys", -] - [[package]] name = "libc" version = "0.2.176" @@ -1339,9 +1303,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "mime" @@ -1422,9 +1386,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] @@ -1451,30 +1415,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c04f5d74368e4d0dfe06c45c8627c81bd7c317d52762d118fb9b3076f6420fd" -[[package]] -name = "palette" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6" -dependencies = [ - "approx", - "fast-srgb8", - "palette_derive", - "phf", -] - -[[package]] -name = "palette_derive" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30" -dependencies = [ - "by_address", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "parking" version = "2.2.1" @@ -1522,48 +1462,6 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" -[[package]] -name = "phf" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" -dependencies = [ - "phf_macros", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared", - "rand", -] - -[[package]] -name = "phf_macros" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", -] - [[package]] name = "pin-project" version = "1.1.10" @@ -1676,12 +1574,6 @@ dependencies = [ "yansi", ] -[[package]] -name = "pure-rust-locales" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1190fd18ae6ce9e137184f207593877e70f39b015040156b1e05081cdfe3733a" - [[package]] name = "quote" version = "1.0.40" @@ -1719,21 +1611,6 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" - [[package]] name = "reactive_graph" version = "0.2.7" @@ -1818,9 +1695,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.2" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" dependencies = [ "aho-corasick", "memchr", @@ -1830,9 +1707,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" dependencies = [ "aho-corasick", "memchr", @@ -1898,12 +1775,15 @@ version = "0.1.0" dependencies = [ "console_error_panic_hook", "console_log", + "icondata_core", + "icondata_io", "leptos", + "leptos_icons", "leptos_meta", "leptos_router", "log", + "reactive_stores", "rocie-client", - "thaw", "uuid", "wasm-bindgen", "wasm-bindgen-test", @@ -2014,9 +1894,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.226" +version = "1.0.227" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" +checksum = "80ece43fc6fbed4eb5392ab50c07334d3e577cbf40997ee896fe7af40bba4245" dependencies = [ "serde_core", "serde_derive", @@ -2024,18 +1904,18 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.226" +version = "1.0.227" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" +checksum = "7a576275b607a2c86ea29e410193df32bc680303c82f31e275bbfcafe8b33be5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.226" +version = "1.0.227" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" +checksum = "51e694923b8824cf0e9b382adf0f60d4e05f348f357b38833a3fa5ed7c2ede04" dependencies = [ "proc-macro2", "quote", @@ -2205,12 +2085,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "siphasher" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" - [[package]] name = "slab" version = "0.4.11" @@ -2331,68 +2205,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "thaw" -version = "0.5.0-beta" -source = "git+https://github.com/thaw-ui/thaw?branch=main#0492a030cf45582bc7eb729869a2d8578002d318" -dependencies = [ - "cfg-if", - "chrono", - "getset", - "icondata_ai", - "icondata_core", - "leptos", - "leptos_transition_group", - "num-traits", - "palette", - "pure-rust-locales", - "send_wrapper", - "slotmap", - "thaw_components", - "thaw_macro", - "thaw_utils", - "uuid", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "thaw_components" -version = "0.4.0-beta" -source = "git+https://github.com/thaw-ui/thaw?branch=main#0492a030cf45582bc7eb729869a2d8578002d318" -dependencies = [ - "cfg-if", - "leptos", - "send_wrapper", - "thaw_utils", - "uuid", - "web-sys", -] - -[[package]] -name = "thaw_macro" -version = "0.1.0" -source = "git+https://github.com/thaw-ui/thaw?branch=main#0492a030cf45582bc7eb729869a2d8578002d318" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thaw_utils" -version = "0.2.0-beta" -source = "git+https://github.com/thaw-ui/thaw?branch=main#0492a030cf45582bc7eb729869a2d8578002d318" -dependencies = [ - "cfg-if", - "chrono", - "leptos", - "reactive_stores", - "send_wrapper", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "thiserror" version = "1.0.69" @@ -2885,7 +2697,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.0", + "windows-sys 0.61.1", ] [[package]] @@ -2958,9 +2770,9 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.61.0" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" dependencies = [ "windows-link", ] diff --git a/Cargo.toml b/Cargo.toml index e0e0265..d1579b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,13 +19,16 @@ web-sys = { version = "0.3", features = ["Document", "Window"] } [dependencies] rocie-client = { path = "../rocie-server/crates/rocie-client" } leptos = { version = "0.8", features = ["csr"] } -thaw = { git = "https://github.com/thaw-ui/thaw", branch = "main" } +reactive_stores = { version = "0.2" } leptos_meta = { version = "0.8" } leptos_router = { version = "0.8" } console_log = "1" log = "0.4" console_error_panic_hook = "0.1" uuid = { version = "1.18.1", features = ["js"] } +leptos_icons = "0.7.0" +icondata_core = "0.1.0" +icondata_io = "0.1.0" [profile.release] opt-level = 'z' diff --git a/README.md b/README.md deleted file mode 100644 index adb94ce..0000000 --- a/README.md +++ /dev/null @@ -1,81 +0,0 @@ - - - Leptos Logo - - -# Leptos Client-Side Rendered (CSR) App Starter Template - -This is a template for use with the [Leptos] web framework using the [Trunk] -tool to compile and serve your app in development. - -## Creating your repo from the template - -This template requires you to have `cargo-generate` and `trunk` installed. -[`leptosfmt`](https://github.com/bram209/leptosfmt) is optional but highly -recommended. You can install them with - -```sh -cargo install cargo-generate trunk leptosfmt -``` - -To set up your project with this template, run - -```sh -cargo generate --git https://github.com/leptos-rs/start-trunk -``` - -to generate your new project, then - -```sh -cd {{project-name}} -``` - -to go to your newly created project. - -By default, this template uses Rust `nightly` and requires that you've installed -the `wasm` compilation target for your toolchain. - -Sass and Tailwind are also supported by the Trunk build tool, but are optional -additions: [see here for more info on how to set those up with -Trunk][trunk-instructions]. - -If you don't have Rust nightly, you can install it with - -```sh -rustup toolchain install nightly --allow-downgrade -``` - -You can add the `wasm` compilation target to rust using - -```sh -rustup target add wasm32-unknown-unknown -``` - -## Developing your Leptos CSR project - -To develop your Leptos CSR project, running - -```sh -trunk serve --port 3000 --open -``` - -will open your app in your default browser at `http://localhost:3000`. - -## Deploying your Leptos CSR project - -To build a Leptos CSR app for release, use the command - -```sh -trunk build --release -``` - -This will output the files necessary to run your app into the `dist` folder; you -can then use any static site host to serve these files. - -For further information about hosting Leptos CSR apps, please refer to [the -Leptos Book chapter on deployment available here][deploy-csr]. - -[deploy-csr]: https://book.leptos.dev/deployment/csr.html -[leptos]: https://github.com/leptos-rs/leptos -[trunk]: https://github.com/trunk-rs/trunk -[trunk-instructions]: https://trunkrs.dev/assets/ diff --git a/Trunk.toml b/Trunk.toml index 7a8f0b4..68c3bf0 100644 --- a/Trunk.toml +++ b/Trunk.toml @@ -1,45 +1,12 @@ -[build] -target = "index.html" -release = false -dist = "dist" -public_url = "/" -filehash = true - -# Whether to inject scripts (and module preloads) into the finalized output. -inject_scripts = true - -# Run without network access -offline = false -# Require Cargo.lock and cache are up to date -frozen = false -# Require Cargo.lock is up to date -locked = false -minify = "on_release" # can be one of: never, on_release, always -# Allow disabling sub-resource integrity (SRI) -no_sri = false - -[watch] -# Paths to watch. The `build.target`'s parent folder is watched by default. -watch = [] -ignore = [] +[[hooks]] +stage = "pre_build" +command = "sh" +command_arguments = [ + "-c", + "tailwindcss -i input.css -o public/tailwindcss-output.css", +] [serve] addresses = ["127.0.0.1"] port = 3000 open = false - -# Whether to disable fallback to index.html for missing files. -# no_spa = false -# Disable auto-reload of the web app. -# no_autoreload = false -# Disable error reporting -# no_error_reporting = false -# Additional headers set for responses. -# headers = { "test-header" = "header value", "test-header2" = "header value 2" } -# Protocol used for autoreload WebSockets connection. -# ws_protocol = "ws" -# The certificate/private key pair to use for TLS, which is enabled if both are set. -# tls_key_path = "self_signed_certs/key.pem" -# tls_cert_path = "self_signed_certs/cert.pem" -# Additional headers to send. NOTE: header names must be valid HTTP headers. -# headers = { "X-Foo" = "bar" } diff --git a/flake.nix b/flake.nix index bd155ca..776e8bd 100644 --- a/flake.nix +++ b/flake.nix @@ -84,6 +84,7 @@ pkgs.trunk pkgs.wasm-bindgen-cli pkgs.dart-sass + pkgs.tailwindcss # Releng pkgs.git-bug diff --git a/index.html b/index.html index 77d81f4..6fe87e8 100644 --- a/index.html +++ b/index.html @@ -1,32 +1,31 @@ - + - - - + + - diff --git a/input.css b/input.css new file mode 100644 index 0000000..b5c61c9 --- /dev/null +++ b/input.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/public/logo.svg b/public/logo.svg deleted file mode 100644 index 9a8e2e2..0000000 --- a/public/logo.svg +++ /dev/null @@ -1,949 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/styles.scss b/public/styles.scss deleted file mode 100644 index 0b30a70..0000000 --- a/public/styles.scss +++ /dev/null @@ -1,52 +0,0 @@ -/* --------------------- Open Props --------------------------- */ - -/* the props */ -@import "https://unpkg.com/open-props"; - -/* optional imports that use the props */ -@import "https://unpkg.com/open-props/normalize.min.css"; -@import "https://unpkg.com/open-props/buttons.min.css"; - -/* ------------------------------------------------------------ */ - -body { - font-family: sans-serif; - text-align: center; -} - -.container { - display: flex; - flex-direction: column; - justify-content: space-around; - align-items: center; -} - -.buttons { - display: flex; - justify-content: space-evenly; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - text-align: center; - margin: 0 auto; - padding: 2rem; -} - -p, -button { - margin: var(--size-6); -} - -body > picture, -button { - display: block; - margin-left: auto; - margin-right: auto; - text-align: center; - margin: 2rem; -} diff --git a/src/api/mod.rs b/src/api/mod.rs new file mode 100644 index 0000000..8b9e77d --- /dev/null +++ b/src/api/mod.rs @@ -0,0 +1,50 @@ +use leptos::{ + error::Error, + prelude::{Read, expect_context}, +}; +use reactive_stores::Store; +use rocie_client::{ + apis::{ + api_get_inventory_api::amount_by_id, + api_get_product_api::{product_by_id, products}, + api_get_unit_api::unit_by_id, + }, + models::{Product, ProductAmount, ProductId, Unit, UnitId}, +}; + +use crate::{ConfigState, ConfigStateStoreFields}; + +pub(crate) async fn get_amount_by_id(product_id: ProductId) -> Result { + let config = expect_context::>(); + amount_by_id(&config.config().read(), product_id) + .await + .map_err(Into::::into) +} +pub(crate) async fn get_product_by_id(product_id: ProductId) -> Result { + let config = expect_context::>(); + product_by_id(&config.config().read(), product_id) + .await + .map_err(Into::::into) +} +pub(crate) async fn get_unit_by_id(unit_id: UnitId) -> Result { + let config = expect_context::>(); + unit_by_id(&config.config().read(), unit_id) + .await + .map_err(Into::::into) +} +pub(crate) async fn get_full_product_by_id( + id: ProductId, +) -> Result<(Product, ProductAmount, Unit), Error> { + let amount = get_amount_by_id(id).await?; + let product = get_product_by_id(id).await?; + let unit = get_unit_by_id(amount.amount.unit).await?; + + Ok::<_, Error>((product, amount, unit)) +} + +pub(crate) async fn get_products() -> Result, Error> { + let config = expect_context::>(); + products(&config.config().read()) + .await + .map_err(Into::::into) +} diff --git a/src/components/async_fetch.rs b/src/components/async_fetch.rs new file mode 100644 index 0000000..7105c6f --- /dev/null +++ b/src/components/async_fetch.rs @@ -0,0 +1,50 @@ +macro_rules! AsyncFetch { + (fetcher = $fetcher:block producer = |$bound_variable:pat_param| $producer:block) => {{ + use leptos::{ + prelude::{ElementChild, LocalResource, Suspend, Transition}, + view, + }; + + view! { + "Loading..."

} + }> + {move || Suspend::new(async move { + let resource = { LocalResource::new(move || $fetcher) }; + resource + .await + .map(|$bound_variable| $producer) + })} +
+ } + }}; +} +pub(crate) use AsyncFetch; + +// #[component] +// pub fn AsyncFetch( +// fetcher: impl Fn() -> Fut + 'static + Send + Sync, +// producer: P, +// ) -> impl IntoView +// where +// V: IntoView + 'static, +// P: Fn(T) -> V + 'static + Send + Sync, +// Fut: Future> + 'static, +// T: 'static, +// LocalResource>: IntoFuture> + Send, +// { +// view! { +// "Loading..."

} +// }> +// { || Suspend::new(async { +// let value_resource = LocalResource::new( || fetcher()); +// value_resource +// .await +// .map(|value| { +// producer(value) +// }) +// })} +//
+// } +// } diff --git a/src/components/container.rs b/src/components/container.rs index cf7aa5a..7a4a64f 100644 --- a/src/components/container.rs +++ b/src/components/container.rs @@ -1,34 +1,35 @@ use leptos::{ IntoView, component, - prelude::{Children, ClassAttribute, ElementChild}, + prelude::{Children, ClassAttribute, ElementChild, OnAttribute}, view, }; -use leptos_meta::Style; +use leptos_router::{NavigateOptions, hooks::use_navigate}; #[component] -pub fn Container(header: impl IntoView, children: Children) -> impl IntoView { +pub fn Container( + header: impl IntoView, + buttons: Vec<(impl IntoView, &'static str)>, + children: Children, +) -> impl IntoView { view! { - - -
-

{header}

+
+

{header}

{children()} + +
    + {buttons + .into_iter() + .map(|(name, path)| { + view! { +
  • + +
  • + } + }) + .collect::>()} +
} } diff --git a/src/components/icon_p.rs b/src/components/icon_p.rs new file mode 100644 index 0000000..372e280 --- /dev/null +++ b/src/components/icon_p.rs @@ -0,0 +1,18 @@ +use leptos::{ + IntoView, component, + prelude::{ClassAttribute, ElementChild, Signal}, + view, +}; +use leptos_icons::Icon; + +#[component] +pub fn IconP(#[prop(into)] icon: Signal, text: &'static str) -> impl IntoView { + view! { +
+
+ +
+

{text}

+
+ } +} diff --git a/src/components/inventory.rs b/src/components/inventory.rs new file mode 100644 index 0000000..5855b33 --- /dev/null +++ b/src/components/inventory.rs @@ -0,0 +1,55 @@ +use leptos::{ + IntoView, component, + prelude::{ClassAttribute, ElementChild}, + view, +}; + +use crate::{ + api::{get_full_product_by_id, get_products}, + components::{async_fetch::AsyncFetch, site_header::SiteHeader}, +}; + +#[component] +pub fn Inventory() -> impl IntoView { + view! { + + +
    + { + AsyncFetch! { + fetcher = {get_products()} + producer = |products| { + products + .into_iter() + .map(|product| { + view! { + {AsyncFetch! { + fetcher = {get_full_product_by_id(product.id)} + producer = |(product, amount, unit)| { + view! { +
      +
    • {product.name}
    • +
    • + + { + format!( + "{} {}", + amount.amount.value, + unit.short_name + ) + } + +
    • +
    + } + } + }} + } + }) + .collect::>() + } + } + } +
+ } +} diff --git a/src/components/mod.rs b/src/components/mod.rs index 85f9671..7174ad8 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1,6 +1,10 @@ // Generic +pub mod async_fetch; pub mod container; +pub mod icon_p; // Specific +pub mod inventory; pub mod product_overview; -pub mod side_header; +pub mod recipies; +pub mod site_header; diff --git a/src/components/product_overview.rs b/src/components/product_overview.rs index 4e95335..ae2eaf2 100644 --- a/src/components/product_overview.rs +++ b/src/components/product_overview.rs @@ -1,47 +1,40 @@ -use std::sync::Arc; +use leptos::{IntoView, component, view}; -use leptos::{ - IntoView, component, - prelude::{ElementChild, Set, signal}, - task::spawn_local, - view, +use crate::{ + api::get_products, + components::{async_fetch::AsyncFetch, container::Container, icon_p::IconP}, }; -use rocie_client::apis::{api_get_product_api::products, configuration::Configuration}; - -use crate::components::container::Container; #[component] -pub fn ProductOverview(config: Arc) -> impl IntoView { - let (read_status, write_status) = signal("Loading..".to_owned()); - - { - let local_config = Arc::clone(&config); - - spawn_local(async move { - let products = products(&local_config).await; - - write_status.set( - products - .as_ref() - .map(move |products| { - let products_num = products.len(); - let plural_s = if products_num == 1 { "" } else { "s" }; - let products_value = 2; - let products_currency = "EUR"; - format!( - "You have {products_num} product{plural_s} \ - in stock with a value \ - of {products_value} {products_currency}.", - ) - }) - .unwrap(), - ); - }); - } - +pub fn ProductOverview() -> impl IntoView { view! { - -

{read_status}

+ }, "inventory"), + (view! { }, "consume"), + (view! { }, "buy"), + ] + > + {AsyncFetch!( + fetcher = {get_products()} + producer = |products| { + let products_num = products.len(); + let plural_s = if products_num == 1 { "" } else { "s" }; + let products_value = 2; + let products_currency = "EUR"; + + view! { +

+ {format!( + "You have {products_num} product{plural_s} \ + in stock with a value \ + of {products_value} {products_currency}.", + )} +

+ } + } + )}
} } diff --git a/src/components/recipies.rs b/src/components/recipies.rs new file mode 100644 index 0000000..1bd3a0d --- /dev/null +++ b/src/components/recipies.rs @@ -0,0 +1,12 @@ +use leptos::{IntoView, component, prelude::ElementChild, view}; + +use crate::components::container::Container; + +#[component] +pub fn Recipies() -> impl IntoView { + view! { + +

"You have 0 recipies."

+
+ } +} diff --git a/src/components/side_header.rs b/src/components/side_header.rs deleted file mode 100644 index 9cd6777..0000000 --- a/src/components/side_header.rs +++ /dev/null @@ -1,22 +0,0 @@ -use leptos::prelude::{AddAnyAttr, ElementChild, IntoView, StyleAttribute, component, view}; -use leptos_router::{NavigateOptions, hooks::use_navigate}; -use thaw::{Flex, FlexJustify, LayoutHeader}; - -#[component] -pub fn SiteHeader() -> impl IntoView { - let navigate = use_navigate(); - - view! { - - - -

"Rocie"

-
-
- } -} diff --git a/src/components/site_header.rs b/src/components/site_header.rs new file mode 100644 index 0000000..65f7137 --- /dev/null +++ b/src/components/site_header.rs @@ -0,0 +1,29 @@ +use icondata_core::Icon as DataIcon; +use leptos::prelude::{ClassAttribute, ElementChild, IntoView, OnAttribute, component, view}; +use leptos_icons::Icon; +use leptos_router::{NavigateOptions, hooks::use_navigate}; + +#[component] +pub fn SiteHeader( + logo: DataIcon, + back_location: &'static str, + name: &'static str, + #[prop(default = None)] menu: Option, +) -> impl IntoView { + let navigate = use_navigate(); + + view! { +
+
+ +
+

{name}

+
{menu}
+
+ } +} diff --git a/src/lib.rs b/src/lib.rs index 357ce93..a488d95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,24 +7,38 @@ reason = "Can't add it to leptos' components" )] #![expect( - clippy::needless_pass_by_value, - reason = "Can't add it to leptos' components" + unused_extern_crates, + reason = "Deependency needed to inject the `js` feature into uuid" )] +extern crate uuid; + +// All of them are only used in the `main.rs` and not in the `lib.rs` part of this crate. +extern crate console_error_panic_hook; +extern crate console_log; +extern crate log; +mod api; mod components; mod pages; -use std::sync::Arc; - -use leptos::prelude::{AddAnyAttr, IntoView, component, view}; +use leptos::prelude::{AddAnyAttr, IntoView, component, provide_context, view}; use leptos_meta::{Html, Meta, Title, provide_meta_context}; use leptos_router::{ components::{Route, Router, Routes}, path, }; +use reactive_stores::Store; use rocie_client::apis::configuration::Configuration; -use crate::pages::{home::Home, not_found::NotFound}; +use crate::{ + components::inventory::Inventory, + pages::{home::Home, not_found::NotFound}, +}; + +#[derive(Debug, Clone, Store)] +pub struct ConfigState { + config: Configuration, +} #[component] pub fn App() -> impl IntoView { @@ -37,13 +51,15 @@ pub fn App() -> impl IntoView { config.user_agent = Some("rocie-mobile".to_owned()); "http://127.0.0.1:8080".clone_into(&mut config.base_path); - Arc::new(config) + config }; + provide_context(Store::new(ConfigState { config })); + view! { - + <Title text="Rocie-mobile" /> <Meta charset="UTF-8" /> <Meta name="viewport" content="width=device-width, initial-scale=1.0" /> @@ -53,8 +69,13 @@ pub fn App() -> impl IntoView { <Route path=path!("/") view=move || { - let local_config = Arc::clone(&config); - view! { <Home config=local_config /> } + view! { <Home /> } + } + /> + <Route + path=path!("/inventory") + view=move || { + view! { <Inventory /> } } /> </Routes> diff --git a/src/main.rs b/src/main.rs index c377484..c3eaadf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,8 @@ +#![expect( + unused_crate_dependencies, + reason = "We use them in the lib version of this crate" +)] + use leptos::prelude::{mount_to_body, view}; use rocie_mobile::App; diff --git a/src/pages/home.rs b/src/pages/home.rs index 8749860..387562e 100644 --- a/src/pages/home.rs +++ b/src/pages/home.rs @@ -1,26 +1,23 @@ -use std::sync::Arc; - use leptos::{ IntoView, component, error::ErrorBoundary, - prelude::{CollectView, ElementChild, Get, GetUntracked}, + prelude::{ClassAttribute, CollectView, ElementChild, Get, GetUntracked}, view, }; use leptos_router::{ NavigateOptions, hooks::{use_navigate, use_query_map}, }; -use rocie_client::apis::configuration::Configuration; -use thaw::{Layout, LayoutPosition}; -use crate::components::{product_overview::ProductOverview, side_header::SiteHeader}; +use crate::components::{ + product_overview::ProductOverview, recipies::Recipies, site_header::SiteHeader, +}; #[component] -pub fn Home(config: Arc<Configuration>) -> impl IntoView { +pub fn Home() -> impl IntoView { let query_map = use_query_map().get_untracked(); let navigate = use_navigate(); - // mobile page if let Some(path) = query_map.get("path") { navigate(&path, NavigateOptions::default()); } @@ -44,12 +41,11 @@ pub fn Home(config: Arc<Configuration>) -> impl IntoView { } }> - <Layout position=LayoutPosition::Absolute> - <SiteHeader /> - <Layout> - <ProductOverview config /> - </Layout> - </Layout> + <div class="flex flex-col content-start"> + <SiteHeader logo=icondata_io::IoRoseSharp back_location="/" name="Rocie" /> + <ProductOverview /> + <Recipies /> + </div> </ErrorBoundary> } } diff --git a/stalwart/Trunk.toml b/stalwart/Trunk.toml deleted file mode 100644 index 579d138..0000000 --- a/stalwart/Trunk.toml +++ /dev/null @@ -1,4 +0,0 @@ -[[hooks]] -stage = "pre_build" -command = "sh" -command_arguments = ["-c", "npx tailwindcss -i input.css -o style/output.css"] diff --git a/stalwart/index.html b/stalwart/index.html deleted file mode 100644 index e7f5dae..0000000 --- a/stalwart/index.html +++ /dev/null @@ -1,32 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - -<head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <link data-trunk rel="rust" data-wasm-opt="z" /> - - <!-- Favicon for browsers --> - <link data-trunk rel="icon" type="image/ico" href="./src/assets/favicon.ico"> - <!-- Favicon sizes for different platforms --> - <link data-trunk rel="icon" type="image/png" sizes="32x32" href="./src/assets/favicon-32x32.png"> - <link data-trunk rel="icon" type="image/png" sizes="16x16" href="./src/assets/favicon-16x16.png"> - <!-- For Android Chrome --> - <link data-trunk rel="icon" type="image/png" sizes="192x192" href="./src/assets/android-chrome-192x192.png"> - <link data-trunk rel="icon" type="image/png" sizes="512x512" href="./src/assets/android-chrome-512x512.png"> - <!-- For iOS devices --> - <link data-trunk rel="copy-file" href="./src/assets/apple-touch-icon.png" /> - <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"> - <!-- Manifest --> - <link data-trunk rel="copy-file" href="./src/assets/site.webmanifest" /> - <link rel="manifest" href="/site.webmanifest"> - <link data-trunk rel="css" href="/style/output.css" /> - <link data-trunk rel="copy-file" href="./src/assets/logo.svg" /> - - <title>Stalwart Management - - - - - - \ No newline at end of file diff --git a/stalwart/input.css b/stalwart/input.css deleted file mode 100644 index b5c61c9..0000000 --- a/stalwart/input.css +++ /dev/null @@ -1,3 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; diff --git a/stalwart/package.json b/stalwart/package.json deleted file mode 100644 index 32a2cb5..0000000 --- a/stalwart/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "stalwart-admin", - "version": "0.1.0", - "description": "", - "main": "index.js", - "scripts": { - "build": "npx tailwindcss -i ./style/input.css -o ./style/output/output.css", - "watch": "npx tailwindcss -i ./style/input.css -o ./style/output/output.css --watch" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "@tailwindcss/forms": "^0.5.7", - "@tailwindcss/typography": "^0.5.10", - "preline": "^1.9.0", - "tailwindcss": "^3.3.5" - } -} diff --git a/stalwart/tailwind.config.js b/stalwart/tailwind.config.js deleted file mode 100644 index f8dfe93..0000000 --- a/stalwart/tailwind.config.js +++ /dev/null @@ -1,36 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -module.exports = { - content: ["*.html", "./src/**/*.rs", "./node_modules/preline/dist/*.js"], - theme: { - screens: { - sm: '480px', - md: '768px', - lg: '1020px', - xl: '1440px', - }, - fontFamily: { - sans: ['Inter', 'sans-serif'], - - }, - extend: { - //https://play.tailwindcss.com/VCZwwz1e3R - animation: { - text: 'text 5s ease infinite', - }, - keyframes: { - text: { - '0%, 100%': { - 'background-size': '200% 200%', - 'background-position': 'left center', - }, - '50%': { - 'background-size': '200% 200%', - 'background-position': 'right center', - }, - }, - }, - }, - }, - darkMode: 'class', - plugins: [require('@tailwindcss/forms'), require("@tailwindcss/typography"), require("preline/plugin")], -} diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..d4be7aa --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,21 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["*.html", "./src/**/*.rs"], + theme: { + screens: { + sm: "480px", + md: "768px", + lg: "1020px", + xl: "1440px", + }, + fontFamily: { + sans: ["Inter", "sans-serif"], + }, + }, + darkMode: "class", + plugins: [ + // require('@tailwindcss/forms'), + // require("@tailwindcss/typography"), + // require("preline/plugin") + ], +}; -- cgit 1.4.1