Skip to content

Instantly share code, notes, and snippets.

@Niedzwiedzw
Created October 15, 2023 16:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Niedzwiedzw/cfa64e176fd7bbc4f414e464367738dd to your computer and use it in GitHub Desktop.
Save Niedzwiedzw/cfa64e176fd7bbc4f414e464367738dd to your computer and use it in GitHub Desktop.
bimber_flight_booker.rs
use super::*;
use bimber_core::{element_builder::ElementBuilder, web_sys::InputEvent, MouseEvent};
use chrono::NaiveDate;
pub enum FlightBookerMessage {
SetMode(FlightBookerMode),
}
#[derive(Debug)]
pub enum FlightBookerMode {
OneWayFlight {
start: chrono::NaiveDate,
},
ReturnFlight {
start: chrono::NaiveDate,
end: chrono::NaiveDate,
},
}
impl std::default::Default for FlightBookerMode {
fn default() -> Self {
Self::OneWayFlight { start: today() }
}
}
#[derive(Default, Debug)]
pub struct FlightBooker {
mode: FlightBookerMode,
}
impl HandleMessage<FlightBookerMessage> for FlightBooker {
fn handle(&mut self, message: FlightBookerMessage) {
match message {
FlightBookerMessage::SetMode(mode) => self.mode = mode,
}
}
}
fn today() -> NaiveDate {
chrono::Local::now().date_naive()
}
fn app(communicator: Communicator<FlightBookerMessage>, inner: &FlightBooker) -> ElementBuilder {
let body = {
let one_way_flight = "One way flight";
let return_flight = "Return flight";
let select = el("select")
.attribute(
"value",
match inner.mode {
FlightBookerMode::OneWayFlight { .. } => one_way_flight,
FlightBookerMode::ReturnFlight { .. } => return_flight,
},
)
.child(
el("option")
.attribute("value", one_way_flight)
.text(one_way_flight)
.event((), "mousedown", move |_: MouseEvent| {
communicator.send(FlightBookerMessage::SetMode(
FlightBookerMode::OneWayFlight { start: today() },
))
}),
)
.child(
el("option")
.attribute("value", return_flight)
.text(return_flight)
.event((), "click", move |_: MouseEvent| {
communicator.send(FlightBookerMessage::SetMode(
FlightBookerMode::ReturnFlight {
start: today(),
end: today(),
},
))
}),
);
let inputs = {
let container = el("div");
match inner.mode {
FlightBookerMode::OneWayFlight { start } => container.key("one-way").child(
el("input").input_value(start.to_string()).event(
(),
"input",
move |input: InputEvent| {
if let Ok(start) = input.value() {
communicator.send(FlightBookerMessage::SetMode(
FlightBookerMode::OneWayFlight { start },
))
}
},
),
),
FlightBookerMode::ReturnFlight { start, end } => container
.key("return")
.child(el("input").input_value(start.to_string()).event(
(),
"input",
move |input: InputEvent| {
if let Ok(start) = input.value() {
communicator.send(FlightBookerMessage::SetMode(
FlightBookerMode::ReturnFlight { start, end },
))
}
},
))
.child(el("input").input_value(end.to_string()).event(
(),
"input",
move |input: InputEvent| {
if let Ok(end) = input.value() {
communicator.send(FlightBookerMessage::SetMode(
FlightBookerMode::ReturnFlight { start, end },
))
}
},
)),
}
};
el("div").child(select).child(inputs)
};
el("main")
.attribute("class", "flight-booker")
.child(el("h3").text("7 GUIs: Flight Booker"))
.child(el("div").child(body))
.child(el("div").text(format!("{inner:#?}")))
}
impl ToLazyHtml for WithCommunicator<FlightBooker, FlightBookerMessage> {
fn to_lazy_html(&self) -> ElementBuilder {
let Self {
inner,
communicator,
} = self;
app(*communicator, inner)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment