use yew::prelude::*; use vcard::properties; use vcard::parameters; use vcard::values::{self, text}; use std::collections::HashSet; use crate::util; #[derive(Clone)] pub struct Address { pub post_office_box: String, pub extension: String, pub street: String, pub locality: String, pub region: String, pub code: String, pub country: String, address_type: AddressType, } impl Address { pub fn new_with_type(address_type: AddressType) -> Self { Self { post_office_box: String::new(), extension: String::new(), street: String::new(), locality: String::new(), region: String::new(), code: String::new(), country: String::new(), address_type } } pub fn to_vcard_value(&self) -> properties::Address { let address_value = values::address_value::AddressValue::from_components( match self.post_office_box.is_empty() { true => None, false => Some(text::Component::from_str(&self.post_office_box).unwrap()), }, match self.extension.is_empty() { true => None, false => Some(text::Component::from_str(&self.extension).unwrap()), }, match self.street.is_empty() { true => None, false => Some(text::Component::from_str(&self.street).unwrap()), }, match self.locality.is_empty() { true => None, false => Some(text::Component::from_str(&self.locality).unwrap()), }, match self.region.is_empty() { true => None, false => Some(text::Component::from_str(&self.region).unwrap()), }, match self.code.is_empty() { true => None, false => Some(text::Component::from_str(&self.code).unwrap()), }, match self.country.is_empty() { true => None, false => Some(text::Component::from_str(&self.country).unwrap()), }, ); let mut address = properties::Address::from_address_value(address_value); let type_values = { let mut type_values = HashSet::new(); type_values.insert( match self.address_type { AddressType::Home => values::type_value::TypeValue::Home, AddressType::Work => values::type_value::TypeValue::Work, } ); vcard::Set::from_hash_set(type_values).unwrap() }; address.typ = Some(parameters::typ::Type::from_type_values(type_values)); address } } #[derive(Clone, Copy, PartialEq)] pub enum AddressType { Home, Work, } impl AddressType { pub fn to_str(&self) -> &str { match self { AddressType::Home => "Home", AddressType::Work => "Work", } } } pub struct AddressView { link: ComponentLink, value: Address, oninput: Callback
, } pub enum Msg { UpdatePostOfficeBox(String), UpdateExtension(String), UpdateStreet(String), UpdateLocality(String), UpdateRegion(String), UpdateCode(String), UpdateCountry(String), } #[derive(Clone, PartialEq, Properties)] pub struct Props { pub oninput: Callback
, pub address_type: AddressType, //pub errors: Vec, } impl Component for AddressView { type Message = Msg; type Properties = Props; fn create(props: ::Properties, link: yew::html::Scope) -> Self { Self { link, value: Address::new_with_type(props.address_type), oninput: props.oninput, } } fn update(&mut self, msg: ::Message) -> bool { match msg { Msg::UpdatePostOfficeBox(b) => self.value.post_office_box = b, Msg::UpdateExtension(e) => self.value.extension = e, Msg::UpdateStreet(s) => self.value.street = s, Msg::UpdateLocality(l) => self.value.locality = l, Msg::UpdateRegion(r) => self.value.region = r, Msg::UpdateCode(p) => self.value.code = p, Msg::UpdateCountry(c) => self.value.country = c, }; self.oninput.emit(self.value.clone()); true } fn change(&mut self, props: ::Properties) -> bool { self.oninput = props.oninput; self.value.address_type = props.address_type; true } fn view(&self) -> yew::virtual_dom::VNode { html!{

{ format!("{} Address", self.value.address_type.to_str()) }

{ util::text_field_input( "Post Office Box", "post_office_box", None, self.link.callback(|e: InputData| Msg::UpdatePostOfficeBox(e.value)) ) } { util::text_field_input( "Extension", "extension", None, self.link.callback(|e: InputData| Msg::UpdateExtension(e.value)) ) } { util::text_field_input( "Street", "street", None, self.link.callback(|e: InputData| Msg::UpdateStreet(e.value)) ) } { util::text_field_input( "Locality", "locality", None, self.link.callback(|e: InputData| Msg::UpdateLocality(e.value)) ) } { util::text_field_input( "Region", "region", None, self.link.callback(|e: InputData| Msg::UpdateRegion(e.value)) ) } { util::text_field_input( "Postal Code", "code", None, self.link.callback(|e: InputData| Msg::UpdateCode(e.value)) ) } { util::text_field_input( "Country", "country", None, self.link.callback(|e: InputData| Msg::UpdateCountry(e.value)) ) }
} } }