mirror of
https://github.com/valitydev/checkout.git
synced 2024-11-06 02:25:18 +00:00
TD-697: Bump typescript, prettier, eslint (#228)
This commit is contained in:
parent
0317ed841b
commit
f06f7f9461
55
.eslintrc.js
Normal file
55
.eslintrc.js
Normal file
@ -0,0 +1,55 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react/jsx-runtime',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'prettier',
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint', 'import', 'react'],
|
||||
root: true,
|
||||
rules: {
|
||||
'import/order': [
|
||||
'error',
|
||||
{
|
||||
alphabetize: {
|
||||
caseInsensitive: true,
|
||||
order: 'asc',
|
||||
},
|
||||
groups: [['builtin', 'external'], 'internal', ['parent', 'sibling', 'index'], 'object'],
|
||||
'newlines-between': 'always',
|
||||
pathGroups: [
|
||||
{
|
||||
group: 'internal',
|
||||
pattern: 'checkout/**',
|
||||
},
|
||||
],
|
||||
pathGroupsExcludedImportTypes: ['builtin'],
|
||||
},
|
||||
],
|
||||
'react/jsx-filename-extension': ['error', { extensions: ['.tsx', '.ts'] }],
|
||||
'react/jsx-max-depth': ['error', { max: 3 }],
|
||||
'react/jsx-sort-props': [
|
||||
'error',
|
||||
{
|
||||
callbacksLast: true,
|
||||
ignoreCase: false,
|
||||
locale: 'auto',
|
||||
multiline: 'last',
|
||||
noSortAlphabetically: false,
|
||||
reservedFirst: true,
|
||||
shorthandFirst: true,
|
||||
},
|
||||
],
|
||||
'react/require-default-props': [0],
|
||||
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'no-case-declarations': 'off',
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
};
|
2
.github/workflows/basic-linters.yml
vendored
2
.github/workflows/basic-linters.yml
vendored
@ -3,7 +3,7 @@ name: Vality basic linters
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "*"
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
|
31
.github/workflows/pr.yaml
vendored
31
.github/workflows/pr.yaml
vendored
@ -15,8 +15,8 @@ jobs:
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}
|
||||
check:
|
||||
name: Check
|
||||
lint-format-check:
|
||||
name: Lint and prettier check
|
||||
runs-on: ubuntu-latest
|
||||
needs: [init]
|
||||
steps:
|
||||
@ -26,14 +26,22 @@ jobs:
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}
|
||||
- name: Init NodeJS
|
||||
uses: actions/setup-node@v3
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
- name: Prettier
|
||||
run: npm run prettier
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
needs: [init]
|
||||
steps:
|
||||
- name: Cache
|
||||
uses: actions/cache@v3
|
||||
id: cache
|
||||
with:
|
||||
node-version: '16.13.2'
|
||||
cache: 'npm'
|
||||
- name: Check
|
||||
run: npm run check
|
||||
- name: Run tests
|
||||
path: ./*
|
||||
key: ${{ github.sha }}
|
||||
- name: Test
|
||||
run: npm run test
|
||||
build:
|
||||
name: Build
|
||||
@ -46,10 +54,5 @@ jobs:
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}
|
||||
- name: Init NodeJS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '16.13.2'
|
||||
cache: 'npm'
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
@ -1,38 +1,7 @@
|
||||
# Exclude everything by default
|
||||
/**/*
|
||||
|
||||
# Include all folders
|
||||
!/**/*/
|
||||
|
||||
# Includes
|
||||
!*.js
|
||||
!*.jsx
|
||||
|
||||
!*.ts
|
||||
!*.tsx
|
||||
|
||||
!*.css
|
||||
!*.scss
|
||||
|
||||
!*.html
|
||||
!*.md
|
||||
!*.svg
|
||||
|
||||
!*.json
|
||||
!*.prettierrc
|
||||
!*.babelrc
|
||||
|
||||
# Excludes
|
||||
package-lock.json
|
||||
package.json
|
||||
node_modules
|
||||
dist
|
||||
|
||||
# VS Code
|
||||
.vscode
|
||||
|
||||
# IDEA
|
||||
.idea
|
||||
|
||||
# Crowdin formats json in his own way
|
||||
src/locale/*.json
|
||||
|
@ -2,8 +2,6 @@
|
||||
"printWidth": 120,
|
||||
"tabWidth": 4,
|
||||
"singleQuote": true,
|
||||
"jsxBracketSameLine": true,
|
||||
"arrowParens": "always",
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.svg",
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
@ -3,6 +3,6 @@ module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'jest-environment-jsdom',
|
||||
moduleNameMapper: {
|
||||
'^checkout/(.*)': '<rootDir>/src/app/$1'
|
||||
}
|
||||
'^checkout/(.*)': '<rootDir>/src/app/$1',
|
||||
},
|
||||
};
|
||||
|
6919
package-lock.json
generated
6919
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
23
package.json
23
package.json
@ -6,15 +6,13 @@
|
||||
"dev": "vite --c vite.config.app.ts",
|
||||
"build:app": "vite build --c vite.config.app.ts",
|
||||
"build:checkout": "vite build --c vite.config.checkout.ts",
|
||||
"build": "npm run build:checkout && npm run build:app",
|
||||
"build": "tsc && npm run build:checkout && npm run build:app",
|
||||
"preview": "npm run build && vite --c vite.config.preview.ts",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"prettier:fix": "prettier \"**\" --write",
|
||||
"prettier:check": "prettier \"**\" --list-different",
|
||||
"lint:fix": "tslint \"src/**/*.@(ts|tsx)\" -e \"**/*.d.ts\"",
|
||||
"check": "npm run lint:fix; npm run prettier:check",
|
||||
"fix": "npm run lint:fix; npm run prettier:fix"
|
||||
"prettier": "prettier * --list-different --ignore-unknown",
|
||||
"prettier:fix": "prettier * --write --ignore-unknown",
|
||||
"lint": "eslint -c .eslintrc.js --ext .ts,.tsx ."
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@ -45,17 +43,18 @@
|
||||
"@types/react": "18.2.14",
|
||||
"@types/react-dom": "18.2.6",
|
||||
"@types/react-test-renderer": "18.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "6.4.0",
|
||||
"@vitejs/plugin-react": "4.0.3",
|
||||
"eslint": "8.47.0",
|
||||
"eslint-config-prettier": "9.0.0",
|
||||
"eslint-plugin-import": "2.28.0",
|
||||
"eslint-plugin-react": "7.33.1",
|
||||
"jest": "29.5.0",
|
||||
"jest-environment-jsdom": "29.5.0",
|
||||
"prettier": "~1.19.1",
|
||||
"prettier": "3.0.1",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"ts-jest": "29.1.0",
|
||||
"tslint": "~5.11.0",
|
||||
"tslint-config-prettier": "~1.18.0",
|
||||
"tslint-immutable": "~4.5.1",
|
||||
"tslint-react": "~3.6.0",
|
||||
"typescript": "4.5.4",
|
||||
"typescript": "5.1.6",
|
||||
"vite": "4.4.6",
|
||||
"vite-plugin-static-copy": "0.17.0",
|
||||
"vite-plugin-svgr": "3.2.0",
|
||||
|
@ -1,16 +1,17 @@
|
||||
import { InvoiceAndToken, InvoiceParamsWithTemplate } from 'checkout/backend/model';
|
||||
|
||||
import { fetchCapi } from '.';
|
||||
import v from './capi-version';
|
||||
import { InvoiceAndToken, InvoiceParamsWithTemplate } from 'checkout/backend/model';
|
||||
|
||||
export const createInvoiceWithTemplate = (
|
||||
capiEndpoint: string,
|
||||
accessToken: string,
|
||||
invoiceTemplateID: string,
|
||||
params: InvoiceParamsWithTemplate
|
||||
params: InvoiceParamsWithTemplate,
|
||||
): Promise<InvoiceAndToken> =>
|
||||
fetchCapi({
|
||||
method: 'POST',
|
||||
endpoint: `${capiEndpoint}/${v}/processing/invoice-templates/${invoiceTemplateID}/invoices`,
|
||||
accessToken,
|
||||
body: params
|
||||
body: params,
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { ClientInfo, PaymentResource, PaymentTool } from 'checkout/backend/model';
|
||||
|
||||
import v from './capi-version';
|
||||
import { fetchCapi } from './fetch-capi';
|
||||
|
||||
@ -6,7 +7,7 @@ export const createPaymentResource = (
|
||||
capiEndpoint: string,
|
||||
accessToken: string,
|
||||
paymentTool: PaymentTool,
|
||||
clientInfo: ClientInfo
|
||||
clientInfo: ClientInfo,
|
||||
): Promise<PaymentResource> =>
|
||||
fetchCapi<PaymentResource>({
|
||||
endpoint: `${capiEndpoint}/${v}/processing/payment-resources`,
|
||||
@ -14,6 +15,6 @@ export const createPaymentResource = (
|
||||
method: 'POST',
|
||||
body: {
|
||||
paymentTool,
|
||||
clientInfo
|
||||
}
|
||||
clientInfo,
|
||||
},
|
||||
});
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { PaymentParams, Payment } from './model';
|
||||
import v from './capi-version';
|
||||
import { fetchCapi } from './fetch-capi';
|
||||
import { PaymentParams, Payment } from './model';
|
||||
|
||||
export const createPayment = (
|
||||
capiEndpoint: string,
|
||||
accessToken: string,
|
||||
invoiceID: string,
|
||||
paymentParams: PaymentParams
|
||||
paymentParams: PaymentParams,
|
||||
): Promise<Payment> =>
|
||||
fetchCapi({
|
||||
method: 'POST',
|
||||
endpoint: `${capiEndpoint}/${v}/processing/invoices/${invoiceID}/payments`,
|
||||
accessToken,
|
||||
body: paymentParams
|
||||
body: paymentParams,
|
||||
});
|
||||
|
@ -3,14 +3,14 @@ import { fetchCapi } from './fetch-capi';
|
||||
describe('fetch capi', () => {
|
||||
test('should do GET request', async () => {
|
||||
const expected = {
|
||||
someField: 'someValue'
|
||||
someField: 'someValue',
|
||||
};
|
||||
|
||||
const mockFetch = jest.fn();
|
||||
mockFetch.mockResolvedValue({
|
||||
status: 200,
|
||||
ok: true,
|
||||
json: async () => expected
|
||||
json: async () => expected,
|
||||
});
|
||||
global.fetch = mockFetch;
|
||||
|
||||
@ -25,22 +25,22 @@ describe('fetch capi', () => {
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
'Content-Type': 'application/json;charset=utf-8',
|
||||
'X-Request-ID': expect.any(String)
|
||||
'X-Request-ID': expect.any(String),
|
||||
},
|
||||
method: 'GET'
|
||||
method: 'GET',
|
||||
});
|
||||
});
|
||||
|
||||
test('should do POST request', async () => {
|
||||
const expected = {
|
||||
someField: 'someValue'
|
||||
someField: 'someValue',
|
||||
};
|
||||
|
||||
const mockFetch = jest.fn();
|
||||
mockFetch.mockResolvedValue({
|
||||
status: 200,
|
||||
ok: true,
|
||||
json: async () => expected
|
||||
json: async () => expected,
|
||||
});
|
||||
global.fetch = mockFetch;
|
||||
|
||||
@ -57,9 +57,9 @@ describe('fetch capi', () => {
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
'Content-Type': 'application/json;charset=utf-8',
|
||||
'X-Request-ID': expect.any(String)
|
||||
'X-Request-ID': expect.any(String),
|
||||
},
|
||||
method
|
||||
method,
|
||||
});
|
||||
});
|
||||
|
||||
@ -69,7 +69,7 @@ describe('fetch capi', () => {
|
||||
mockFetch.mockResolvedValue({
|
||||
status: 500,
|
||||
ok: false,
|
||||
statusText
|
||||
statusText,
|
||||
});
|
||||
global.fetch = mockFetch;
|
||||
|
||||
@ -78,14 +78,18 @@ describe('fetch capi', () => {
|
||||
try {
|
||||
await fetchCapi({ endpoint, accessToken });
|
||||
} catch (error) {
|
||||
expect(error).toStrictEqual({ status: 500, statusText, details: undefined });
|
||||
expect(error).toStrictEqual({
|
||||
status: 500,
|
||||
statusText,
|
||||
details: undefined,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('should retry json reject', async () => {
|
||||
const errorMsg = 'Read json error';
|
||||
const expected = {
|
||||
someField: 'someValue'
|
||||
someField: 'someValue',
|
||||
};
|
||||
const mockFetchJson = jest
|
||||
.fn()
|
||||
@ -95,7 +99,7 @@ describe('fetch capi', () => {
|
||||
const mockFetch = jest.fn().mockResolvedValue({
|
||||
status: 200,
|
||||
ok: true,
|
||||
json: mockFetchJson
|
||||
json: mockFetchJson,
|
||||
});
|
||||
global.fetch = mockFetch;
|
||||
|
||||
@ -112,7 +116,7 @@ describe('fetch capi', () => {
|
||||
|
||||
test('should retry failed fetch requests', async () => {
|
||||
const expected = {
|
||||
someField: 'someValue'
|
||||
someField: 'someValue',
|
||||
};
|
||||
|
||||
const mockFetch = jest
|
||||
@ -122,7 +126,7 @@ describe('fetch capi', () => {
|
||||
.mockResolvedValueOnce({
|
||||
status: 200,
|
||||
ok: true,
|
||||
json: async () => expected
|
||||
json: async () => expected,
|
||||
});
|
||||
global.fetch = mockFetch;
|
||||
|
||||
@ -140,9 +144,9 @@ describe('fetch capi', () => {
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
'Content-Type': 'application/json;charset=utf-8',
|
||||
'X-Request-ID': expect.any(String)
|
||||
'X-Request-ID': expect.any(String),
|
||||
},
|
||||
method: 'GET'
|
||||
method: 'GET',
|
||||
};
|
||||
expect(mockFetch).toHaveBeenCalledWith(endpoint, requestInit);
|
||||
expect(mockFetch).toHaveBeenCalledWith(endpoint, requestInit);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import guid from 'checkout/utils/guid';
|
||||
import delay from 'checkout/utils/delay';
|
||||
import guid from 'checkout/utils/guid';
|
||||
|
||||
export type FetchCapiParams = {
|
||||
endpoint: string;
|
||||
@ -25,7 +25,7 @@ const provideResponse = async (response: Response, retryDelay: number, retryLimi
|
||||
return Promise.reject({
|
||||
status: response.status,
|
||||
statusText: response.statusText || undefined,
|
||||
details: await getDetails(response)
|
||||
details: await getDetails(response),
|
||||
});
|
||||
} catch (ex) {
|
||||
if (attempt === retryLimit) {
|
||||
@ -44,9 +44,9 @@ const doFetch = async (param: FetchCapiParams, retryDelay: number, retryLimit: n
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=utf-8',
|
||||
Authorization: param.accessToken ? `Bearer ${param.accessToken}` : undefined,
|
||||
'X-Request-ID': guid()
|
||||
'X-Request-ID': guid(),
|
||||
},
|
||||
body: param.body ? JSON.stringify(param.body) : undefined
|
||||
body: param.body ? JSON.stringify(param.body) : undefined,
|
||||
});
|
||||
} catch (ex) {
|
||||
if (attempt === retryLimit) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { AppConfig } from './app-config';
|
||||
import { getNocacheValue } from 'checkout/utils';
|
||||
|
||||
import { AppConfig } from './app-config';
|
||||
import { fetchCapi } from './fetch-capi';
|
||||
|
||||
export const getAppConfig = (): Promise<AppConfig> =>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { getNocacheValue } from 'checkout/utils';
|
||||
|
||||
import { fetchCapi } from './fetch-capi';
|
||||
|
||||
export interface Env {
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { InvoiceEvent } from 'checkout/backend/model';
|
||||
|
||||
import { fetchCapi } from '.';
|
||||
import v from './capi-version';
|
||||
import { InvoiceEvent } from 'checkout/backend/model';
|
||||
|
||||
export const getInvoiceEvents = (
|
||||
capiEndpoint: string,
|
||||
accessToken: string,
|
||||
invoiceID: string,
|
||||
limit: number = 50,
|
||||
eventID?: number
|
||||
eventID?: number,
|
||||
): Promise<InvoiceEvent[]> => {
|
||||
let endpoint = `${capiEndpoint}/${v}/processing/invoices/${invoiceID}/events?limit=${limit}`;
|
||||
endpoint = eventID ? endpoint + `&eventID=${eventID}` : endpoint;
|
||||
|
@ -4,9 +4,9 @@ import v from './capi-version';
|
||||
export const getInvoicePaymentMethodsByTemplateID = (
|
||||
capiEndpoint: string,
|
||||
accessToken: string,
|
||||
invoiceTemplateID: string
|
||||
invoiceTemplateID: string,
|
||||
): Promise<PaymentMethod[]> =>
|
||||
fetchCapi({
|
||||
endpoint: `${capiEndpoint}/${v}/processing/invoice-templates/${invoiceTemplateID}/payment-methods`,
|
||||
accessToken
|
||||
accessToken,
|
||||
});
|
||||
|
@ -4,9 +4,9 @@ import v from './capi-version';
|
||||
export const getInvoicePaymentMethods = (
|
||||
capiEndpoint: string,
|
||||
accessToken: string,
|
||||
invoiceID: string
|
||||
invoiceID: string,
|
||||
): Promise<PaymentMethod[]> =>
|
||||
fetchCapi({
|
||||
endpoint: `${capiEndpoint}/${v}/processing/invoices/${invoiceID}/payment-methods`,
|
||||
accessToken
|
||||
accessToken,
|
||||
});
|
||||
|
@ -4,9 +4,9 @@ import v from './capi-version';
|
||||
export const getInvoiceTemplateByID = (
|
||||
capiEndpoint: string,
|
||||
accessToken: string,
|
||||
invoiceTemplateID: string
|
||||
invoiceTemplateID: string,
|
||||
): Promise<InvoiceTemplate> =>
|
||||
fetchCapi({
|
||||
endpoint: `${capiEndpoint}/${v}/processing/invoice-templates/${invoiceTemplateID}`,
|
||||
accessToken
|
||||
accessToken,
|
||||
});
|
||||
|
@ -4,5 +4,5 @@ import v from './capi-version';
|
||||
export const getInvoiceByID = (capiEndpoint: string, accessToken: string, invoiceID: string): Promise<Invoice> =>
|
||||
fetchCapi({
|
||||
endpoint: `${capiEndpoint}/${v}/processing/invoices/${invoiceID}`,
|
||||
accessToken
|
||||
accessToken,
|
||||
});
|
||||
|
@ -1,7 +1,10 @@
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { detectLocale } from '../../locale';
|
||||
import { getNocacheValue } from 'checkout/utils';
|
||||
|
||||
import { fetchCapi } from './fetch-capi';
|
||||
import { detectLocale } from '../../locale';
|
||||
|
||||
export const getLocale = (locale: string): Promise<Locale> =>
|
||||
fetchCapi({ endpoint: `../v1/locale/${detectLocale(locale)}.json?nocache=${getNocacheValue()}` });
|
||||
fetchCapi({
|
||||
endpoint: `../v1/locale/${detectLocale(locale)}.json?nocache=${getNocacheValue()}`,
|
||||
});
|
||||
|
@ -4,9 +4,9 @@ import v from './capi-version';
|
||||
export const getServiceProviderByID = (
|
||||
capiEndpoint: string,
|
||||
accessToken: string,
|
||||
serviceProviderID: string
|
||||
serviceProviderID: string,
|
||||
): Promise<ServiceProvider> =>
|
||||
fetchCapi({
|
||||
endpoint: `${capiEndpoint}/${v}/processing/service-providers/${serviceProviderID}`,
|
||||
accessToken
|
||||
accessToken,
|
||||
});
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { PaymentMethod } from './payment-method';
|
||||
import { PaymentSystem } from './payment-system';
|
||||
import { PaymentMethod, PaymentMethodName } from './payment-method';
|
||||
|
||||
export class BankCard extends PaymentMethod {
|
||||
method: PaymentMethodName.BankCard;
|
||||
paymentSystems: PaymentSystem[];
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { PaymentMethod, PaymentMethodName } from './payment-method';
|
||||
import { PaymentMethod } from './payment-method';
|
||||
|
||||
export class DigitalWallet extends PaymentMethod {
|
||||
method: PaymentMethodName.DigitalWallet;
|
||||
providers: string[];
|
||||
}
|
||||
|
@ -4,5 +4,5 @@ export enum InvoiceChangeType {
|
||||
PaymentInteractionRequested = 'PaymentInteractionRequested',
|
||||
PaymentInteractionCompleted = 'PaymentInteractionCompleted',
|
||||
PaymentStarted = 'PaymentStarted',
|
||||
PaymentStatusChanged = 'PaymentStatusChanged'
|
||||
PaymentStatusChanged = 'PaymentStatusChanged',
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { InvoiceChangeType } from 'checkout/backend/model/event/invoice-change-type';
|
||||
|
||||
import { InvoiceChange } from './invoice-change';
|
||||
import { Invoice } from '../invoice';
|
||||
import { InvoiceChangeType } from 'checkout/backend/model/event/invoice-change-type';
|
||||
|
||||
export class InvoiceCreated extends InvoiceChange {
|
||||
changeType = InvoiceChangeType.InvoiceCreated;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { InvoiceChange } from 'checkout/backend/model/event/invoice-change';
|
||||
|
||||
import { Event } from './event';
|
||||
|
||||
export class InvoiceEvent extends Event<InvoiceChange> {}
|
||||
|
@ -6,7 +6,7 @@ export enum InvoiceStatuses {
|
||||
cancelled = 'cancelled',
|
||||
fulfilled = 'fulfilled',
|
||||
unpaid = 'unpaid',
|
||||
refunded = 'refunded'
|
||||
refunded = 'refunded',
|
||||
}
|
||||
|
||||
export class InvoiceStatusChanged extends InvoiceChange {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { InvoiceChange } from './invoice-change';
|
||||
import { Payment } from '../payment';
|
||||
import { InvoiceChangeType } from './invoice-change-type';
|
||||
import { Payment } from '../payment';
|
||||
|
||||
export class PaymentStarted extends InvoiceChange {
|
||||
changeType = InvoiceChangeType.PaymentStarted;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { PaymentError } from 'checkout/backend';
|
||||
|
||||
import { InvoiceChange } from './invoice-change';
|
||||
import { InvoiceChangeType } from './invoice-change-type';
|
||||
import { PaymentError } from 'checkout/backend';
|
||||
|
||||
export enum PaymentStatuses {
|
||||
processed = 'processed',
|
||||
@ -8,7 +9,7 @@ export enum PaymentStatuses {
|
||||
cancelled = 'cancelled',
|
||||
pending = 'pending',
|
||||
captured = 'captured',
|
||||
refunded = 'refunded'
|
||||
refunded = 'refunded',
|
||||
}
|
||||
|
||||
export class PaymentStatusChanged extends InvoiceChange {
|
||||
|
@ -1,5 +1,5 @@
|
||||
export enum InteractionType {
|
||||
Redirect = 'Redirect',
|
||||
PaymentTerminalReceipt = 'PaymentTerminalReceipt',
|
||||
QrCodeDisplayRequest = 'QrCodeDisplayRequest'
|
||||
QrCodeDisplayRequest = 'QrCodeDisplayRequest',
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { UserInteraction } from './user-interaction';
|
||||
import { BrowserRequest } from './browser-request';
|
||||
import { UserInteraction } from './user-interaction';
|
||||
|
||||
export class Redirect extends UserInteraction {
|
||||
request: BrowserRequest;
|
||||
|
@ -1,4 +1,4 @@
|
||||
export enum RequestType {
|
||||
BrowserGetRequest = 'BrowserGetRequest',
|
||||
BrowserPostRequest = 'BrowserPostRequest'
|
||||
BrowserPostRequest = 'BrowserPostRequest',
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ export enum InvoiceStatus {
|
||||
paid = 'paid',
|
||||
cancelled = 'cancelled',
|
||||
refunded = 'refunded',
|
||||
fulfilled = 'fulfilled'
|
||||
fulfilled = 'fulfilled',
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { InvoiceTemplate } from './invoice-template';
|
||||
import { AccessToken } from './access-token';
|
||||
import { InvoiceTemplate } from './invoice-template';
|
||||
|
||||
export class InvoiceTemplateAndToken {
|
||||
invoiceTemplate: InvoiceTemplate;
|
||||
|
@ -1,5 +1,5 @@
|
||||
export enum CostType {
|
||||
InvoiceTemplateLineCostFixed = 'InvoiceTemplateLineCostFixed',
|
||||
InvoiceTemplateLineCostRange = 'InvoiceTemplateLineCostRange',
|
||||
InvoiceTemplateLineCostUnlim = 'InvoiceTemplateLineCostUnlim'
|
||||
InvoiceTemplateLineCostUnlim = 'InvoiceTemplateLineCostUnlim',
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { InvoiceTemplateLineCost } from './invoice-template-line-cost';
|
||||
import { CostType } from './cost-type';
|
||||
|
||||
export class InvoiceTemplateLineCostFixed extends InvoiceTemplateLineCost {
|
||||
costType: CostType.InvoiceTemplateLineCostFixed;
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { InvoiceTemplateLineCost } from './invoice-template-line-cost';
|
||||
import { CostAmountRange } from './cost-amount-range';
|
||||
import { CostType } from './cost-type';
|
||||
import { InvoiceTemplateLineCost } from './invoice-template-line-cost';
|
||||
|
||||
export class InvoiceTemplateLineCostRange extends InvoiceTemplateLineCost {
|
||||
costType: CostType.InvoiceTemplateLineCostRange;
|
||||
range: CostAmountRange;
|
||||
currency: string;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { InvoiceTemplateLineCost } from './invoice-template-line-cost';
|
||||
import { CostType } from './cost-type';
|
||||
import { InvoiceTemplateLineCost } from './invoice-template-line-cost';
|
||||
|
||||
export class InvoiceTemplateLineCostUnlim extends InvoiceTemplateLineCost {
|
||||
constType: CostType.InvoiceTemplateLineCostUnlim;
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { InvoiceTemplateDetails } from './invoice-template-details';
|
||||
import { InvoiceLine } from '../invoice-cart/invoice-line';
|
||||
import { TemplateType } from './template-type';
|
||||
|
||||
export class InvoiceTemplateMultiLine extends InvoiceTemplateDetails {
|
||||
templateType: TemplateType.InvoiceTemplateMultiLine;
|
||||
cart: InvoiceLine[];
|
||||
currency: string;
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { InvoiceTemplateDetails } from './invoice-template-details';
|
||||
import { InvoiceTemplateLineCost } from './invoice-template-line-cost';
|
||||
import { InvoiceLineTaxMode } from '../invoice-cart/invoice-line-tax-mode';
|
||||
import { TemplateType } from './template-type';
|
||||
|
||||
export class InvoiceTemplateSingleLine extends InvoiceTemplateDetails {
|
||||
templateType: TemplateType.InvoiceTemplateSingleLine;
|
||||
product: string;
|
||||
price: InvoiceTemplateLineCost;
|
||||
taxMode?: InvoiceLineTaxMode;
|
||||
|
@ -1,4 +1,4 @@
|
||||
export enum TemplateType {
|
||||
InvoiceTemplateMultiLine = 'InvoiceTemplateMultiLine',
|
||||
InvoiceTemplateSingleLine = 'InvoiceTemplateSingleLine'
|
||||
InvoiceTemplateSingleLine = 'InvoiceTemplateSingleLine',
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { LifetimeInterval } from './invoice-template-details/lifetime-interval';
|
||||
import { InvoiceTemplateDetails } from './invoice-template-details/invoice-template-details';
|
||||
import { LifetimeInterval } from './invoice-template-details/lifetime-interval';
|
||||
|
||||
export class InvoiceTemplate {
|
||||
id: string;
|
||||
|
@ -20,7 +20,7 @@ export enum LogicErrorCode {
|
||||
invalidClaimStatus = 'invalidClaimStatus',
|
||||
invalidClaimRevision = 'invalidClaimRevision',
|
||||
limitExceeded = 'limitExceeded',
|
||||
invalidRequest = 'invalidRequest'
|
||||
invalidRequest = 'invalidRequest',
|
||||
}
|
||||
|
||||
export class LogicError {
|
||||
|
@ -1,4 +1,4 @@
|
||||
export enum PayerType {
|
||||
CustomerPayer = 'CustomerPayer',
|
||||
PaymentResourcePayer = 'PaymentResourcePayer'
|
||||
PaymentResourcePayer = 'PaymentResourcePayer',
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Payer } from './payer';
|
||||
import { ContactInfo } from '../contact-info';
|
||||
import { PayerType } from './payer-type';
|
||||
import { PaymentToolDetails } from '../payment-tool-details';
|
||||
|
||||
export type SessionInfo = {
|
||||
@ -8,7 +7,6 @@ export type SessionInfo = {
|
||||
};
|
||||
|
||||
export class PaymentResourcePayer extends Payer {
|
||||
payerType: PayerType.PaymentResourcePayer;
|
||||
paymentToolToken: string;
|
||||
paymentSession: string;
|
||||
contactInfo: ContactInfo;
|
||||
|
@ -1,4 +1,4 @@
|
||||
export enum FlowType {
|
||||
PaymentFlowInstant = 'PaymentFlowInstant',
|
||||
PaymentFlowHold = 'PaymentFlowHold'
|
||||
PaymentFlowHold = 'PaymentFlowHold',
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
export enum HoldExpirationType {
|
||||
cancel = 'cancel',
|
||||
capture = 'capture'
|
||||
capture = 'capture',
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { PaymentFlow } from './payment-flow';
|
||||
import { FlowType } from './flow-type';
|
||||
import { HoldExpirationType } from './hold-expiration-type';
|
||||
import { PaymentFlow } from './payment-flow';
|
||||
|
||||
export class PaymentFlowHold extends PaymentFlow {
|
||||
type: FlowType.PaymentFlowHold;
|
||||
onHoldExpiration: HoldExpirationType;
|
||||
}
|
||||
|
@ -1,6 +1,3 @@
|
||||
import { PaymentFlow } from './payment-flow';
|
||||
import { FlowType } from './flow-type';
|
||||
|
||||
export class PaymentFlowInstant extends PaymentFlow {
|
||||
type: FlowType.PaymentFlowInstant;
|
||||
}
|
||||
export class PaymentFlowInstant extends PaymentFlow {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
export enum PaymentMethodName {
|
||||
BankCard = 'BankCard',
|
||||
PaymentTerminal = 'PaymentTerminal',
|
||||
DigitalWallet = 'DigitalWallet'
|
||||
DigitalWallet = 'DigitalWallet',
|
||||
}
|
||||
|
||||
export abstract class PaymentMethod {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { PaymentFlow } from './payment-flow';
|
||||
import { Payer } from './payer';
|
||||
import { PaymentFlow } from './payment-flow';
|
||||
|
||||
export class PaymentParams {
|
||||
flow: PaymentFlow;
|
||||
|
@ -4,5 +4,5 @@ export enum PaymentStatus {
|
||||
captured = 'captured',
|
||||
cancelled = 'cancelled',
|
||||
refunded = 'refunded',
|
||||
failed = 'failed'
|
||||
failed = 'failed',
|
||||
}
|
||||
|
@ -10,5 +10,5 @@ export enum PaymentSystem {
|
||||
discover = 'discover',
|
||||
unionpay = 'unionpay',
|
||||
jcb = 'jcb',
|
||||
nspkmir = 'nspkmir'
|
||||
nspkmir = 'nspkmir',
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { PaymentMethod, PaymentMethodName } from './payment-method';
|
||||
import { PaymentMethod } from './payment-method';
|
||||
|
||||
export class PaymentTerminal extends PaymentMethod {
|
||||
method: PaymentMethodName.PaymentTerminal;
|
||||
providers: string[];
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
export enum PaymentToolDetailsType {
|
||||
PaymentToolDetailsBankCard = 'PaymentToolDetailsBankCard',
|
||||
PaymentToolDetailsPaymentTerminal = 'PaymentToolDetailsPaymentTerminal',
|
||||
PaymentToolDetailsDigitalWallet = 'PaymentToolDetailsDigitalWallet'
|
||||
PaymentToolDetailsDigitalWallet = 'PaymentToolDetailsDigitalWallet',
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
export enum PaymentToolType {
|
||||
CardData = 'CardData',
|
||||
PaymentTerminalData = 'PaymentTerminalData',
|
||||
DigitalWalletData = 'DigitalWalletData'
|
||||
DigitalWalletData = 'DigitalWalletData',
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { PaymentFlow } from './payment-flow';
|
||||
import { Payer } from './payer';
|
||||
import { PaymentStatus } from './payment-status';
|
||||
import { PaymentError } from 'checkout/backend';
|
||||
|
||||
import { Payer } from './payer';
|
||||
import { PaymentFlow } from './payment-flow';
|
||||
import { PaymentStatus } from './payment-status';
|
||||
|
||||
export class Payment {
|
||||
id: string;
|
||||
invoiceID: string;
|
||||
|
@ -4,11 +4,11 @@ import { ShortenedUrl, ShortenedUrlParams } from './model';
|
||||
export const shortenUrl = (
|
||||
urlShortenerEndpoint: string,
|
||||
accessToken: string,
|
||||
params: ShortenedUrlParams
|
||||
params: ShortenedUrlParams,
|
||||
): Promise<ShortenedUrl> =>
|
||||
fetchCapi({
|
||||
method: 'POST',
|
||||
endpoint: `${urlShortenerEndpoint}/v1/shortened-urls`,
|
||||
accessToken,
|
||||
body: params
|
||||
body: params,
|
||||
});
|
||||
|
@ -1,16 +1,16 @@
|
||||
import * as React from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { ThemeProvider } from 'styled-components';
|
||||
|
||||
import { useInitApp, useTheme } from 'checkout/hooks';
|
||||
import { InitParams } from 'checkout/initialize';
|
||||
import { Overlay } from './overlay';
|
||||
import { ModalContainer } from './modal-container';
|
||||
import { LayoutLoader } from './layout-loader';
|
||||
|
||||
import { AppWrapper } from './app-wrapper';
|
||||
import { GlobalStyle } from './global-style';
|
||||
import { InitialContext } from './initial-context';
|
||||
import { useInitApp, useTheme } from 'checkout/hooks';
|
||||
import { LayoutLoader } from './layout-loader';
|
||||
import { ModalContainer } from './modal-container';
|
||||
import { ModalError } from './modal-error';
|
||||
import { Overlay } from './overlay';
|
||||
import { ResultContext } from './result-context';
|
||||
|
||||
export type AppProps = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { createGlobalStyle } from 'styled-components';
|
||||
|
||||
import { device } from 'checkout/utils/device';
|
||||
|
||||
export const GlobalStyle = createGlobalStyle`
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
import { InitialData } from 'checkout/hooks';
|
||||
|
||||
export const InitialContext = createContext<InitialData>(null);
|
||||
|
@ -1,9 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import styled, { keyframes } from 'styled-components';
|
||||
|
||||
import { Loader } from '../ui/loader';
|
||||
import { device } from 'checkout/utils/device';
|
||||
|
||||
import { Loader } from '../ui/loader';
|
||||
|
||||
const growth = keyframes`
|
||||
from {
|
||||
transform: scale(0);
|
||||
|
@ -1,18 +1,18 @@
|
||||
import * as React from 'react';
|
||||
import { useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useContext, useEffect, useMemo, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
import { Modal } from './modal';
|
||||
import { UserInteractionModal } from './user-interaction-modal';
|
||||
import { ModalName, ResultFormInfo, ResultType } from 'checkout/hooks';
|
||||
import { InitialContext } from '../initial-context';
|
||||
import { PayableInvoiceContext } from './payable-invoice-context';
|
||||
import { PayableInvoiceData, useInvoiceEvents, useModal } from 'checkout/hooks';
|
||||
import { InvoiceChangeType } from 'checkout/backend';
|
||||
import { ModalName, ResultFormInfo, ResultType } from 'checkout/hooks';
|
||||
import { PayableInvoiceData, useInvoiceEvents, useModal } from 'checkout/hooks';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
|
||||
import { Modal } from './modal';
|
||||
import { ModalContext } from './modal-context';
|
||||
import { PayableInvoiceContext } from './payable-invoice-context';
|
||||
import { useInteractionModel } from './use-interaction-model';
|
||||
import { UserInteractionModal } from './user-interaction-modal';
|
||||
import { InitialContext } from '../initial-context';
|
||||
|
||||
const Container = styled.div`
|
||||
height: 100%;
|
||||
@ -24,7 +24,7 @@ export const ModalContainer = () => {
|
||||
appConfig: { capiEndpoint },
|
||||
initConfig,
|
||||
model: { serviceProviders, invoice, invoiceAccessToken },
|
||||
availablePaymentMethods
|
||||
availablePaymentMethods,
|
||||
} = useContext(InitialContext);
|
||||
const {
|
||||
modalState,
|
||||
@ -34,11 +34,11 @@ export const ModalContainer = () => {
|
||||
prepareToRetry,
|
||||
forgetPaymentAttempt,
|
||||
setViewInfoError,
|
||||
toInteractionState
|
||||
toInteractionState,
|
||||
} = useModal({
|
||||
integrationType: initConfig.integrationType,
|
||||
availablePaymentMethods,
|
||||
serviceProviders
|
||||
serviceProviders,
|
||||
});
|
||||
const [payableInvoiceData, setPayableInvoiceData] = useState<PayableInvoiceData>(null);
|
||||
const { eventsState, startPolling, searchEventsChange } = useInvoiceEvents(capiEndpoint, payableInvoiceData);
|
||||
@ -50,9 +50,9 @@ export const ModalContainer = () => {
|
||||
invoice: {
|
||||
id: invoice.id,
|
||||
dueDate: invoice.dueDate,
|
||||
externalID: invoice.externalID
|
||||
externalID: invoice.externalID,
|
||||
},
|
||||
invoiceAccessToken
|
||||
invoiceAccessToken,
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
@ -85,8 +85,8 @@ export const ModalContainer = () => {
|
||||
case InvoiceChangeType.PaymentStatusChanged:
|
||||
goToFormInfo(
|
||||
new ResultFormInfo(ResultType.hookProcessed, {
|
||||
change
|
||||
})
|
||||
change,
|
||||
}),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@ -100,8 +100,8 @@ export const ModalContainer = () => {
|
||||
if (eventsState.status === 'FAILURE') {
|
||||
goToFormInfo(
|
||||
new ResultFormInfo(ResultType.hookError, {
|
||||
error: eventsState.error
|
||||
})
|
||||
error: eventsState.error,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}, [payableInvoiceData, eventsState]);
|
||||
@ -114,7 +114,7 @@ export const ModalContainer = () => {
|
||||
const activeModalName = useMemo(() => modalState.find((modal) => modal.active).name, [modalState]);
|
||||
|
||||
return (
|
||||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 1 }}>
|
||||
<motion.div animate={{ opacity: 1 }} initial={{ opacity: 0 }} transition={{ duration: 1 }}>
|
||||
<Container>
|
||||
<ModalContext.Provider
|
||||
value={{
|
||||
@ -123,8 +123,9 @@ export const ModalContainer = () => {
|
||||
prepareToPay,
|
||||
prepareToRetry,
|
||||
forgetPaymentAttempt,
|
||||
setViewInfoError
|
||||
}}>
|
||||
setViewInfoError,
|
||||
}}
|
||||
>
|
||||
<PayableInvoiceContext.Provider value={{ payableInvoiceData, setPayableInvoiceData }}>
|
||||
{activeModalName === ModalName.modalForms && <Modal />}
|
||||
{activeModalName === ModalName.modalInteraction && <UserInteractionModal />}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { ReactSVG } from 'react-svg';
|
||||
import { useContext } from 'react';
|
||||
import { ReactSVG } from 'react-svg';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { InitialContext } from '../../initial-context';
|
||||
|
@ -1,4 +1,5 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { device } from 'checkout/utils/device';
|
||||
|
||||
export const FormBlock = styled.div`
|
||||
|
@ -1,26 +1,25 @@
|
||||
import * as React from 'react';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||
|
||||
import { FormGroup } from '../form-group';
|
||||
import { CardHolder, CardNumber, ExpireDate, SecureCode } from './fields';
|
||||
import { ResultFormInfo, ResultType } from 'checkout/hooks';
|
||||
import { PayButton } from '../pay-button';
|
||||
import { Header } from '../header';
|
||||
import { toAmountConfig, toCardHolderConfig } from '../fields-config';
|
||||
import { Amount } from '../common-fields';
|
||||
import { PaymentMethodName, useCreatePayment } from 'checkout/hooks';
|
||||
import { isEmptyObject } from 'checkout/utils/is-empty-object';
|
||||
import { CardFormInputs } from './card-form-inputs';
|
||||
|
||||
import { CardFormInputs } from './card-form-inputs';
|
||||
import { CardHolder, CardNumber, ExpireDate, SecureCode } from './fields';
|
||||
import { InitialContext } from '../../../../initial-context';
|
||||
import { ModalContext } from '../../../modal-context';
|
||||
import { Amount } from '../common-fields';
|
||||
import { toAmountConfig, toCardHolderConfig } from '../fields-config';
|
||||
import { FormGroup } from '../form-group';
|
||||
import { Header } from '../header';
|
||||
import { PayButton } from '../pay-button';
|
||||
|
||||
export const CardForm = ({ onMount }: { onMount: () => void }) => {
|
||||
const {
|
||||
locale,
|
||||
initConfig,
|
||||
model: { invoiceTemplate }
|
||||
model: { invoiceTemplate },
|
||||
} = useContext(InitialContext);
|
||||
const { setViewInfoError, goToFormInfo, prepareToPay } = useContext(ModalContext);
|
||||
const { createPaymentState, setFormData } = useCreatePayment();
|
||||
@ -28,7 +27,7 @@ export const CardForm = ({ onMount }: { onMount: () => void }) => {
|
||||
register,
|
||||
handleSubmit,
|
||||
watch,
|
||||
formState: { errors, dirtyFields, isSubmitted }
|
||||
formState: { errors, dirtyFields, isSubmitted },
|
||||
} = useForm<CardFormInputs>({ mode: 'onChange' });
|
||||
const cardHolder = toCardHolderConfig(initConfig.requireCardHolder);
|
||||
const amount = toAmountConfig(initConfig, invoiceTemplate);
|
||||
@ -47,8 +46,8 @@ export const CardForm = ({ onMount }: { onMount: () => void }) => {
|
||||
if (createPaymentState.status === 'FAILURE') {
|
||||
goToFormInfo(
|
||||
new ResultFormInfo(ResultType.hookError, {
|
||||
error: createPaymentState.error
|
||||
})
|
||||
error: createPaymentState.error,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}, [createPaymentState]);
|
||||
@ -63,35 +62,35 @@ export const CardForm = ({ onMount }: { onMount: () => void }) => {
|
||||
<Header title={locale['form.header.pay.card.label']} />
|
||||
<FormGroup>
|
||||
<CardNumber
|
||||
locale={locale}
|
||||
fieldError={errors.cardNumber}
|
||||
isDirty={dirtyFields.cardNumber}
|
||||
locale={locale}
|
||||
register={register}
|
||||
watch={watch}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup $gap={10}>
|
||||
<ExpireDate
|
||||
locale={locale}
|
||||
fieldError={errors.expireDate}
|
||||
isDirty={dirtyFields.expireDate}
|
||||
locale={locale}
|
||||
register={register}
|
||||
/>
|
||||
<SecureCode
|
||||
locale={locale}
|
||||
cardNumber={watch('cardNumber')}
|
||||
fieldError={errors.secureCode}
|
||||
isDirty={dirtyFields.secureCode}
|
||||
register={register}
|
||||
locale={locale}
|
||||
obscureCardCvv={initConfig?.obscureCardCvv}
|
||||
cardNumber={watch('cardNumber')}
|
||||
register={register}
|
||||
/>
|
||||
</FormGroup>
|
||||
{cardHolder.visible && (
|
||||
<FormGroup>
|
||||
<CardHolder
|
||||
locale={locale}
|
||||
fieldError={errors.cardHolder}
|
||||
isDirty={dirtyFields.cardHolder}
|
||||
locale={locale}
|
||||
register={register}
|
||||
/>
|
||||
</FormGroup>
|
||||
@ -100,10 +99,10 @@ export const CardForm = ({ onMount }: { onMount: () => void }) => {
|
||||
<FormGroup>
|
||||
<Amount
|
||||
cost={amount.cost}
|
||||
locale={locale}
|
||||
localeCode={initConfig.locale}
|
||||
fieldError={errors.amount}
|
||||
isDirty={dirtyFields.amount}
|
||||
locale={locale}
|
||||
localeCode={initConfig.locale}
|
||||
register={register}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
@ -1,13 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import { FieldError, UseFormRegister } from 'react-hook-form';
|
||||
|
||||
import { validateCardHolder } from './validate-card-holder';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { formatCardHolder } from './format-card-holder';
|
||||
import { Input } from 'checkout/components';
|
||||
import { CardFormInputs } from '../../card-form-inputs';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
|
||||
import { formatCardHolder } from './format-card-holder';
|
||||
import { validateCardHolder } from './validate-card-holder';
|
||||
import { ReactComponent as UserIcon } from '../../../../../../../ui/icon/user.svg';
|
||||
import { CardFormInputs } from '../../card-form-inputs';
|
||||
|
||||
export type CardHolderProps = {
|
||||
register: UseFormRegister<CardFormInputs>;
|
||||
@ -20,16 +20,16 @@ export const CardHolder = ({ register, locale, fieldError, isDirty }: CardHolder
|
||||
<Input
|
||||
{...register('cardHolder', {
|
||||
required: true,
|
||||
validate: (value) => !validateCardHolder(value) || 'Card holder is invalid'
|
||||
validate: (value) => !validateCardHolder(value) || 'Card holder is invalid',
|
||||
})}
|
||||
icon={<UserIcon />}
|
||||
placeholder={locale['form.input.cardholder.placeholder']}
|
||||
mark={true}
|
||||
id="card-holder-input"
|
||||
onInput={formatCardHolder}
|
||||
autoComplete="cc-name"
|
||||
spellCheck={false}
|
||||
error={!isNil(fieldError)}
|
||||
dirty={isDirty}
|
||||
error={!isNil(fieldError)}
|
||||
icon={<UserIcon />}
|
||||
id="card-holder-input"
|
||||
mark={true}
|
||||
placeholder={locale['form.input.cardholder.placeholder']}
|
||||
spellCheck={false}
|
||||
onInput={formatCardHolder}
|
||||
/>
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { safeVal } from 'checkout/utils';
|
||||
import { FormEvent } from 'react';
|
||||
|
||||
import { safeVal } from 'checkout/utils';
|
||||
|
||||
export const formatCardHolder = (e: FormEvent<HTMLInputElement>) => {
|
||||
const target = e.currentTarget;
|
||||
let value = target.value;
|
||||
|
@ -1,15 +1,15 @@
|
||||
import * as React from 'react';
|
||||
import { FieldError, UseFormRegister, UseFormWatch } from 'react-hook-form';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { validateCardNumber } from './validate-card-number';
|
||||
import { Input } from 'checkout/components';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { formatCardNumber } from './format-card-number';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
import { CardFormInputs } from '../../card-form-inputs';
|
||||
import { ReactComponent as CardIcon } from '../../../../../../../ui/icon/card.svg';
|
||||
import { CardTypeIcon } from 'checkout/components/ui/card-type-icon';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
|
||||
import { formatCardNumber } from './format-card-number';
|
||||
import { validateCardNumber } from './validate-card-number';
|
||||
import { ReactComponent as CardIcon } from '../../../../../../../ui/icon/card.svg';
|
||||
import { CardFormInputs } from '../../card-form-inputs';
|
||||
|
||||
const InputContainer = styled.div`
|
||||
width: 100%;
|
||||
@ -35,17 +35,17 @@ export const CardNumber = ({ register, locale, fieldError, isDirty, watch }: Car
|
||||
<CardNumberInput
|
||||
{...register('cardNumber', {
|
||||
required: true,
|
||||
validate: (value) => !validateCardNumber(value) || 'Card number is invalid'
|
||||
validate: (value) => !validateCardNumber(value) || 'Card number is invalid',
|
||||
})}
|
||||
icon={<CardIcon />}
|
||||
placeholder={locale['form.input.card.placeholder']}
|
||||
mark={true}
|
||||
type="tel"
|
||||
id="card-number-input"
|
||||
onInput={formatCardNumber}
|
||||
autoComplete="cc-number"
|
||||
error={!isNil(fieldError)}
|
||||
dirty={isDirty}
|
||||
error={!isNil(fieldError)}
|
||||
icon={<CardIcon />}
|
||||
id="card-number-input"
|
||||
mark={true}
|
||||
placeholder={locale['form.input.card.placeholder']}
|
||||
type="tel"
|
||||
onInput={formatCardNumber}
|
||||
/>
|
||||
<CardTypeIcon cardNumber={watch('cardNumber')} />
|
||||
</InputContainer>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { FormEvent } from 'react';
|
||||
import { number } from 'card-validator';
|
||||
import { FormEvent } from 'react';
|
||||
|
||||
import { replaceFullWidthChars, safeVal } from 'checkout/utils';
|
||||
|
||||
function format(num: string): string {
|
||||
|
@ -1,13 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import { FieldError, UseFormRegister } from 'react-hook-form';
|
||||
|
||||
import { validateExpireDate } from './validate-expire-date';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { formatExpiry } from './format-expiry';
|
||||
import { Input } from 'checkout/components';
|
||||
import { CardFormInputs } from '../../card-form-inputs';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
|
||||
import { formatExpiry } from './format-expiry';
|
||||
import { validateExpireDate } from './validate-expire-date';
|
||||
import { ReactComponent as CalendarIcon } from '../../../../../../../ui/icon/calendar.svg';
|
||||
import { CardFormInputs } from '../../card-form-inputs';
|
||||
|
||||
export type ExpireDateProps = {
|
||||
register: UseFormRegister<CardFormInputs>;
|
||||
@ -20,16 +20,16 @@ export const ExpireDate = ({ register, locale, fieldError, isDirty }: ExpireDate
|
||||
<Input
|
||||
{...register('expireDate', {
|
||||
required: true,
|
||||
validate: (value) => !validateExpireDate(value) || 'Exp date is invalid'
|
||||
validate: (value) => !validateExpireDate(value) || 'Exp date is invalid',
|
||||
})}
|
||||
icon={<CalendarIcon />}
|
||||
placeholder={locale['form.input.expiry.placeholder']}
|
||||
mark={true}
|
||||
type="tel"
|
||||
id="expire-date-input"
|
||||
onInput={formatExpiry}
|
||||
autoComplete="cc-exp"
|
||||
error={!isNil(fieldError)}
|
||||
dirty={isDirty}
|
||||
error={!isNil(fieldError)}
|
||||
icon={<CalendarIcon />}
|
||||
id="expire-date-input"
|
||||
mark={true}
|
||||
placeholder={locale['form.input.expiry.placeholder']}
|
||||
type="tel"
|
||||
onInput={formatExpiry}
|
||||
/>
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { replaceFullWidthChars, safeVal } from 'checkout/utils';
|
||||
import { FormEvent } from 'react';
|
||||
|
||||
import { replaceFullWidthChars, safeVal } from 'checkout/utils';
|
||||
|
||||
function format(expiry: string): string {
|
||||
const parts = expiry.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/);
|
||||
if (!parts) {
|
||||
|
@ -8,7 +8,7 @@ export function cardExpiryVal(value: string): ExpiryDate {
|
||||
let prefix;
|
||||
let year;
|
||||
let ref;
|
||||
(ref = value.split(/[\s\/]+/, 2)), (month = ref[0]), (year = ref[1]);
|
||||
(ref = value.split(/[\s]+/, 2)), (month = ref[0]), (year = ref[1]);
|
||||
if ((year != null ? year.length : void 0) === 2 && /^\d+$/.test(year)) {
|
||||
prefix = new Date().getFullYear();
|
||||
prefix = prefix.toString().slice(0, 2);
|
||||
@ -18,6 +18,6 @@ export function cardExpiryVal(value: string): ExpiryDate {
|
||||
year = parseInt(year, 10);
|
||||
return {
|
||||
month,
|
||||
year
|
||||
year,
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { number } from 'card-validator';
|
||||
|
||||
import { replaceFullWidthChars } from 'checkout/utils';
|
||||
|
||||
export function formatCVC(value: string, cardNumber: string): string {
|
||||
|
@ -1,15 +1,15 @@
|
||||
import * as React from 'react';
|
||||
import { number } from 'card-validator';
|
||||
import { FieldError, UseFormRegister } from 'react-hook-form';
|
||||
|
||||
import { validateSecureCode } from './validate-secure-code';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { formatCVC } from './format-cvc';
|
||||
import { Input } from 'checkout/components';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { safeVal } from 'checkout/utils';
|
||||
import { CardFormInputs } from '../../card-form-inputs';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
|
||||
import { formatCVC } from './format-cvc';
|
||||
import { validateSecureCode } from './validate-secure-code';
|
||||
import { ReactComponent as LockIcon } from '../../../../../../../ui/icon/lock.svg';
|
||||
import { CardFormInputs } from '../../card-form-inputs';
|
||||
|
||||
export interface SecureCodeProps {
|
||||
register: UseFormRegister<CardFormInputs>;
|
||||
@ -29,19 +29,19 @@ export const SecureCode = ({ cardNumber, locale, obscureCardCvv, register, field
|
||||
<Input
|
||||
{...register('secureCode', {
|
||||
required: true,
|
||||
validate: (value) => !validateSecureCode(value, { cardNumber }) || 'Secure code is invalid'
|
||||
validate: (value) => !validateSecureCode(value, { cardNumber }) || 'Secure code is invalid',
|
||||
})}
|
||||
icon={<LockIcon />}
|
||||
placeholder={getPlaceholder(cardNumber, locale)}
|
||||
mark={true}
|
||||
type={obscureCardCvv ? 'password' : 'tel'}
|
||||
id="secure-code-input"
|
||||
autoComplete="cc-csc"
|
||||
error={!isNil(fieldError)}
|
||||
dirty={isDirty}
|
||||
error={!isNil(fieldError)}
|
||||
icon={<LockIcon />}
|
||||
id="secure-code-input"
|
||||
mark={true}
|
||||
placeholder={getPlaceholder(cardNumber, locale)}
|
||||
type={obscureCardCvv ? 'password' : 'tel'}
|
||||
onInput={(e) => {
|
||||
const target = e.currentTarget;
|
||||
let value = target.value;
|
||||
const value = target.value;
|
||||
const formatted = formatCVC(value, cardNumber);
|
||||
return safeVal(formatted, target);
|
||||
}}
|
||||
|
@ -1,13 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import { FieldError, UseFormRegister } from 'react-hook-form';
|
||||
|
||||
import { InvoiceTemplateLineCostRange, InvoiceTemplateLineCostUnlim } from 'checkout/backend';
|
||||
import { Input } from 'checkout/components';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
|
||||
import { formatAmount } from './format-amount';
|
||||
import { getPlaceholder } from './get-placeholder';
|
||||
import { validateAmount } from './validate-amount';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { InvoiceTemplateLineCostRange, InvoiceTemplateLineCostUnlim } from 'checkout/backend';
|
||||
import { formatAmount } from './format-amount';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
import { ReactComponent as AmountIcon } from '../../../../../../ui/icon/amount.svg';
|
||||
|
||||
export type AmountProps = {
|
||||
@ -23,15 +23,15 @@ export const Amount = ({ register, locale, fieldError, cost, localeCode, isDirty
|
||||
<Input
|
||||
{...register('amount', {
|
||||
required: true,
|
||||
validate: (value) => !validateAmount(value, cost) || 'Amount is invalid'
|
||||
validate: (value) => !validateAmount(value, cost) || 'Amount is invalid',
|
||||
})}
|
||||
icon={<AmountIcon />}
|
||||
placeholder={getPlaceholder(cost, locale['form.input.amount.placeholder'], localeCode)}
|
||||
mark={true}
|
||||
type="tel"
|
||||
id="amount-input"
|
||||
onInput={formatAmount}
|
||||
error={!isNil(fieldError)}
|
||||
dirty={isDirty}
|
||||
error={!isNil(fieldError)}
|
||||
icon={<AmountIcon />}
|
||||
id="amount-input"
|
||||
mark={true}
|
||||
placeholder={getPlaceholder(cost, locale['form.input.amount.placeholder'], localeCode)}
|
||||
type="tel"
|
||||
onInput={formatAmount}
|
||||
/>
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { replaceFullWidthChars, safeVal } from 'checkout/utils';
|
||||
import { FormEvent } from 'react';
|
||||
|
||||
import { replaceFullWidthChars, safeVal } from 'checkout/utils';
|
||||
|
||||
const createNumArr = (num: string): string[] => {
|
||||
let numTempArr;
|
||||
if (/^\d+(\.\d+)?$/.test(num)) {
|
||||
|
@ -9,13 +9,13 @@ const toRangePlaceholder = (cost: InvoiceTemplateLineCostRange, locale: string):
|
||||
minorValue: range.lowerBound,
|
||||
currencyCode: cost.currency,
|
||||
status: 'final',
|
||||
locale
|
||||
locale,
|
||||
});
|
||||
const upper = formatAmount({
|
||||
minorValue: range.upperBound,
|
||||
currencyCode: cost.currency,
|
||||
status: 'final',
|
||||
locale
|
||||
locale,
|
||||
});
|
||||
return `${lower} - ${upper}`;
|
||||
};
|
||||
@ -23,7 +23,7 @@ const toRangePlaceholder = (cost: InvoiceTemplateLineCostRange, locale: string):
|
||||
export const getPlaceholder = (
|
||||
cost: InvoiceTemplateLineCostRange | InvoiceTemplateLineCostUnlim,
|
||||
localeString: string,
|
||||
localeCode: string
|
||||
localeCode: string,
|
||||
): string => {
|
||||
if (!cost) {
|
||||
return;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import toNumber from 'checkout/utils/to-number';
|
||||
import isNumber from 'checkout/utils/is-number';
|
||||
import { CostType, InvoiceTemplateLineCostRange, InvoiceTemplateLineCostUnlim } from 'checkout/backend';
|
||||
import isNumber from 'checkout/utils/is-number';
|
||||
import toNumber from 'checkout/utils/to-number';
|
||||
|
||||
function validate(amount: number, min?: number, max?: number): boolean {
|
||||
if (!amount || !isNumber(amount) || amount <= 0) {
|
||||
@ -14,7 +14,7 @@ function validate(amount: number, min?: number, max?: number): boolean {
|
||||
|
||||
export const validateAmount = (
|
||||
value: string,
|
||||
cost: InvoiceTemplateLineCostRange | InvoiceTemplateLineCostUnlim
|
||||
cost: InvoiceTemplateLineCostRange | InvoiceTemplateLineCostUnlim,
|
||||
): boolean => {
|
||||
if (value) {
|
||||
value = value.replace(/\s/g, '').replace(/,/g, '.');
|
||||
|
@ -1,8 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { FieldError, FieldErrorsImpl, Merge, UseFormRegister } from 'react-hook-form';
|
||||
import { formatEmail, validateEmail } from 'checkout/utils';
|
||||
import { Locale } from 'checkout/locale';
|
||||
|
||||
import { Input } from 'checkout/components';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { formatEmail, validateEmail } from 'checkout/utils';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
|
||||
export type EmailProps = {
|
||||
@ -16,15 +16,15 @@ export const Email = ({ register, locale, fieldError, isDirty }: EmailProps) =>
|
||||
<Input
|
||||
{...register('email', {
|
||||
required: true,
|
||||
validate: (value) => !validateEmail(value) || 'Email is invalid'
|
||||
validate: (value) => !validateEmail(value) || 'Email is invalid',
|
||||
})}
|
||||
placeholder={locale['form.input.email.placeholder']}
|
||||
mark={true}
|
||||
type="email"
|
||||
id="email-input"
|
||||
onInput={formatEmail}
|
||||
autoComplete="email"
|
||||
error={!isNil(fieldError)}
|
||||
dirty={isDirty}
|
||||
error={!isNil(fieldError)}
|
||||
id="email-input"
|
||||
mark={true}
|
||||
placeholder={locale['form.input.email.placeholder']}
|
||||
type="email"
|
||||
onInput={formatEmail}
|
||||
/>
|
||||
);
|
||||
|
@ -1,8 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { FieldError, FieldErrorsImpl, Merge, UseFormRegister } from 'react-hook-form';
|
||||
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { Input } from 'checkout/components';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { formatPhoneNumber, validatePhone } from 'checkout/utils';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
|
||||
@ -17,16 +16,16 @@ export const Phone = ({ register, locale, fieldError, isDirty }: PhoneProps) =>
|
||||
<Input
|
||||
{...register('phoneNumber', {
|
||||
required: true,
|
||||
validate: (value) => !validatePhone(value) || 'Phone number is invalid'
|
||||
validate: (value) => !validatePhone(value) || 'Phone number is invalid',
|
||||
})}
|
||||
placeholder={locale['form.input.phone.placeholder']}
|
||||
mark={true}
|
||||
type="tel"
|
||||
id="phone-input"
|
||||
onInput={formatPhoneNumber}
|
||||
onFocus={formatPhoneNumber}
|
||||
autoComplete="tel"
|
||||
error={!isNil(fieldError)}
|
||||
dirty={isDirty}
|
||||
error={!isNil(fieldError)}
|
||||
id="phone-input"
|
||||
mark={true}
|
||||
placeholder={locale['form.input.phone.placeholder']}
|
||||
type="tel"
|
||||
onFocus={formatPhoneNumber}
|
||||
onInput={formatPhoneNumber}
|
||||
/>
|
||||
);
|
||||
|
@ -2,9 +2,10 @@ import {
|
||||
InvoiceTemplate,
|
||||
InvoiceTemplateLineCostRange,
|
||||
InvoiceTemplateLineCostUnlim,
|
||||
InvoiceTemplateSingleLine
|
||||
InvoiceTemplateSingleLine,
|
||||
} from 'checkout/backend';
|
||||
import { InitConfig } from 'checkout/config';
|
||||
|
||||
import { AmountConfig, EmailConfig, FieldsConfig, PhoneNumberConfig } from './fields-config';
|
||||
|
||||
const toSingleLineAmountConfig = (c: InvoiceTemplateSingleLine): AmountConfig => {
|
||||
@ -47,12 +48,12 @@ export const toEmailConfig = (email: string): EmailConfig => {
|
||||
};
|
||||
|
||||
export const toCardHolderConfig = (requireCardHolder: boolean | null) => ({
|
||||
visible: requireCardHolder === null ? true : requireCardHolder
|
||||
visible: requireCardHolder === null ? true : requireCardHolder,
|
||||
});
|
||||
|
||||
export const toFieldsConfig = (c: InitConfig, t: InvoiceTemplate): FieldsConfig => ({
|
||||
amount: toAmountConfig(c, t),
|
||||
email: toEmailConfig(c.email),
|
||||
cardHolder: toCardHolderConfig(c.requireCardHolder),
|
||||
phoneNumber: toPhoneNumberConfig(c.phoneNumber)
|
||||
phoneNumber: toPhoneNumberConfig(c.phoneNumber),
|
||||
});
|
||||
|
@ -1,23 +1,22 @@
|
||||
import * as React from 'react';
|
||||
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { CardForm } from './card-form';
|
||||
import { FormName, ModalForms, ModalName, SlideDirection } from 'checkout/hooks';
|
||||
import { PaymentMethods } from './payment-methods';
|
||||
import { FormLoader } from './form-loader';
|
||||
import { ResultForm } from './result-form';
|
||||
import { WalletForm } from './wallet-form';
|
||||
import { findNamed } from 'checkout/utils';
|
||||
import { device } from 'checkout/utils/device';
|
||||
import { NoAvailablePaymentMethodForm } from './no-available-payment-method-form';
|
||||
import { WalletProviders } from './wallet-providers';
|
||||
import { RedirectForm } from './redirect-form';
|
||||
import { PaymentTerminalForm } from './payment-terminal-form';
|
||||
import { QrCodeInteractionForm } from './qr-code-interaction-form';
|
||||
import { PaymentTerminalSelectorForm } from './payment-terminal-selector-form';
|
||||
|
||||
import { CardForm } from './card-form';
|
||||
import { FormLoader } from './form-loader';
|
||||
import { NoAvailablePaymentMethodForm } from './no-available-payment-method-form';
|
||||
import { PaymentMethods } from './payment-methods';
|
||||
import { PaymentTerminalForm } from './payment-terminal-form';
|
||||
import { PaymentTerminalSelectorForm } from './payment-terminal-selector-form';
|
||||
import { QrCodeInteractionForm } from './qr-code-interaction-form';
|
||||
import { RedirectForm } from './redirect-form';
|
||||
import { ResultForm } from './result-form';
|
||||
import { WalletForm } from './wallet-form';
|
||||
import { WalletProviders } from './wallet-providers';
|
||||
import { ModalContext } from '../../modal-context';
|
||||
|
||||
const Container = styled.div`
|
||||
@ -87,12 +86,12 @@ export const FormContainer = () => {
|
||||
|
||||
const {
|
||||
formName,
|
||||
viewInfo: { slideDirection, inProcess }
|
||||
viewInfo: { slideDirection, inProcess },
|
||||
} = useMemo(() => {
|
||||
const found = findNamed(modalState, ModalName.modalForms) as ModalForms;
|
||||
return {
|
||||
formName: found.formsInfo.find((item) => item.active)?.name,
|
||||
viewInfo: found.viewInfo
|
||||
viewInfo: found.viewInfo,
|
||||
};
|
||||
}, [modalState]);
|
||||
|
||||
@ -111,11 +110,12 @@ export const FormContainer = () => {
|
||||
<Container>
|
||||
<Form height={height}>
|
||||
<motion.div
|
||||
ref={contentElement}
|
||||
key={formName}
|
||||
initial={{ x: toInitialPos(slideDirection) }}
|
||||
ref={contentElement}
|
||||
animate={{ x: 0 }}
|
||||
transition={{ duration: 0.3 }}>
|
||||
initial={{ x: toInitialPos(slideDirection) }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
{renderForm(formName, onMount)}
|
||||
{inProcess && <FormLoader />}
|
||||
</motion.div>
|
||||
|
@ -1,6 +1,9 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const FormGroup = styled.div<{ direction?: 'column' | 'row'; $gap?: number }>`
|
||||
export const FormGroup = styled.div<{
|
||||
direction?: 'column' | 'row';
|
||||
$gap?: number;
|
||||
}>`
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
flex-direction: ${({ direction }) => direction || 'row'};
|
||||
|
@ -1,4 +1,3 @@
|
||||
import * as React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import styled from 'styled-components';
|
||||
|
||||
@ -7,7 +6,7 @@ import { Loader } from 'checkout/components';
|
||||
const fadeIn = {
|
||||
hidden: { opacity: 0 },
|
||||
show: { opacity: 1, transition: { duration: 0.5 } },
|
||||
exit: { opacity: 0, transition: { duration: 0.5 } }
|
||||
exit: { opacity: 0, transition: { duration: 0.5 } },
|
||||
};
|
||||
|
||||
const LoaderWrapper = styled.div`
|
||||
@ -26,7 +25,7 @@ const LoaderWrapper = styled.div`
|
||||
`;
|
||||
|
||||
export const FormLoader = () => (
|
||||
<motion.div variants={fadeIn} initial="hidden" animate="show" exit="exit">
|
||||
<motion.div animate="show" exit="exit" initial="hidden" variants={fadeIn}>
|
||||
<LoaderWrapper key="form-loader" id="form-loader">
|
||||
<Loader />
|
||||
</LoaderWrapper>
|
||||
|
@ -2,13 +2,13 @@ import {
|
||||
KnownProviderCategories,
|
||||
PaymentMethod,
|
||||
PaymentMethodName,
|
||||
PaymentTerminalPaymentMethod
|
||||
PaymentTerminalPaymentMethod,
|
||||
} from 'checkout/hooks';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
|
||||
export const getAvailableTerminalPaymentMethod = (
|
||||
availablePaymentMethods: PaymentMethod[],
|
||||
category: KnownProviderCategories
|
||||
category: KnownProviderCategories,
|
||||
): PaymentTerminalPaymentMethod | null => {
|
||||
if (isNil(category)) {
|
||||
return null;
|
||||
|
@ -1,14 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { findInfoWithPrevious, findNamed } from 'checkout/utils';
|
||||
import { FormInfo, ModalForms, ModalName, ModalState } from 'checkout/hooks';
|
||||
import { HeaderWrapper } from '../header-wrapper';
|
||||
import { Title } from '../title';
|
||||
import { ChevronButton } from 'checkout/components';
|
||||
import { FormInfo, ModalForms, ModalName, ModalState } from 'checkout/hooks';
|
||||
import { Direction } from 'checkout/hooks';
|
||||
import { findInfoWithPrevious, findNamed } from 'checkout/utils';
|
||||
|
||||
import { ModalContext } from '../../../modal-context';
|
||||
import { HeaderWrapper } from '../header-wrapper';
|
||||
import { Title } from '../title';
|
||||
|
||||
const getDestination = (modals: ModalState[]): FormInfo => {
|
||||
const modalForms = findNamed(modals, ModalName.modalForms) as ModalForms;
|
||||
@ -24,9 +23,9 @@ export const Header = ({ title }: { title: string }) => {
|
||||
<HeaderWrapper>
|
||||
{destination && (
|
||||
<ChevronButton
|
||||
id="desktop-back-btn"
|
||||
type="left"
|
||||
onClick={() => goToFormInfo(destination, Direction.back)}
|
||||
id="desktop-back-btn"
|
||||
/>
|
||||
)}
|
||||
<Title>{title}</Title>
|
||||
|
@ -1,10 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { Text } from '../text';
|
||||
|
||||
import { InitialContext } from '../../../../initial-context';
|
||||
import { Text } from '../text';
|
||||
|
||||
const Container = styled.div`
|
||||
padding: 80px 0;
|
||||
|
@ -1,11 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { useContext } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { formatAmount } from 'checkout/utils';
|
||||
import { Button } from 'checkout/components';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { AmountInfo } from 'checkout/hooks';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { formatAmount } from 'checkout/utils';
|
||||
|
||||
import { InitialContext } from '../../../../initial-context';
|
||||
|
||||
@ -23,7 +22,7 @@ export const PayButton = () => {
|
||||
const { locale, amountInfo } = useContext(InitialContext);
|
||||
const label = toLabel(locale, amountInfo);
|
||||
return (
|
||||
<PayButtonWrapper type="submit" color="primary" id="pay-btn">
|
||||
<PayButtonWrapper color="primary" id="pay-btn" type="submit">
|
||||
{label}
|
||||
</PayButtonWrapper>
|
||||
);
|
||||
|
@ -1,10 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { CardFormInfo, FormName } from 'checkout/hooks';
|
||||
import { Method } from './method';
|
||||
import { PaymentMethodIcon, PaymentMethodTitle } from 'checkout/components/ui';
|
||||
import { CardFormInfo, FormName } from 'checkout/hooks';
|
||||
|
||||
import { Method } from './method';
|
||||
import { InitialContext } from '../../../../../initial-context';
|
||||
import { ModalContext } from '../../../../modal-context';
|
||||
|
||||
@ -17,7 +16,7 @@ export const BankCard = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Method onClick={onClick} id="bank-card-payment-method">
|
||||
<Method id="bank-card-payment-method" onClick={onClick}>
|
||||
<PaymentMethodIcon name="bank-card" />
|
||||
<PaymentMethodTitle>{locale['form.payment.method.name.card.label']}</PaymentMethodTitle>
|
||||
</Method>
|
||||
|
@ -1,9 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { Methods } from './methods';
|
||||
import { PaymentMethod } from 'checkout/hooks';
|
||||
|
||||
import { Methods } from './methods';
|
||||
|
||||
const List = styled.ul`
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
@ -1,16 +1,15 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { assertUnreachable } from 'checkout/utils';
|
||||
import { Wallets } from './wallets';
|
||||
import { BankCard } from './bank-card';
|
||||
import { WalletProviderPaymentMethodItem } from '../../wallet-provider-payment-method-item';
|
||||
import { PaymentTerminalMethodItems } from './payment-terminal-method-items';
|
||||
import {
|
||||
DigitalWalletPaymentMethod,
|
||||
PaymentMethod,
|
||||
PaymentMethodName,
|
||||
PaymentTerminalPaymentMethod
|
||||
PaymentTerminalPaymentMethod,
|
||||
} from 'checkout/hooks';
|
||||
import { assertUnreachable } from 'checkout/utils';
|
||||
|
||||
import { BankCard } from './bank-card';
|
||||
import { PaymentTerminalMethodItems } from './payment-terminal-method-items';
|
||||
import { Wallets } from './wallets';
|
||||
import { WalletProviderPaymentMethodItem } from '../../wallet-provider-payment-method-item';
|
||||
|
||||
const Method = ({ method }: { method: PaymentMethod }) => {
|
||||
switch (method.name) {
|
||||
|
@ -1,10 +1,13 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { KnownProviderCategories } from 'checkout/hooks';
|
||||
|
||||
export const CategoryContent: React.FC<{ category: KnownProviderCategories }> = ({ category }) => {
|
||||
export const CategoryContent: React.FC<{
|
||||
category: KnownProviderCategories;
|
||||
}> = ({ category }) => {
|
||||
switch (category) {
|
||||
case 'netbanking':
|
||||
return <img src="/assets/inb-logo.jpg" height="68px" width="106px"></img>;
|
||||
return <img height="68px" src="/assets/inb-logo.jpg" width="106px"></img>;
|
||||
}
|
||||
return <div>{category}</div>;
|
||||
};
|
||||
|
@ -1,15 +1,16 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { MetadataContent } from './metadata-content';
|
||||
import { CategoryContent } from './category-content';
|
||||
import { PaymentTerminalPaymentMethod } from 'checkout/hooks';
|
||||
|
||||
export const Content: React.FC<{ method: PaymentTerminalPaymentMethod; localeCode: string }> = ({
|
||||
method,
|
||||
localeCode
|
||||
}) => {
|
||||
import { CategoryContent } from './category-content';
|
||||
import { MetadataContent } from './metadata-content';
|
||||
|
||||
export const Content: React.FC<{
|
||||
method: PaymentTerminalPaymentMethod;
|
||||
localeCode: string;
|
||||
}> = ({ method, localeCode }) => {
|
||||
if (method.serviceProviders.length === 1) {
|
||||
return <MetadataContent serviceProvider={method.serviceProviders[0]} localeCode={localeCode} />;
|
||||
return <MetadataContent localeCode={localeCode} serviceProvider={method.serviceProviders[0]} />;
|
||||
}
|
||||
if (method.serviceProviders.length > 1) {
|
||||
return <CategoryContent category={method.category} />;
|
||||
|
@ -3,14 +3,14 @@ import * as React from 'react';
|
||||
import { ServiceProvider } from 'checkout/backend';
|
||||
import { getMetadata, MetadataLogo, MetadataTitle } from 'checkout/components';
|
||||
|
||||
export const MetadataContent: React.FC<{ serviceProvider: ServiceProvider; localeCode: string }> = ({
|
||||
serviceProvider,
|
||||
localeCode
|
||||
}) => {
|
||||
export const MetadataContent: React.FC<{
|
||||
serviceProvider: ServiceProvider;
|
||||
localeCode: string;
|
||||
}> = ({ serviceProvider, localeCode }) => {
|
||||
const { logo, title } = getMetadata(serviceProvider);
|
||||
return (
|
||||
<>
|
||||
{title && <MetadataTitle metadata={title} localeCode={localeCode} />}
|
||||
{title && <MetadataTitle localeCode={localeCode} metadata={title} />}
|
||||
{logo && <MetadataLogo metadata={logo} />}
|
||||
</>
|
||||
);
|
||||
|
@ -1,19 +1,18 @@
|
||||
import * as React from 'react';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
|
||||
import { PaymentMethodName, ServiceProvider, ServiceProviderContactInfo } from 'checkout/backend';
|
||||
import { getMetadata, PaymentMethodItemContainer } from 'checkout/components/ui';
|
||||
import {
|
||||
FormName,
|
||||
PaymentTerminalFormInfo,
|
||||
PaymentTerminalSelectorFormInfo,
|
||||
ResultFormInfo,
|
||||
ResultType
|
||||
ResultType,
|
||||
} from 'checkout/hooks';
|
||||
import { getMetadata, PaymentMethodItemContainer } from 'checkout/components/ui';
|
||||
import { PaymentMethodName, ServiceProvider, ServiceProviderContactInfo } from 'checkout/backend';
|
||||
import { Content } from './content';
|
||||
import { PaymentTerminalPaymentMethod, useCreatePayment, PaymentTerminalFormValues } from 'checkout/hooks';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
|
||||
import { Content } from './content';
|
||||
import { InitialContext } from '../../../../../../initial-context';
|
||||
import { ModalContext } from '../../../../../modal-context';
|
||||
|
||||
@ -30,7 +29,7 @@ const isRequiredPhoneNumber = (contactInfo: ServiceProviderContactInfo, phoneNum
|
||||
const isRequiredPaymentTerminalForm = (
|
||||
serviceProvider: ServiceProvider,
|
||||
emailPrefilled: boolean,
|
||||
phoneNumberPrefilled: boolean
|
||||
phoneNumberPrefilled: boolean,
|
||||
): boolean => {
|
||||
const { form, contactInfo } = getMetadata(serviceProvider);
|
||||
return (
|
||||
@ -59,8 +58,8 @@ export const PaymentTerminalMethodItem = ({ method }: PaymentTerminalMethodItemP
|
||||
setFormData({
|
||||
method: PaymentMethodName.PaymentTerminal,
|
||||
values: {
|
||||
provider: serviceProvider.id
|
||||
} as PaymentTerminalFormValues
|
||||
provider: serviceProvider.id,
|
||||
} as PaymentTerminalFormValues,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -78,7 +77,7 @@ export const PaymentTerminalMethodItem = ({ method }: PaymentTerminalMethodItemP
|
||||
|
||||
return (
|
||||
<PaymentMethodItemContainer id={`${Math.floor(Math.random() * 100)}-payment-method-item`} onClick={onClick}>
|
||||
<Content method={method} localeCode={initConfig.locale} />
|
||||
<Content localeCode={initConfig.locale} method={method} />
|
||||
</PaymentMethodItemContainer>
|
||||
);
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { KnownProviderCategories, PaymentTerminalPaymentMethod } from 'checkout/hooks';
|
||||
import { assertUnreachable } from 'checkout/utils';
|
||||
|
||||
import { PaymentTerminalMethodItem } from './payment-terminal-method-item';
|
||||
|
||||
export interface PaymentTerminalMethodItemsProps {
|
||||
|
@ -1,11 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { PaymentMethodIcon, PaymentMethodTitle } from 'checkout/components/ui';
|
||||
import { FormName, WalletProvidersFormInfo } from 'checkout/hooks';
|
||||
|
||||
import { Method } from './method';
|
||||
import { Text } from './text';
|
||||
import { PaymentMethodIcon, PaymentMethodTitle } from 'checkout/components/ui';
|
||||
|
||||
import { InitialContext } from '../../../../../initial-context';
|
||||
import { ModalContext } from '../../../../modal-context';
|
||||
|
||||
@ -18,7 +17,7 @@ export const Wallets = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Method onClick={onClick} id="wallets-payment-method">
|
||||
<Method id="wallets-payment-method" onClick={onClick}>
|
||||
<PaymentMethodIcon name="wallets" />
|
||||
<Text>
|
||||
<PaymentMethodTitle>{locale['form.payment.method.name.wallet.label']}</PaymentMethodTitle>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user