diff options
Diffstat (limited to 'src/view/address.rs')
| -rw-r--r-- | src/view/address.rs | 213 | 
1 files changed, 213 insertions, 0 deletions
diff --git a/src/view/address.rs b/src/view/address.rs new file mode 100644 index 0000000..a30ba85 --- /dev/null +++ b/src/view/address.rs @@ -0,0 +1,213 @@ +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<Self>, +    value: Address, +    oninput: Callback<Address>, +} + +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<Address>, +    pub address_type: AddressType, +    //pub errors: Vec<String>, +} + +impl Component for AddressView { +    type Message = Msg; +    type Properties = Props; +    fn create(props: <Self as yew::Component>::Properties, link: yew::html::Scope<Self>) -> Self { +        Self { +            link, +            value: Address::new_with_type(props.address_type), +            oninput: props.oninput, +        } +    } +    fn update(&mut self, msg: <Self as yew::Component>::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: <Self as yew::Component>::Properties) -> bool {  +        self.oninput = props.oninput; +        self.value.address_type = props.address_type; +        true +    } +    fn view(&self) -> yew::virtual_dom::VNode { +        html!{ +            <div class="box"> +                <h3 class="subtitle">{ format!("{} Address", self.value.address_type.to_str()) }</h3> + +                <div class="columns is-mobile is-multiline"> + +                    { 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)) +                    ) } + +                </div> +            </div> +        } +    } +}
\ No newline at end of file  | 
