v0.03
This commit is contained in:
@@ -4,10 +4,12 @@ use serde::{Deserialize, Serialize};
|
||||
use sycamore::prelude::*;
|
||||
use sycamore::suspense::Suspense;
|
||||
use sycamore_router::{Route, Router, RouterProps};
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
//use tokio;
|
||||
use wasm_bindgen::JsCast;
|
||||
use web_sys::{Event, HtmlInputElement, KeyboardEvent}; // 0.3.5
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
struct Docs {
|
||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||
pub struct Docs {
|
||||
key: String,
|
||||
title: String,
|
||||
first_publish_year: Option<u32>,
|
||||
@@ -21,12 +23,24 @@ struct Docs {
|
||||
time: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
struct Books {
|
||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||
pub struct Books {
|
||||
num_found: u32,
|
||||
docs: Vec<Docs>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct AppState {
|
||||
pub books: RcSignal<Books>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
// #[tokio::main]
|
||||
async fn set_books(&self, search: String) {
|
||||
self.books.set(fetch_books(search).await.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Route)]
|
||||
enum AppRoutes {
|
||||
#[to("/")]
|
||||
@@ -37,7 +51,7 @@ enum AppRoutes {
|
||||
NotFound,
|
||||
}
|
||||
|
||||
async fn fetch_books(search: &str) -> Result<Books, reqwasm::Error> {
|
||||
async fn fetch_books(search: String) -> Result<Books, reqwasm::Error> {
|
||||
let url = format!("http://127.0.0.1:8080/api/hello?search={}", search);
|
||||
let resp = Request::get(&url).send().await?;
|
||||
|
||||
@@ -45,15 +59,52 @@ async fn fetch_books(search: &str) -> Result<Books, reqwasm::Error> {
|
||||
Ok(body)
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Header<G: Html>(cx: Scope) -> View<G> {
|
||||
let app_state = use_context::<AppState>(cx);
|
||||
let value = create_signal(cx, String::new());
|
||||
let input_ref = create_node_ref(cx);
|
||||
|
||||
let handle_submit = |event: Event| {
|
||||
let event: KeyboardEvent = event.unchecked_into();
|
||||
|
||||
if event.key() == "Enter" {
|
||||
let mut task = value.get().as_ref().clone();
|
||||
task = task.trim().to_string();
|
||||
|
||||
if !task.is_empty() {
|
||||
app_state.set_books(task);
|
||||
value.set("".to_string());
|
||||
input_ref
|
||||
.get::<DomNode>()
|
||||
.unchecked_into::<HtmlInputElement>()
|
||||
.set_value("");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
view! { cx,
|
||||
header(class="header") {
|
||||
h1 { "todos" }
|
||||
input(ref=input_ref,
|
||||
class="new-todo",
|
||||
placeholder="What needs to be done?",
|
||||
bind:value=value,
|
||||
on:keyup=handle_submit,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
async fn VisitsCount<G: Html>(cx: Scope<'_>) -> View<G> {
|
||||
let books = fetch_books("foundation").await.unwrap();
|
||||
let app_state = use_context::<AppState>(cx);
|
||||
print!("Visitcounts\n");
|
||||
view! {cx,
|
||||
p {
|
||||
"Total visits: "
|
||||
span {
|
||||
(books.num_found)
|
||||
(app_state.books.get().num_found)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,9 +112,14 @@ async fn VisitsCount<G: Html>(cx: Scope<'_>) -> View<G> {
|
||||
|
||||
#[component]
|
||||
fn App<G: Html>(cx: Scope) -> View<G> {
|
||||
let app_state = AppState {
|
||||
books: create_rc_signal(Books::default()),
|
||||
};
|
||||
provide_context(cx, app_state);
|
||||
view! {
|
||||
cx,
|
||||
div {
|
||||
Header {}
|
||||
p { "Page Visit Counter" }
|
||||
Suspense(fallback=view! { cx, "Loading..." }) {
|
||||
VisitsCount {}
|
||||
@@ -106,5 +162,4 @@ fn main() {
|
||||
console_log::init_with_level(log::Level::Debug).unwrap();
|
||||
|
||||
sycamore::render(|cx| view! { cx, App {} });
|
||||
//sycamore::render(|cx| App(cx));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user