From 348ecfdcac6e3237e045d9f8f3bfd76bcad1cbeb Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Mon, 16 May 2022 13:34:38 +0200 Subject: [PATCH] [Refactoring] Payments: Use API country list (#1881) --- src/components/payment/PaymentInfo.tsx | 11 +- src/components/payment/PaymentModal.tsx | 17 +- src/components/payment/ShippingInfo.tsx | 15 +- src/hooks/reducers/usePaymentReducer.ts | 14 +- src/util/countries.ts | 273 ------------------------ 5 files changed, 35 insertions(+), 295 deletions(-) delete mode 100644 src/util/countries.ts diff --git a/src/components/payment/PaymentInfo.tsx b/src/components/payment/PaymentInfo.tsx index e84aa6f3a..3d2302cbb 100644 --- a/src/components/payment/PaymentInfo.tsx +++ b/src/components/payment/PaymentInfo.tsx @@ -2,9 +2,10 @@ import React, { FC, useCallback, memo, useRef, useEffect, } from '../../lib/teact/teact'; +import { ApiCountry } from '../../api/types'; + import { FormState, FormEditDispatch } from '../../hooks/reducers/usePaymentReducer'; import useLang from '../../hooks/useLang'; -import countryList from '../../util/countries'; import InputText from '../ui/InputText'; import Checkbox from '../ui/Checkbox'; @@ -20,6 +21,7 @@ export type OwnProps = { needCardholderName?: boolean; needCountry?: boolean; needZip?: boolean; + countryList: ApiCountry[]; dispatch: FormEditDispatch; }; @@ -29,6 +31,7 @@ const PaymentInfo: FC = ({ needCardholderName, needCountry, needZip, + countryList, dispatch, }) => { // eslint-disable-next-line no-null/no-null @@ -121,12 +124,12 @@ const PaymentInfo: FC = ({ ref={selectCountryRef} > { - countryList.map(({ name }) => ( + countryList.map(({ defaultName, name }) => ( )) } diff --git a/src/components/payment/PaymentModal.tsx b/src/components/payment/PaymentModal.tsx index 976bba382..e5fd825a6 100644 --- a/src/components/payment/PaymentModal.tsx +++ b/src/components/payment/PaymentModal.tsx @@ -4,6 +4,7 @@ import React, { import { getActions, withGlobal } from '../../global'; import { GlobalState } from '../../global/types'; +import { ApiCountry } from '../../api/types'; import { PaymentStep, ShippingOption, Price } from '../../types'; import { formatCurrency } from '../../util/formatCurrency'; @@ -47,6 +48,7 @@ type StateProps = { needCountry?: boolean; needZip?: boolean; confirmPaymentUrl?: string; + countryList: ApiCountry[]; }; type GlobalStateProps = Pick = ({ needZip, confirmPaymentUrl, error, + countryList, }) => { const { validateRequestedInfo, @@ -115,6 +118,10 @@ const Invoice: FC = ({ const { name: fullName, phone, email, shippingAddress, } = savedInfo; + const { + countryIso2, ...shippingAddressRest + } = shippingAddress || {}; + const shippingCountry = countryIso2 && countryList.find(({ iso2 }) => iso2 === countryIso2)!.defaultName; paymentDispatch({ type: 'updateUserInfo', payload: { @@ -123,11 +130,14 @@ const Invoice: FC = ({ ? `+${phone}` : phone, email, - ...(shippingAddress || {}), + ...(shippingCountry && { + country: shippingCountry, + ...shippingAddressRest, + }), }, }); } - }, [savedInfo, paymentDispatch]); + }, [savedInfo, paymentDispatch, countryList]); const handleErrorModalClose = useCallback(() => { clearPaymentError(); @@ -181,6 +191,7 @@ const Invoice: FC = ({ needEmail={Boolean(emailRequested || emailToProvider)} needPhone={Boolean(phoneRequested || phoneToProvider)} needName={Boolean(nameRequested)} + countryList={countryList} /> ); case PaymentStep.Shipping: @@ -201,6 +212,7 @@ const Invoice: FC = ({ needCardholderName={needCardholderName} needCountry={needCountry} needZip={needZip} + countryList={countryList} /> ); case PaymentStep.Checkout: @@ -415,6 +427,7 @@ export default memo(withGlobal( needZip, error, confirmPaymentUrl, + countryList: global.countryList.general, }; }, )(Invoice)); diff --git a/src/components/payment/ShippingInfo.tsx b/src/components/payment/ShippingInfo.tsx index 4491cf30d..7ba4fe8f1 100644 --- a/src/components/payment/ShippingInfo.tsx +++ b/src/components/payment/ShippingInfo.tsx @@ -2,10 +2,11 @@ import React, { FC, useRef, useCallback, useEffect, memo, } from '../../lib/teact/teact'; +import { ApiCountry } from '../../api/types'; + import { FormState, FormEditDispatch } from '../../hooks/reducers/usePaymentReducer'; import useFocusAfterAnimation from '../../hooks/useFocusAfterAnimation'; import useLang from '../../hooks/useLang'; -import countryList from '../../util/countries'; import InputText from '../ui/InputText'; import Select from '../ui/Select'; @@ -19,6 +20,7 @@ export type OwnProps = { needPhone: boolean; needName: boolean; needAddress: boolean; + countryList: ApiCountry[]; dispatch: FormEditDispatch; }; @@ -28,6 +30,7 @@ const ShippingInfo: FC = ({ needPhone, needName, needAddress, + countryList, dispatch, }) => { // eslint-disable-next-line no-null/no-null @@ -65,8 +68,8 @@ const ShippingInfo: FC = ({ }, [dispatch]); const handleCountryChange = useCallback((e) => { - dispatch({ type: 'changeCountry', payload: e.target.value }); - }, [dispatch]); + dispatch({ type: 'changeCountry', payload: countryList.find((country) => country.iso2 === e.target.value) }); + }, [countryList, dispatch]); const handlePostCodeChange = useCallback((e) => { dispatch({ type: 'changePostCode', payload: e.target.value }); @@ -139,12 +142,12 @@ const ShippingInfo: FC = ({ error={formErrors.countryIso2} ref={selectCountryRef} > - {countryList.map(({ name, id }) => ( + {countryList.map(({ defaultName, name, iso2 }) => ( ))} diff --git a/src/hooks/reducers/usePaymentReducer.ts b/src/hooks/reducers/usePaymentReducer.ts index 75f047f6c..ab2e68bb3 100644 --- a/src/hooks/reducers/usePaymentReducer.ts +++ b/src/hooks/reducers/usePaymentReducer.ts @@ -1,5 +1,4 @@ import useReducer, { StateReducer, Dispatch } from '../useReducer'; -import countryList from '../../util/countries'; export type FormState = { streetLine1: string; @@ -94,8 +93,8 @@ const reducer: StateReducer = (state, action) => { case 'changeCountry': return { ...state, - countryIso2: action.payload, - billingCountry: getBillingCountry(action.payload), + countryIso2: action.payload.iso2, + billingCountry: action.payload.defaultName, formErrors: { ...state.formErrors, countryIso2: undefined, @@ -198,11 +197,11 @@ const reducer: StateReducer = (state, action) => { case 'changeSaveCredentials': return { ...state, saveCredentials: action.payload }; case 'updateUserInfo': - if (action.payload.countryIso2) { + if (action.payload.country) { return { ...state, ...action.payload, - billingCountry: getBillingCountry(action.payload.countryIso2), + billingCountry: action.payload.country, }; } return { ...state, ...action.payload }; @@ -219,11 +218,6 @@ const reducer: StateReducer = (state, action) => { } }; -function getBillingCountry(countryCode: string) { - const country = countryList.find(({ id }) => id === countryCode); - return country ? country.name : ''; -} - const usePaymentReducer = () => { return useReducer(reducer, INITIAL_STATE); }; diff --git a/src/util/countries.ts b/src/util/countries.ts deleted file mode 100644 index 23d0f8991..000000000 --- a/src/util/countries.ts +++ /dev/null @@ -1,273 +0,0 @@ -// This data was received from Telegram Desktop (Telegram/Resources/numbers.txt) -const DATA = `AF🇦🇫93Afghanistan333 -AO🇦🇴244Angola333 -AL🇦🇱355Albania234 -AD🇦🇩376Andorra222 -AE🇦🇪971United Arab Emirates234 -AI🇦🇮1264Anguilla34 -AR🇦🇷54Argentina -AM🇦🇲374Armenia233 -AG🇦🇬1268Antigua and Barbuda34 -AU🇦🇺61Australia333 -AS🇦🇸1684American Samoa34 -AT🇦🇹43Austria -AW🇦🇼297Aruba34 -AZ🇦🇿994Azerbaijan2322 -BI🇧🇮257Burundi224 -BE🇧🇪32Belgium3222 -BJ🇧🇯229Benin233 -BF🇧🇫226Burkina Faso2222 -BD🇧🇩880Bangladesh -BG🇧🇬359Bulgaria -BH🇧🇭973Bahrain44 -BS🇧🇸1242Bahamas34 -BA🇧🇦387Bosnia and Herzegovina -BY🇧🇾375Belarus2322 -BZ🇧🇿501Belize -BO🇧🇴591Bolivia134 -BR🇧🇷55Brazil254 -BB🇧🇧1246Barbados34 -BM🇧🇲1441Bermuda34 -BN🇧🇳673Brunei34 -BQ🇧🇶599Bonaire, Sint Eustatius and Saba -BT🇧🇹975Bhutan -BW🇧🇼267Botswana233 -CF🇨🇫236Central African Republic2222 -CA🇨🇦1Canada334 -CH🇨🇭41Switzerland234 -CK🇨🇰682Cook Islands -CL🇨🇱56Chile144 -CN🇨🇳86China344 -CI🇨🇮225Côte d\`Ivoire233 -CM🇨🇲237Cameroon44 -CD🇨🇩243DR Congo234 -CG🇨🇬242Republic of the Congo234 -CO🇨🇴57Colombia334 -KM🇰🇲269Comoros34 -CV🇨🇻238Cape Verde34 -CR🇨🇷506Costa Rica -CU🇨🇺53Cuba44 -CY🇨🇾357Cyprus44 -CW🇨🇼599Curaçao -CZ🇨🇿420Czech Republic -DE🇩🇪49Germany38 -DJ🇩🇯253Djibouti2222 -DM🇩🇲1767Dominica34 -DK🇩🇰45Denmark44 -DO🇩🇴1Dominican Republic334 -DZ🇩🇿213Algeria3222 -EC🇪🇨593Ecuador -EG🇪🇬20Egypt234 -ER🇪🇷291Eritrea133 -ES🇪🇸34Spain333 -EE🇪🇪372Estonia -ET🇪🇹251Ethiopia234 -FI🇫🇮358Finland -FJ🇫🇯679Fiji -FK🇫🇰500Falkland Islands -FM🇫🇲691Micronesia -FO🇫🇴298Faroe Islands33 -FR🇫🇷33France12222 -GA🇬🇦241Gabon1222 -GB🇬🇧44United Kingdom46 -GE🇬🇪995Georgia -GF🇬🇫594French Guiana -GH🇬🇭233Ghana -GI🇬🇮350Gibraltar44 -GL🇬🇱299Greenland33 -GN🇬🇳224Guinea333 -GM🇬🇲220Gambia34 -GP🇬🇵590Guadeloupe -GU🇬🇺1671Guam34 -GW🇬🇼245Guinea-Bissau34 -GQ🇬🇶240Equatorial Guinea333 -GR🇬🇷30Greece244 -GD🇬🇩1473Grenada34 -GT🇬🇹502Guatemala134 -GY🇬🇾592Guyana -HK🇭🇰852Hong Kong -HN🇭🇳504Honduras44 -HR🇭🇷385Croatia -HT🇭🇹509Haiti -HU🇭🇺36Hungary234 -ID🇮🇩62Indonesia -IN🇮🇳91India55 -IO🇩🇬246Diego Garcia34 -IE🇮🇪353Ireland234 -IR🇮🇷98Iran334 -IQ🇮🇶964Iraq334 -IS🇮🇸354Iceland34 -IL🇮🇱972Israel234 -IT🇮🇹39Italy334 -JM🇯🇲1876Jamaica34 -JO🇯🇴962Jordan144 -JP🇯🇵81Japan244 -KZ🇰🇿7Kazakhstan3322 -KE🇰🇪254Kenya333 -KG🇰🇬996Kyrgyzstan -KH🇰🇭855Cambodia -KI🇰🇮686Kiribati -KN🇰🇳1869Saint Kitts and Nevis34 -KR🇰🇷82South Korea -KW🇰🇼965Kuwait44 -KY🇰🇾1345Cayman Islands34 -LA🇱🇦856Laos -LB🇱🇧961Lebanon -LR🇱🇷231Liberia -LY🇱🇾218Libya234 -LC🇱🇨1758Saint Lucia34 -LI🇱🇮423Liechtenstein -LK🇱🇰94Sri Lanka234 -LS🇱🇸266Lesotho233 -LT🇱🇹370Lithuania35 -LU🇱🇺352Luxembourg -LV🇱🇻371Latvia35 -MA🇲🇦212Morocco234 -MC🇲🇨377Monaco44 -MD🇲🇩373Moldova233 -MG🇲🇬261Madagascar2232 -MP🇲🇵1670Northern Mariana Islands34 -MO🇲🇴853Macau -MS🇲🇸1664Montserrat34 -MV🇲🇻960Maldives -MX🇲🇽52Mexico -MH🇲🇭692Marshall Islands -MK🇲🇰389Macedonia -ML🇲🇱223Mali44 -MT🇲🇹356Malta2222 -MM🇲🇲95Myanmar -ME🇲🇪382Montenegro -MN🇲🇳976Mongolia -MZ🇲🇿258Mozambique234 -MQ🇲🇶596Martinique -MR🇲🇷222Mauritania44 -MU🇲🇺230Mauritius -MW🇲🇼265Malawi -MY🇲🇾60Malaysia -NA🇳🇦264Namibia234 -NC🇳🇨687New Caledonia6 -NE🇳🇪227Niger2222 -NF🇳🇫672Norfolk Island -NG🇳🇬234Nigeria -NI🇳🇮505Nicaragua44 -NL🇳🇱31Netherlands12222 -NO🇳🇴47Norway44 -NP🇳🇵977Nepal -NU🇳🇺683Niue -NR🇳🇷674Nauru -NZ🇳🇿64New Zealand -OM🇴🇲968Oman44 -PK🇵🇰92Pakistan334 -PA🇵🇦507Panama44 -PE🇵🇪51Peru333 -PF🇵🇫689French Polynesia -PH🇵🇭63Philippines334 -PM🇵🇲508Saint Pierre and Miquelon -PR🇵🇷1Puerto Rico334 -PS🇵🇸970Palestine324 -PW🇵🇼680Palau -PG🇵🇬675Papua New Guinea -PL🇵🇱48Poland333 -KP🇰🇵850North Korea -PT🇵🇹351Portugal144 -PY🇵🇾595Paraguay333 -QA🇶🇦974Qatar -RE🇷🇪262Réunion333 -RO🇷🇴40Romania333 -RU🇷🇺7Russia3322 -RW🇷🇼250Rwanda333 -SA🇸🇦966Saudi Arabia -SD🇸🇩249Sudan234 -SN🇸🇳221Senegal234 -SG🇸🇬65Singapore44 -SH🇸🇭290Saint Helena23 -SH🇸🇭247Saint Helena4 -SB🇸🇧677Solomon Islands -SL🇸🇱232Sierra Leone233 -SV🇸🇻503El Salvador44 -SM🇸🇲378San Marino334 -SO🇸🇴252Somalia233 -RS🇷🇸381Serbia234 -SS🇸🇸211South Sudan234 -ST🇸🇹239São Tomé and Príncipe25 -SR🇸🇷597Suriname34 -SK🇸🇰421Slovakia -SI🇸🇮386Slovenia -SE🇸🇪46Sweden234 -SZ🇸🇿268Swaziland44 -SC🇸🇨248Seychelles1222 -SX🇸🇽1721Sint Maarten34 -SY🇸🇾963Syria -TC🇹🇨1649Turks and Caicos Islands34 -TD🇹🇩235Chad2222 -TG🇹🇬228Togo233 -TH🇹🇭66Thailand144 -TJ🇹🇯992Tajikistan -TK🇹🇰690Tokelau -TM🇹🇲993Turkmenistan26 -TL🇹🇱670Timor-Leste -TO🇹🇴676Tonga -TT🇹🇹1868Trinidad and Tobago34 -TN🇹🇳216Tunisia233 -TR🇹🇷90Turkey334 -TV🇹🇻688Tuvalu -TW🇹🇼886Taiwan -TZ🇹🇿255Tanzania234 -UG🇺🇬256Uganda234 -UA🇺🇦380Ukraine2322 -UY🇺🇾598Uruguay44 -US🇺🇸1United States334 -UZ🇺🇿998Uzbekistan27 -VA🇻🇦3Vatican City -VC🇻🇨1784Saint Vincent and the Grenadines34 -VE🇻🇪58Venezuela334 -VG🇻🇬1284British Virgin Islands34 -VI🇻🇮1340US Virgin Islands34 -VN🇻🇳84Vietnam -VU🇻🇺678Vanuatu -WF🇼🇫681Wallis and Futuna -WS🇼🇸685Samoa -XK🇽🇰383Kosovo44 -YE🇾🇪967Yemen333 -ZA🇿🇦27South Africa234 -ZM🇿🇲260Zambia234 -ZW🇿🇼263Zimbabwe234`; - -const formatsCache: Record = {}; -export const defaultPhoneNumberFormat = /(\d{1,3})(\d{1,3})?(\d{1,3})?(\d{1,3})?(\d{1,3})?/; - -const parsed = DATA - .split('\n') - .map((str) => { - const id = str.substr(0, 2); - const flag = str.substr(2, 4); - const code = `+${str.match(/\d+/)![0]}`; - const name = str.split(/\d+/)[1]; - const format = str.match(/\d+$/); - const phoneFormat = getPhoneNumberFormat(format); - - return { - id, flag, code, name, phoneFormat, - }; - }); - -function getPhoneNumberFormat(format: RegExpMatchArray | null) { - if (!format) { - return defaultPhoneNumberFormat; - } - - const formatValue = format[0] as string; - let phoneNumberFormat; - - if (!formatsCache[formatValue]) { - const phoneNumberGroups = formatValue.split('').map(Number); - phoneNumberFormat = phoneNumberGroups.reduce((result, count, i) => { - return `${result}(\\d{1,${count}})${i > 0 ? '?' : ''}`; - }, ''); - formatsCache[formatValue] = new RegExp(`${phoneNumberFormat}${'()?'.repeat(5 - phoneNumberGroups.length)}`); - } - - return formatsCache[formatValue]; -} - -export default parsed;