tweb/src/components/popups/paymentShipping.ts
Eduard Kuzmenko 866d1c05ef Forums
2023-01-06 23:27:29 +04:00

226 lines
8.1 KiB
TypeScript

/*
* https://github.com/morethanwords/tweb
* Copyright (C) 2019-2021 Eduard Kuzmenko
* https://github.com/morethanwords/tweb/blob/master/LICENSE
*/
import PopupElement from '.';
import placeCaretAtEnd from '../../helpers/dom/placeCaretAtEnd';
import {InputInvoice, PaymentRequestedInfo, PaymentsPaymentForm, PaymentsValidatedRequestedInfo} from '../../layer';
import matchEmail from '../../lib/richTextProcessor/matchEmail';
import CheckboxField from '../checkboxField';
import CountryInputField from '../countryInputField';
import InputField from '../inputField';
import Row from '../row';
import SettingSection from '../settingSection';
import TelInputField from '../telInputField';
import {PaymentButton} from './payment';
import {createCountryZipFields, handleInputFieldsOnChange, InputFieldCorrected} from './paymentCard';
export type PaymentShippingAddress = PaymentRequestedInfo;
type ShippingFocusField = 'name' | 'email' | 'phone';
export default class PopupPaymentShipping extends PopupElement<{
finish: (o: {shippingAddress: PaymentShippingAddress, requestedInfo: PaymentsValidatedRequestedInfo}) => void
}> {
constructor(
private paymentForm: PaymentsPaymentForm,
private inputInvoice: InputInvoice,
private focus?: ShippingFocusField
) {
super('popup-payment popup-payment-shipping', {
closable: true,
overlayClosable: true,
body: true,
scrollable: true,
title: 'PaymentShippingInfo'
});
this.d();
}
private d() {
const paymentForm = this.paymentForm;
const invoice = paymentForm.invoice;
const savedInfo = this.paymentForm.saved_info;
let addressSection: SettingSection,
address1InputField: InputField,
address2InputField: InputField,
cityInputField: InputField,
stateInputField: InputField,
countryInputField: CountryInputField,
postcodeInputField: InputFieldCorrected;
if(invoice.pFlags.shipping_address_requested) {
addressSection = new SettingSection({name: 'PaymentShippingAddress', noDelimiter: true, noShadow: true});
address1InputField = new InputField({label: 'PaymentShippingAddress1Placeholder', maxLength: 64, required: true});
address2InputField = new InputField({label: 'PaymentShippingAddress2Placeholder', maxLength: 64});
cityInputField = new InputField({label: 'PaymentShippingCityPlaceholder', maxLength: 64, required: true});
stateInputField = new InputField({label: 'PaymentShippingStatePlaceholder', maxLength: 64});
const res = createCountryZipFields(true, true);
countryInputField = res.countryInputField;
postcodeInputField = res.postcodeInputField;
addressSection.content.append(...[
address1InputField,
address2InputField,
cityInputField,
stateInputField,
countryInputField,
postcodeInputField
].filter(Boolean).map((inputField) => inputField.container));
}
let receiverSection: SettingSection;
let nameInputField: InputField, emailInputField: InputField, telInputField: TelInputField;
if([invoice.pFlags.name_requested, invoice.pFlags.email_requested, invoice.pFlags.phone_requested].includes(true)) {
receiverSection = new SettingSection({name: 'PaymentShippingReceiver', noDelimiter: true, noShadow: true});
const validateEmail = () => {
const value = emailInputField.value;
const match = matchEmail(value);
if(!match || match[0].length !== value.length) {
return false;
}
return true;
};
const validatePhone = () => {
return !!telInputField.value.match(/\d/);
};
if(invoice.pFlags.name_requested) nameInputField = new InputField({label: 'PaymentShippingName', maxLength: 256, required: true});
if(invoice.pFlags.email_requested) emailInputField = new InputField({label: 'PaymentShippingEmailPlaceholder', maxLength: 64, required: true, validate: validateEmail});
if(invoice.pFlags.phone_requested) telInputField = new TelInputField({required: true, validate: validatePhone});
receiverSection.content.append(...[
nameInputField,
emailInputField,
telInputField
].filter(Boolean).map((inputField) => inputField.container));
}
const saveCheckboxField = new CheckboxField({
text: 'PaymentShippingSave',
checked: true
});
const saveRow = new Row({
checkboxField: saveCheckboxField,
subtitleLangKey: 'PaymentShippingSaveInfo'
});
(receiverSection || addressSection).content.append(saveRow.container);
this.scrollable.append(...[addressSection, receiverSection].filter(Boolean).map((section) => section.container));
const payButton = PaymentButton({
key: 'PaymentInfo.Done',
onClick: async() => {
const selectedCountry = countryInputField && countryInputField.getSelected().country;
const data: PaymentShippingAddress = {
_: 'paymentRequestedInfo',
shipping_address: selectedCountry && {
_: 'postAddress',
street_line1: address1InputField.value,
street_line2: address2InputField.value,
city: cityInputField.value,
state: stateInputField.value,
// country: countryInputField.value,
country_iso2: selectedCountry?.iso2,
post_code: postcodeInputField.value
},
name: nameInputField?.value,
email: emailInputField?.value,
phone: telInputField?.value
};
try {
const requestedInfo = await this.managers.appPaymentsManager.validateRequestedInfo(this.inputInvoice, data, saveCheckboxField?.checked);
this.dispatchEvent('finish', {
shippingAddress: data,
requestedInfo
});
this.hide();
} catch(err: any) {
const errorMap: {[err: string]: InputField} = {
ADDRESS_STREET_LINE1_INVALID: address1InputField,
ADDRESS_STREET_LINE2_INVALID: address2InputField,
ADDRESS_COUNTRY_INVALID: countryInputField,
ADDRESS_CITY_INVALID: cityInputField,
ADDRESS_STATE_INVALID: stateInputField,
ADDRESS_POSTCODE_INVALID: postcodeInputField,
REQ_INFO_NAME_INVALID: nameInputField,
REQ_INFO_EMAIL_INVALID: emailInputField,
REQ_INFO_PHONE_INVALID: telInputField
};
const inputField = errorMap[(err as ApiError).type];
if(inputField) {
inputField.setError();
(err as any).handled = true;
}
throw err;
}
}
});
this.body.append(this.btnConfirmOnEnter = payButton);
if(savedInfo) {
const shippingAddress = savedInfo.shipping_address;
if(shippingAddress) {
address1InputField.value = shippingAddress.street_line1;
address2InputField.value = shippingAddress.street_line2;
cityInputField.value = shippingAddress.city;
stateInputField.value = shippingAddress.state;
countryInputField.selectCountryByIso2(shippingAddress.country_iso2);
postcodeInputField.value = shippingAddress.post_code;
}
savedInfo.name && nameInputField && (nameInputField.value = savedInfo.name);
savedInfo.email && emailInputField && (emailInputField.value = savedInfo.email);
savedInfo.phone && telInputField && (telInputField.value = savedInfo.phone);
}
const {validate} = handleInputFieldsOnChange([
address1InputField,
address2InputField,
cityInputField,
stateInputField,
countryInputField,
postcodeInputField,
nameInputField,
emailInputField,
telInputField
].filter(Boolean), (valid) => {
payButton.disabled = !valid;
});
validate();
this.show();
let focusField: InputField;
if(this.focus) {
const focusMap: {[field in ShippingFocusField]?: InputField} = {
name: nameInputField,
email: emailInputField,
phone: telInputField
};
focusField = focusMap[this.focus];
} else {
focusField = address1InputField;
}
if(focusField) {
placeCaretAtEnd(focusField.input);
}
}
}