UNPKG

@progressive-development/pd-contact

Version:

Progressive Development Contact component

547 lines (533 loc) 19.3 kB
import { LitElement, css, html } from 'lit'; import { property, state, query } from 'lit/decorators.js'; import { msg, str } from '@lit/localize'; import '@progressive-development/pd-icon/pd-icon'; import '@progressive-development/pd-forms/pd-checkbox'; import '@progressive-development/pd-forms/pd-form-container'; import '@progressive-development/pd-forms/pd-form-row'; import '@progressive-development/pd-forms/pd-input'; import '@progressive-development/pd-forms/pd-select'; import '@progressive-development/pd-forms/pd-radio-group'; import { C_TYPE, C_COMPANY, C_BTWNR, C_FIRSTNAME, C_LASTNAME, C_STREET, C_CITY, C_ZIP, C_ADDITIONAL, C_PROPERTY_DATE, C_PHONE1, C_EMAIL } from '../types.js'; var __defProp = Object.defineProperty; var __decorateClass = (decorators, target, key, kind) => { var result = void 0 ; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (decorator(target, key, result) ) || result; if (result) __defProp(target, key, result); return result; }; const countryPrefixes = { de: "+49", // Deutschland be: "+32", // Belgien nl: "+31", // Niederland fr: "+33", // Frankreich es: "+34" // Spanien }; function transformPhone(phone, country) { if (!phone || typeof phone !== "string") return ""; const countryPrefix = countryPrefixes[country]; if (!countryPrefix) throw new Error(`Unbekanntes Land: ${country}`); const cleanedPhone = phone.replace(/\s+/g, "").replace(/[^0-9+]/g, ""); if (cleanedPhone.startsWith("+")) return cleanedPhone; if (cleanedPhone.startsWith("0")) return countryPrefix + cleanedPhone.slice(1); return ""; } const yearSelection = [ { value: "UNDEF", name: msg("Baujahr auswählen", { id: "pd.contact.property.year.selection" }) }, ...Array.from({ length: 2025 - 2014 + 1 }, (_, i) => { const year = (2014 + i).toString(); return { value: year, name: year }; }) ]; const _PdContact = class _PdContact extends LitElement { constructor() { super(...arguments); this.addressTitle = msg("Adresse", { id: "pd.contact.address.title" }); this.phoneMailLink = false; this.summary = false; this.withPropertyDate = false; this.requiredFields = []; this.inputFields = []; this._business = false; } static { this.styles = [ css` :host { display: block; } .contact { display: flex; flex-direction: column; } address { color: var( --pd-contact-address-col, var(--pd-default-font-content-col) ); line-height: 1.8; font-style: normal; } dl { margin: 0; padding: 0; } dt { font-weight: bold; padding-top: 10px; color: var( --pd-contact-address-title-col, var(--pd-default-font-title-col) ); } dd { font-weight: 400; font-size: 1em; margin: 0; padding: 0; } dd.larger { padding-top: 3px; padding-bottom: 5px; } .contact-form { --row-padding-top: 10px; } .link-icon { --pd-icon-bg-col-active: #859900; --pd-icon-bg-col-hover: #859900; --pd-icon-size: 14px; --pd-icon-col-active: white; } .link-item { display: flex; align-items: center; text-decoration: none; color: var(--pd-default-font-link-col, inherit); } .link-item:hover { color: var(--pd-default-font-link-col-hover, #451a46); } ` ]; } willUpdate(changedProps) { if (changedProps.has("contact") && this.contact) { this._business = this.contact.business ?? false; } } render() { return html` <div class="contact"> ${this.summary ? this._renderViewContact() : this._renderEditContact()} </div> `; } _renderEditContact() { return html` <pd-form-container id="contactContainerId" requiredFieldInfo autoTrimm> ${this.inputFields.length === 0 || this._showInput(C_TYPE) ? html` <pd-form-row> <pd-radio-group id="contactTypeRadioId" class="quarter3" label="${msg("Typ", { id: "pd.contact.label.type" })}" required initValue="${this._getRadioValue()}" @pd-form-element-change="${this._switchAddressType}" style="--group-gap: 20px;" > <pd-checkbox checkType="RADIO" initValue="${this.contact ? !this.contact.business : true}" valueName="private" >${msg("Privatperson", { id: "pd.contact.check.private" })}</pd-checkbox > <pd-checkbox checkType="RADIO" valueName="business" initValue="${this.contact ? this.contact.business || false : false}" >${msg("Unternehmen", { id: "pd.contact.check.company" })}</pd-checkbox > </pd-radio-group> </pd-form-row> ` : ""} ${this._business ? html` ${this.inputFields.length === 0 || this._showInput(C_COMPANY) ? html` <pd-form-row class="contact-form"> <pd-input id="compNameId" class="quarter3" label="${msg("Name des Unternehmen", { id: "pd.contact.label.company" })}" ?required="${this._isRequired(C_COMPANY)}" initValue="${this.contact?.companyName || ""}" valueName="companyName" autoCompleteName="organization" ></pd-input> </pd-form-row> ` : ""} ${this.inputFields.length === 0 || this._showInput(C_BTWNR) ? html` <pd-form-row class="contact-form"> <pd-input id="vatId" class="quarter3" label="${msg("USt-IdNr.", { id: "pd.contact.label.btw" })}" ?required="${this._isRequired(C_BTWNR)}" fieldType="vat" valueName="vatNr" initValue="${this.contact?.vatNr || ""}" autoCompleteName="vat" ></pd-input> </pd-form-row> ` : ""} ` : html` ${this.inputFields.length === 0 || this._showInput(C_FIRSTNAME) ? html` <pd-form-row class="contact-form"> <pd-input id="firstNameId" class="quarter3" label="${msg("Vorname", { id: "pd.contact.label.firstName" })}" valueName="firstName" initValue="${this.contact?.firstName || ""}" autoCompleteName="given-name" ?required="${this._isRequired(C_FIRSTNAME)}" ></pd-input> </pd-form-row> ` : ""} ${this.inputFields.length === 0 || this._showInput(C_LASTNAME) ? html` <pd-form-row class="contact-form"> <pd-input id="lastNameId" class="quarter3" label="${msg("Nachname", { id: "pd.contact.label.lastName" })}" valueName="lastName" initValue="${this.contact?.lastName || ""}" autoCompleteName="family-name" ?required="${this._isRequired(C_LASTNAME)}" ></pd-input> </pd-form-row> ` : ""} `} ${this.inputFields.length === 0 || this._showInput(C_STREET) ? html` <pd-form-row class="contact-form"> <pd-input id="streetId" class="quarter2" label="${msg("Strasse", { id: "pd.contact.label.street" })}" valueName="street" initValue="${this.contact?.street || ""}" autoCompleteName="street-address" ?required="${this._isRequired(C_STREET)}" ></pd-input> <pd-input id="streetNrId" class="quarter1" label="${msg("Nr.", { id: "pd.contact.label.streetNr" })}" valueName="streetNr" initValue="${this.contact?.streetNr || ""}" ?required="${this._isRequired(C_STREET)}" ></pd-input> </pd-form-row> ` : ""} ${this.inputFields.length === 0 || this._showInput(C_CITY) ? html` <pd-form-row class="contact-form"> ${this.match && this.match.zip ? html` <pd-input readonly id="zipId" class="quarter1" label="${msg("PLZ", { id: "pd.contact.label.zip" })}" valueName="zip" initValue="${this.match.zip}" ></pd-input> ` : html` <pd-input id="zipId" class="quarter1" label="${msg("PLZ", { id: "pd.contact.label.zip" })}" fieldType="number" valueName="zip" initValue="${this.contact?.zip || ""}" autoCompleteName="postal-code" ?required="${this._isRequired(C_ZIP)}" ></pd-input> `} <pd-input id="cityId" class="quarter2" label="${msg("Ort", { id: "pd.contact.label.city" })}" valueName="city" initValue="${this.contact?.city || ""}" autoCompleteName="locality" ?required="${this._isRequired(C_CITY)}" ></pd-input> </pd-form-row> ` : ""} ${this.inputFields.length === 0 || this._showInput(C_ADDITIONAL) ? html` <pd-form-row class="contact-form"> <pd-input class="quarter3" id="additionalHintId" label="${msg("Addresszusatz", { id: "pd.contact.label.additional" })}" initValue="${this.contact?.additionalHint || ""}" valueName="additionalHint" ?required="${this._isRequired(C_ADDITIONAL)}" ></pd-input> </pd-form-row> ` : ""} ${this.withPropertyDate ? html` <pd-form-row class="contact-form"> <pd-select class="quarter3" id="propertyDateId" label="${msg("Datum der Immobilie", { id: "pd.contact.label.propertyDate" })}" initValue="${this.contact?.propertyDate || ""}" .values="${yearSelection}" ?required="${this._isRequired(C_PROPERTY_DATE)}" ></pd-select> </pd-form-row> ` : ""} ${this.inputFields.length === 0 || this._showInput(C_PHONE1) ? html` <pd-form-row class="contact-form"> <pd-input id="phoneId" class="quarter3" label="${msg("Telefon", { id: "pd.contact.label.phone" })}" name="phone" valueName="phone1" initValue="${this.contact?.phone1 || ""}" fieldType="phone" autoCompleteName="tel" ?required="${this._isRequired(C_PHONE1)}" ></pd-input> </pd-form-row> ` : ""} ${this.inputFields.length === 0 || this._showInput(C_EMAIL) ? html` <pd-form-row class="contact-form"> <pd-input id="mailId" class="quarter3" label="${msg("E-mail", { id: "pd.contact.label.email" })}" fieldType="mail" valueName="email" initValue="${this.contact?.email || ""}" autoCompleteName="email" ?required="${this._isRequired(C_EMAIL)}" ></pd-input> </pd-form-row> ` : ""} </pd-form-container> `; } _getRadioValue() { if (this.contact) { return this.contact.business ? "business" : "private"; } return "private"; } _renderViewContact() { if (!this.contact) return html`<p>Contact undefined</p>`; const trPhoneNr = transformPhone( this.contact.phone1 || "", this.contact.country || "be" ); return html` <address> <dl> <dt>${this.addressTitle}</dt> <dd>${this.contact.companyName}</dd> <dd>${this.contact.vatNr}</dd> <dd>${this._getFullName()}</dd> <dd>${this._getFullStreet()}</dd> <dd>${this._getFullLocation()}</dd> ${this.contact.additionalHint ? html`<dd>${this.contact.additionalHint}</dd>` : ""} ${this.contact.propertyDate ? html`<dd> ${msg(str`Baujahr: ${this.contact.propertyDate}`, { id: "pd.contact.label.summary.propertyDate" })} </dd>` : ""} <dd>${this.contact.country}</dd> ${this.contact.phone1 ? html` <dd class="larger"> ${this.phoneMailLink && trPhoneNr ? html` <a href="tel:${trPhoneNr}" aria-label="Phone call: ${this.contact.phone1}" class="link-item" > <span style="margin-right: 8px;" >${this.contact.phone1}</span > <pd-icon activeIcon icon="phoneIcon" class="round link-icon" ></pd-icon> </a>` : this.contact.phone1} </dd>` : ""} ${this.contact.email ? html` <dd class="larger"> ${this.phoneMailLink ? html` <a href="mailto:${this.contact.email}" aria-label="Send mail: ${this.contact.email}" class="link-item" > <span style="margin-right: 8px;" >${this.contact.email}</span > <pd-icon activeIcon icon="mailIcon" class="round link-icon" ></pd-icon> </a>` : this.contact.email} </dd>` : ""} ${this.contact.btw ? html` <dt>BTW</dt> <dd>${this.contact.btw}</dd>` : ""} ${this.contact.kbc ? html` <dt>Bankgegevens</dt> <dd>${this.contact.kbc}</dd> <dd>${this.contact.bank}</dd>` : ""} </dl> </address> `; } get valid() { return this._contactForm?.valid === true; } async triggerValidate() { return this._contactForm?.triggerValidate(); } getValues() { const contactFormValues = this._contactForm?.getValues().origin; console.log("VAlues:", contactFormValues); const commonValues = { business: this._business, street: contactFormValues.street, streetNr: contactFormValues.streetNr, zip: contactFormValues.zip, city: contactFormValues.city, additionalHint: contactFormValues.additionalHint, propertyDate: contactFormValues.propertyDate, phone1: contactFormValues.phone1, email: contactFormValues.email // No input fields for following values //country?: string; //btw?: string; //kbc?: string; //bank?: string; }; return this._business ? { ...commonValues, companyName: contactFormValues.companyName, vatNr: contactFormValues.vatNr } : { ...commonValues, firstName: contactFormValues.firstName, lastName: contactFormValues.lastName }; } _switchAddressType(e) { console.log("Do switch", e); if (e.detail.name === "contactTypeRadioId") { this._business = e.detail.value === "business"; } e.stopPropagation(); } _isRequired(field) { return this.requiredFields.length > 0 ? this.requiredFields.includes(field) : false; } _showInput(field) { return this.inputFields.length > 0 ? this.inputFields.includes(field) : true; } _setFormData() { const getInput = (id) => this.shadowRoot?.getElementById(id)?.value; return { business: this._business, companyName: this._business ? getInput("compNameId") : void 0, vatNr: this._business ? getInput("vatId") : void 0, firstName: !this._business ? getInput("firstNameId") : void 0, lastName: !this._business ? getInput("lastNameId") : void 0, street: getInput("streetId"), streetNr: getInput("streetNrId"), additionalHint: getInput("additionalHintId"), propertyDate: this.withPropertyDate ? getInput("propertyDateId") : void 0, zip: getInput("zipId"), city: getInput("cityId"), phone1: getInput("phoneId"), email: getInput("mailId") }; } _getFullName() { return _PdContact._getFullVal( this.contact?.firstName, this.contact?.lastName ); } _getFullStreet() { return _PdContact._getFullVal(this.contact?.street, this.contact?.streetNr); } _getFullLocation() { return _PdContact._getFullVal(this.contact?.zip, this.contact?.city); } static _getFullVal(val1, val2, fallback = "") { return [val1, val2].filter(Boolean).join(" ") || fallback; } }; __decorateClass([ property() ], _PdContact.prototype, "addressTitle"); __decorateClass([ property({ type: Boolean }) ], _PdContact.prototype, "phoneMailLink"); __decorateClass([ property({ type: Boolean }) ], _PdContact.prototype, "summary"); __decorateClass([ property({ type: Boolean }) ], _PdContact.prototype, "withPropertyDate"); __decorateClass([ property({ type: Array }) ], _PdContact.prototype, "requiredFields"); __decorateClass([ property({ type: Array }) ], _PdContact.prototype, "inputFields"); __decorateClass([ property({ type: Object }) ], _PdContact.prototype, "contact"); __decorateClass([ property({ type: Object }) ], _PdContact.prototype, "match"); __decorateClass([ state() ], _PdContact.prototype, "_business"); __decorateClass([ query("#contactContainerId") ], _PdContact.prototype, "_contactForm"); let PdContact = _PdContact; export { PdContact };