diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/view.rs | 110 |
1 files changed, 103 insertions, 7 deletions
diff --git a/src/view.rs b/src/view.rs index 38cfa58..6953496 100644 --- a/src/view.rs +++ b/src/view.rs @@ -1,21 +1,49 @@ +extern crate console_error_panic_hook; use crate::pdfgen; use wasm_bindgen::prelude::*; use js_sys; use yew::prelude::*; +use vcard::{VCard, VCardError}; +use std::panic; -struct Form { +fn init() { + panic::set_hook(Box::new(console_error_panic_hook::hook)); +} + +pub struct Form { + link: ComponentLink<Self>, + error: Option<String>, + formatted_name: String, + generated_vcard: Option<String>, +} + +pub enum Msg { + UpdateFormattedName(String), + GenerateVCard, + Nope, } impl Component for Form { - type Message = (); + type Message = Msg; type Properties = (); - fn create(_props: Self::Properties, _link: ComponentLink<Self>) -> Self { - Self { } + fn create(_props: Self::Properties, link: ComponentLink<Self>) -> Self { + Self { link, error: None, formatted_name: String::new(), generated_vcard: None } } - fn update(&mut self, _msg: Self::Message) -> ShouldRender { - false + fn update(&mut self, msg: Self::Message) -> ShouldRender { + match msg { + Msg::UpdateFormattedName(value) => self.formatted_name = String::from(value), + Msg::GenerateVCard => { + match self.generate_vcard() { + Ok(vcard) => self.generated_vcard = Some(vcard.to_string()), + Err(VCardError::FormatError(err)) => self.error = Some(err.to_string()), + Err(VCardError::EmptyFormatName) => self.error = Some(String::from("A VCard should have at least one formatted name.")), + }; + } + Msg::Nope => (), + }; + true } fn change(&mut self, _props: Self::Properties) -> ShouldRender { @@ -23,19 +51,87 @@ impl Component for Form { } fn view(&self) -> Html { + + let raw = pdfgen::genpdf(); + let data = base64::encode(&raw); + let uri_component: String = js_sys::encode_uri_component(&data).into(); + let href = format!{"data:application/pdf;base64,{}", uri_component }; + + let formatted_name_input = self.link.callback(|e: ChangeData| + match e { + ChangeData::Value(v) => Msg::UpdateFormattedName(v), + _ => Msg::Nope, + } + ); + + html!{ + <div id="form" > + { self.render_error() } + <label for="formatted_name">{ "Formatted Name" }</label> + <input type="text" id="formatted_name" onchange=formatted_name_input/> + <input id="prefix"/> + <input id="first_name"/> + <input id="middle_name"/> + <input id="last_name"/> + <input id="suffix"/> + <button id="generate-vcard" class="button primary small" onclick=self.link.callback(|_| Msg::GenerateVCard)>{ "Generate VCard" }</button> + + { self.render_pdf() } { self.render_vcard() } + </div> + } + } +} + +impl Form { + fn generate_vcard(&self) -> Result<VCard, VCardError> { + match VCard::from_formatted_name_str(&self.formatted_name) { + Ok(vcard) => Ok(vcard), + Err(err) => Err(err), + } + } + fn render_error(&self) -> Html { + if self.error.is_some() { + html!{ + <div class="alert danger"> + <p>{ self.error.as_ref().unwrap() }</p> + </div> + } + } else { + html!{} + } + } + fn render_pdf(&self) -> Html { let raw = pdfgen::genpdf(); let data = base64::encode(&raw); let uri_component: String = js_sys::encode_uri_component(&data).into(); let href = format!{"data:application/pdf;base64,{}", uri_component }; + html!{ - <a href=href download="demo.pdf" > + <a href=href download="demo.pdf" class="button success small" > { "Download PDF" } </a> } } + fn render_vcard(&self) -> Html { + if self.generated_vcard.is_some() { + let data = base64::encode(self.generated_vcard.as_ref().unwrap()); + let uri_component: String = js_sys::encode_uri_component(&data).into(); + let href = format!("data:text/vcard;base64,{}", uri_component); + + html!{ + <a href=href download=format!("{}.vcs",self.formatted_name) class="button success small"> + { "Download vCard" } + </a> + } + } else { + html!{} + } + } } + #[wasm_bindgen(start)] pub fn run_app() { + init(); App::<Form>::new().mount_to_body(); }
\ No newline at end of file |