summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-10-02 13:16:37 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-10-02 13:16:37 +0200
commit10152a2fc2b3de942b9f08d81c81d6566003d336 (patch)
tree86f597e3bcdc87381fa9dfcd706794845e83421f /src
parentfeat(treewide): Switch to tailwindcss and add more components (diff)
downloadweb-client-10152a2fc2b3de942b9f08d81c81d6566003d336.zip
feat(buy): Add the framework for the /buy page
Diffstat (limited to '')
-rw-r--r--src/components/buy.rs38
-rw-r--r--src/components/input_placeholder.rs77
-rw-r--r--src/components/mod.rs2
-rw-r--r--src/components/product_overview.rs5
-rw-r--r--src/lib.rs8
5 files changed, 128 insertions, 2 deletions
diff --git a/src/components/buy.rs b/src/components/buy.rs
new file mode 100644
index 0000000..86e9952
--- /dev/null
+++ b/src/components/buy.rs
@@ -0,0 +1,38 @@
+use leptos::{
+ IntoView, component,
+ html::Input,
+ prelude::{ClassAttribute, ElementChild, Get, NodeRef, OnAttribute, Set, signal},
+ view,
+ web_sys::SubmitEvent,
+};
+
+use crate::components::{input_placeholder::InputPlaceholder, site_header::SiteHeader};
+
+#[component]
+pub fn Buy() -> impl IntoView {
+ let (product_barcode, set_product_barcode) = signal(String::new());
+
+ let input_element: NodeRef<Input> = NodeRef::new();
+
+ let on_submit = move |ev: SubmitEvent| {
+ // stop the page from reloading!
+ ev.prevent_default();
+
+ let value = input_element
+ .get()
+ // event handlers can only fire after the view
+ // is mounted to the DOM, so the `NodeRef` will be `Some`
+ .expect("<input> to exist")
+ .value();
+ set_product_barcode.set(value);
+ };
+
+ view! {
+ <SiteHeader logo=icondata_io::IoPricetag back_location="/" name="Buy" />
+ <form class="flex flex-col contents-start m-2 g-2" on:submit=on_submit>
+ <InputPlaceholder input_type="number" label="Product Barcode" node_ref=input_element />
+ <input type="submit" value="Submit" />
+ </form>
+ <p>"Name is: " {product_barcode}</p>
+ }
+}
diff --git a/src/components/input_placeholder.rs b/src/components/input_placeholder.rs
new file mode 100644
index 0000000..92f9926
--- /dev/null
+++ b/src/components/input_placeholder.rs
@@ -0,0 +1,77 @@
+use leptos::{
+ IntoView, component,
+ html::Input,
+ prelude::{ClassAttribute, ElementChild, GlobalAttributes, NodeRef, NodeRefAttribute},
+ view,
+};
+use uuid::Uuid;
+
+#[component]
+pub fn InputPlaceholder(
+ input_type: &'static str,
+ label: &'static str,
+ node_ref: NodeRef<Input>,
+ #[prop(default = None)] initial_value: Option<String>,
+) -> impl IntoView {
+ let id = Uuid::new_v4();
+
+ view! {
+ <div class="relative h-14">
+ <input
+ id=id.to_string()
+ type=input_type
+ class="\
+ absolute \
+ bottom-0 \
+ bg-gray-200 \
+ border-8 \
+ border-b-2 \
+ border-b-trasparent \
+ border-gray-200 \
+ focus:outline-none \
+ h-10 \
+ peer \
+ placeholder-transparent \
+ rounded-t-lg \
+ text-gray-900 \
+ w-full \
+ "
+ placeholder="sentinel value"
+ node_ref=node_ref
+ value=initial_value
+ />
+
+ // TODO: Reference `var(--tw-border-2)` instead of the `2 px` <2025-10-01>
+ <div class="
+ absolute \
+ bottom-0 \
+ h-[2px] \
+ w-full \
+ bg-gray-300 \
+ peer-focus:bg-indigo-600 \
+ " />
+
+ <label
+ for=id.to_string()
+ class="\
+ bottom-10 \
+ absolute \
+ left-0 \
+ text-gray-700 \
+ text-sm \
+ transition-all \
+ peer-focus:bottom-10 \
+ peer-focus:left-0 \
+ peer-focus:text-gray-700 \
+ peer-focus:text-sm \
+ peer-placeholder-shown:text-base \
+ peer-placeholder-shown:text-gray-400 \
+ peer-placeholder-shown:bottom-2 \
+ peer-placeholder-shown:left-2 \
+ "
+ >
+ {label}
+ </label>
+ </div>
+ }
+}
diff --git a/src/components/mod.rs b/src/components/mod.rs
index 7174ad8..55e4397 100644
--- a/src/components/mod.rs
+++ b/src/components/mod.rs
@@ -2,8 +2,10 @@
pub mod async_fetch;
pub mod container;
pub mod icon_p;
+pub mod input_placeholder;
// Specific
+pub mod buy;
pub mod inventory;
pub mod product_overview;
pub mod recipies;
diff --git a/src/components/product_overview.rs b/src/components/product_overview.rs
index ae2eaf2..d86c04d 100644
--- a/src/components/product_overview.rs
+++ b/src/components/product_overview.rs
@@ -11,7 +11,10 @@ pub fn ProductOverview() -> impl IntoView {
<Container
header="Inventory"
buttons=vec![
- (view! { <IconP icon=icondata_io::IoClipboardOutline text="Inventory" /> }, "inventory"),
+ (
+ view! { <IconP icon=icondata_io::IoClipboardOutline text="Inventory" /> },
+ "inventory",
+ ),
(view! { <IconP icon=icondata_io::IoPricetags text="Consume" /> }, "consume"),
(view! { <IconP icon=icondata_io::IoStorefront text="Buy" /> }, "buy"),
]
diff --git a/src/lib.rs b/src/lib.rs
index a488d95..3813ebb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -31,7 +31,7 @@ use reactive_stores::Store;
use rocie_client::apis::configuration::Configuration;
use crate::{
- components::inventory::Inventory,
+ components::{buy::Buy, inventory::Inventory},
pages::{home::Home, not_found::NotFound},
};
@@ -78,6 +78,12 @@ pub fn App() -> impl IntoView {
view! { <Inventory /> }
}
/>
+ <Route
+ path=path!("/buy")
+ view=move || {
+ view! { <Buy /> }
+ }
+ />
</Routes>
</Router>
}