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 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
}
+// }>
+// { || 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}
{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! {
+
+ }
+}
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! {
-
+
@@ -53,8 +69,13 @@ pub fn App() -> impl IntoView {
}
+ view! { }
+ }
+ />
+ }
}
/>
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) -> 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) -> impl IntoView {
}
}>
-
-
-
-
-
-
+
}
}
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 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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