use yew::prelude::*; use vcard::properties; use vcard::values::{self, text}; use crate::util; #[derive(Clone)] pub struct Name { pub prefix: String, pub first_name: String, pub middle_name: String, pub last_name: String, pub suffix: String, } impl Name { pub fn new() -> Self { Self { prefix: String::new(), first_name: String::new(), middle_name: String::new(), last_name: String::new(), suffix: String::new(), } } pub fn formatted_name(&self) -> String { let mut formatted_name = String::new(); if !self.prefix.is_empty() { formatted_name.push_str(&self.prefix); } if !self.first_name.is_empty() { formatted_name.push_str(" "); formatted_name.push_str(&self.first_name); } if !self.middle_name.is_empty() { formatted_name.push_str(" "); formatted_name.push_str(&self.middle_name); } if !self.last_name.is_empty() { formatted_name.push_str(" "); formatted_name.push_str(&self.last_name); } if !self.suffix.is_empty() { formatted_name.push_str(", "); formatted_name.push_str(&self.suffix); } formatted_name } pub fn to_vcard_value(&self) -> properties::Name { let name_value = values::name_value::NameValue::from_components( match self.last_name.is_empty() { true => None, false => Some(text::Component::from_str(&self.last_name).unwrap()), }, match self.first_name.is_empty() { true => None, false => Some(text::Component::from_str(&self.first_name).unwrap()), }, match self.middle_name.is_empty() { true => None, false => Some(text::Component::from_str(&self.middle_name).unwrap()), }, match self.prefix.is_empty() { true => None, false => Some(text::Component::from_str(&self.prefix).unwrap()), }, match self.suffix.is_empty() { true => None, false => Some(text::Component::from_str(&self.suffix).unwrap()), }, ); properties::Name::from_name_value(name_value) } } pub struct NameView { link: ComponentLink, value: Name, oninput: Callback, //errors: Vec, } pub enum Msg { UpdatePrefix(String), UpdateFirstName(String), UpdateMiddleName(String), UpdateLastName(String), UpdateSuffix(String), } #[derive(Clone, PartialEq, Properties)] pub struct Props { pub oninput: Callback, //pub errors: Vec, } impl Component for NameView { type Message = Msg; type Properties = Props; fn create(props: ::Properties, link: yew::html::Scope) -> Self { Self { link, value: Name::new(), oninput: props.oninput, } } fn update(&mut self, msg: ::Message) -> bool { match msg { Msg::UpdatePrefix(p) => self.value.prefix = p, Msg::UpdateFirstName(f) => self.value.first_name = f, Msg::UpdateMiddleName(m) => self.value.middle_name = m, Msg::UpdateLastName(l) => self.value.last_name = l, Msg::UpdateSuffix(s) => self.value.suffix = s, }; self.oninput.emit(self.value.clone()); true } fn change(&mut self, props: ::Properties) -> bool { self.oninput = props.oninput; true } fn view(&self) -> yew::virtual_dom::VNode { html!{

{ "Name" }

{ util::text_field_input( "Prefix", "prefix", Some("Sir"), self.link.callback(|e: InputData| Msg::UpdatePrefix(e.value)) ) } { util::text_field_input( "First name", "first_name", Some("Arthur"), self.link.callback(|e: InputData| Msg::UpdateFirstName(e.value)) ) } { util::text_field_input( "Middle name", "middle_name", Some("Charles"), self.link.callback(|e: InputData| Msg::UpdateMiddleName(e.value)) ) } { util::text_field_input( "Last name", "last_name", Some("Clarke"), self.link.callback(|e: InputData| Msg::UpdateLastName(e.value)) ) } { util::text_field_input( "Suffix", "suffix", Some("CBE FRAS"), self.link.callback(|e: InputData| Msg::UpdateSuffix(e.value)) ) }
} } }