mirror of
https://github.com/valitydev/checkout.git
synced 2024-11-06 02:25:18 +00:00
TD-681: Migrate to Vite (#219)
This commit is contained in:
parent
1c448dcc40
commit
8d4dd2fa4d
2
.github/workflows/master.yaml
vendored
2
.github/workflows/master.yaml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
- name: Set checkout version
|
||||
uses: jossef/action-set-json-field@v2
|
||||
with:
|
||||
file: ./dist/env.json
|
||||
file: ./dist/v1/env.json
|
||||
field: version
|
||||
value: ${{ github.sha }}
|
||||
- name: Deploy image
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,4 +2,3 @@
|
||||
/dist/
|
||||
Dockerfile
|
||||
.DS_Store
|
||||
/.cache-loader/
|
||||
|
5
.idea/.gitignore
vendored
5
.idea/.gitignore
vendored
@ -1,5 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CamelCaseConfig">
|
||||
<option name="cb5State" value="false" />
|
||||
<option name="cb6State" value="false" />
|
||||
<option name="cb7State" value="false" />
|
||||
</component>
|
||||
</project>
|
@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.cache-loader" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -1,58 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<HTMLCodeStyleSettings>
|
||||
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
||||
<option name="HTML_ENFORCE_QUOTES" value="true" />
|
||||
</HTMLCodeStyleSettings>
|
||||
<JSCodeStyleSettings version="0">
|
||||
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
||||
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
||||
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
||||
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
||||
</JSCodeStyleSettings>
|
||||
<TypeScriptCodeStyleSettings version="0">
|
||||
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
||||
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
||||
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
||||
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
||||
</TypeScriptCodeStyleSettings>
|
||||
<VueCodeStyleSettings>
|
||||
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
|
||||
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
|
||||
</VueCodeStyleSettings>
|
||||
<codeStyleSettings language="HTML">
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JavaScript">
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="TypeScript">
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="Vue">
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
@ -1,5 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
@ -1,6 +0,0 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="TsLint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/checkout.iml" filepath="$PROJECT_DIR$/.idea/checkout.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PrettierConfiguration">
|
||||
<option name="myConfigurationMode" value="AUTOMATIC" />
|
||||
<option name="myRunOnSave" value="true" />
|
||||
<option name="myRunOnReformat" value="true" />
|
||||
<option name="myFilesPattern" value="{**/*,*}.{js,ts,jsx,tsx,json}" />
|
||||
</component>
|
||||
</project>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -27,7 +27,6 @@ package-lock.json
|
||||
package.json
|
||||
node_modules
|
||||
dist
|
||||
.cache-loader
|
||||
|
||||
# VS Code
|
||||
.vscode
|
||||
|
5
.vscode/extensions.json
vendored
5
.vscode/extensions.json
vendored
@ -1,5 +0,0 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"eamodio.toggle-excluded-files"
|
||||
]
|
||||
}
|
21
.vscode/settings.json
vendored
21
.vscode/settings.json
vendored
@ -1,21 +0,0 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"Unmount",
|
||||
"Euroset",
|
||||
"QPS"
|
||||
],
|
||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||
"prettier.configPath": ".prettierrc",
|
||||
"prettier.prettierPath": "node_modules/prettier",
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"files.exclude": {
|
||||
".cache-loader": true,
|
||||
".vscode": true,
|
||||
"**/.DS_Store": true,
|
||||
"**/.git": true,
|
||||
"**/.hg": true,
|
||||
"**/.svn": true,
|
||||
"**/CVS": true
|
||||
},
|
||||
}
|
@ -12,5 +12,6 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="src/app/index.tsx"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,49 +0,0 @@
|
||||
const path = require('path');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
name: 'checkout',
|
||||
stats: {
|
||||
children: false,
|
||||
moduleTrace: false,
|
||||
modules: false
|
||||
},
|
||||
entry: {
|
||||
app: ['./src/app/polyfills.ts', './src/app/index.tsx']
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
commons: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: 'vendor',
|
||||
chunks: 'all'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
modules: ['node_modules', path.join(__dirname, 'src/app')],
|
||||
extensions: ['.ts', '.tsx', '.js', '.mjs'],
|
||||
alias: {
|
||||
checkout: __dirname + '/../src/app'
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
template: './src/app/index.html',
|
||||
filename: 'checkout.html'
|
||||
}),
|
||||
new CopyWebpackPlugin(
|
||||
[
|
||||
{ from: './src/app/finish-interaction.html' },
|
||||
{ from: './src/appConfig.json', to: '..' },
|
||||
{ from: './src/env.json', to: '..' },
|
||||
{ from: './src/locale/*.json', to: './locale', flatten: true },
|
||||
{ from: './src/assets', to: '../assets' }
|
||||
],
|
||||
{ logLevel: 'warn' }
|
||||
)
|
||||
]
|
||||
};
|
@ -1,90 +0,0 @@
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
module.exports = (env) => ({
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(ts|tsx)$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'thread-loader',
|
||||
options: {
|
||||
workers: Math.round(os.cpus().length / 2)
|
||||
}
|
||||
},
|
||||
'cache-loader',
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
happyPackMode: true,
|
||||
// TODO: после закрытия issue https://github.com/Igorbek/typescript-plugin-styled-components/issues/14
|
||||
// добавить минификацию styled-components под prod
|
||||
...(env === 'development'
|
||||
? { getCustomTransformers: path.join(__dirname, './ts-transformers.js') }
|
||||
: {})
|
||||
}
|
||||
}
|
||||
],
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /\.mjs$/,
|
||||
include: /node_modules/,
|
||||
type: 'javascript/auto'
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
minimize: true,
|
||||
modules: true,
|
||||
namedExport: true,
|
||||
localIdentName: '[local]__[hash:5]'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(jpeg|jpg)$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[hash:8].[ext]',
|
||||
outputPath: './assets/',
|
||||
mimetype: 'mimetype=image/jpeg'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
oneOf: [
|
||||
{
|
||||
loader: 'svg-react-loader',
|
||||
issuer: /\.tsx?$/,
|
||||
options: {
|
||||
classIdPrefix: '[name]-[hash:8]__',
|
||||
uniqueIdPrefix: true
|
||||
}
|
||||
}
|
||||
],
|
||||
exclude: /node_modules/
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new ForkTsCheckerWebpackPlugin({
|
||||
checkSyntacticErrors: true,
|
||||
formatter: 'codeframe',
|
||||
tslint: true
|
||||
})
|
||||
]
|
||||
});
|
@ -1,10 +0,0 @@
|
||||
const path = require('path');
|
||||
|
||||
const _root = path.resolve(__dirname, '..');
|
||||
|
||||
function root(args) {
|
||||
args = Array.prototype.slice.call(arguments, 0);
|
||||
return path.join.apply(path, [_root].concat(args));
|
||||
}
|
||||
|
||||
exports.root = root;
|
@ -1,17 +0,0 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
name: 'initializer',
|
||||
stats: {
|
||||
children: false,
|
||||
moduleTrace: false,
|
||||
modules: false
|
||||
},
|
||||
entry: {
|
||||
checkout: './src/initializer/index.ts'
|
||||
},
|
||||
resolve: {
|
||||
modules: ['node_modules', path.join(__dirname, 'src/initializer')],
|
||||
extensions: ['.ts', '.js']
|
||||
}
|
||||
};
|
@ -1,13 +0,0 @@
|
||||
const helpers = require('./helpers');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
|
||||
const prepareOutputConfig = (outputPath, jsFilenamePattern = '[name]', cssFilenamePattern = '[name]') => ({
|
||||
output: {
|
||||
filename: `${jsFilenamePattern}.js`,
|
||||
path: helpers.root(outputPath),
|
||||
publicPath: './'
|
||||
},
|
||||
plugins: [new MiniCssExtractPlugin({ filename: `${cssFilenamePattern}.css` })]
|
||||
});
|
||||
|
||||
module.exports = prepareOutputConfig;
|
@ -1,6 +0,0 @@
|
||||
const createStyledComponentsTransformer = require('typescript-plugin-styled-components').default;
|
||||
|
||||
const styledComponentsTransformer = createStyledComponentsTransformer({ ssr: false, displayName: true });
|
||||
const getCustomTransformers = () => ({ before: [styledComponentsTransformer] });
|
||||
|
||||
module.exports = getCustomTransformers;
|
@ -1,32 +0,0 @@
|
||||
const path = require('path');
|
||||
const WriteFilePlugin = require('write-file-webpack-plugin');
|
||||
const merge = require('webpack-merge');
|
||||
const checkoutConfig = require('./checkout-config');
|
||||
const initializerConfig = require('./initializer-config');
|
||||
const prepareOutputConfig = require('./prepare-output-config');
|
||||
const commonConfig = require('./common-config');
|
||||
|
||||
const commonDevConfig = {
|
||||
devtool: 'source-map',
|
||||
plugins: [
|
||||
new WriteFilePlugin({
|
||||
log: false
|
||||
})
|
||||
],
|
||||
devServer: {
|
||||
contentBase: path.join(__dirname, '../dist'),
|
||||
compress: true,
|
||||
disableHostCheck: false,
|
||||
stats: 'minimal'
|
||||
}
|
||||
};
|
||||
|
||||
const baseOutput = 'dist';
|
||||
|
||||
const prepareModule = (env, baseConfig, outputPath) =>
|
||||
merge(baseConfig, commonConfig(env), prepareOutputConfig(outputPath), commonDevConfig);
|
||||
|
||||
module.exports = (env, { mode }) => [
|
||||
prepareModule(mode, checkoutConfig, `${baseOutput}/v1`),
|
||||
prepareModule(mode, initializerConfig, baseOutput)
|
||||
];
|
@ -1,32 +0,0 @@
|
||||
const webpack = require('webpack');
|
||||
const merge = require('webpack-merge');
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
const checkoutConfig = require('./checkout-config');
|
||||
const initializerConfig = require('./initializer-config');
|
||||
const prepareOutputConfig = require('./prepare-output-config');
|
||||
const commonConfig = require('./common-config');
|
||||
|
||||
const commonProdConfig = {
|
||||
devtool: 'source-map',
|
||||
plugins: [
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify('production')
|
||||
}
|
||||
}),
|
||||
new BundleAnalyzerPlugin({
|
||||
analyzerMode: 'disabled'
|
||||
})
|
||||
]
|
||||
};
|
||||
|
||||
const baseOutput = 'dist';
|
||||
|
||||
const prepareModule = (env, baseConfig, outputPath, jsPattern, cssPattern) =>
|
||||
merge(baseConfig, commonConfig(env), prepareOutputConfig(outputPath, jsPattern, cssPattern), commonProdConfig);
|
||||
|
||||
module.exports = (env, { mode }) => [
|
||||
prepareModule(mode, checkoutConfig, `${baseOutput}/v1`, '[name].[hash:20]', '[hash:20]'),
|
||||
prepareModule(mode, initializerConfig, baseOutput)
|
||||
];
|
17625
package-lock.json
generated
17625
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
41
package.json
41
package.json
@ -3,16 +3,18 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"clear": "rimraf dist && rimraf .cache-loader",
|
||||
"build": "npm run clear && webpack --mode production --colors --progress --config config/webpack.prod.js",
|
||||
"start": "npm run clear && webpack-dev-server --mode development --colors --progress --config config/webpack.dev.js --port 7050 --host ::",
|
||||
"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",
|
||||
"preview": "npm run build && vite --c vite.config.preview.ts",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"check": "npm run lint:fix; npm run prettier:check",
|
||||
"fix": "npm run lint:fix; npm run prettier:fix",
|
||||
"prettier:fix": "prettier \"**\" --write",
|
||||
"prettier:check": "prettier \"**\" --list-different",
|
||||
"lint:fix": "tslint \"src/**/*.@(ts|tsx)\" -e \"**/*.d.ts\""
|
||||
"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"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@ -43,37 +45,20 @@
|
||||
"@types/react": "18.2.14",
|
||||
"@types/react-dom": "18.2.6",
|
||||
"@types/react-test-renderer": "18.0.0",
|
||||
"cache-loader": "4.1.0",
|
||||
"concurrently": "7.0.0",
|
||||
"copy-webpack-plugin": "~5.1.1",
|
||||
"css-loader": "~1.0.1",
|
||||
"file-loader": "~2.0.0",
|
||||
"fork-ts-checker-webpack-plugin": "~4.1.1",
|
||||
"html-webpack-plugin": "~3.2.0",
|
||||
"identity-obj-proxy": "~3.0.0",
|
||||
"@vitejs/plugin-react": "4.0.3",
|
||||
"jest": "29.5.0",
|
||||
"jest-environment-jsdom": "29.5.0",
|
||||
"mini-css-extract-plugin": "~0.4.5",
|
||||
"prettier": "~1.19.1",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"rimraf": "~2.6.2",
|
||||
"style-loader": "~0.23.1",
|
||||
"svg-react-loader": "~0.4.6",
|
||||
"thread-loader": "~2.1.2",
|
||||
"ts-jest": "29.1.0",
|
||||
"ts-loader": "~5.3.3",
|
||||
"tslint": "~5.11.0",
|
||||
"tslint-config-prettier": "~1.18.0",
|
||||
"tslint-immutable": "~4.5.1",
|
||||
"tslint-loader": "~3.5.4",
|
||||
"tslint-react": "~3.6.0",
|
||||
"typescript": "4.5.4",
|
||||
"typescript-plugin-styled-components": "~1.0.0",
|
||||
"webpack": "~4.29.0",
|
||||
"webpack-bundle-analyzer": "~3.6.0",
|
||||
"webpack-cli": "~3.3.0",
|
||||
"webpack-dev-server": "~3.11.0",
|
||||
"webpack-merge": "~4.2.1",
|
||||
"write-file-webpack-plugin": "~4.5.0"
|
||||
"vite": "4.4.6",
|
||||
"vite-plugin-static-copy": "0.17.0",
|
||||
"vite-plugin-svgr": "3.2.0",
|
||||
"vite-tsconfig-paths": "4.2.0"
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,4 @@ import { getNocacheValue } from 'checkout/utils';
|
||||
import { fetchCapi } from './fetch-capi';
|
||||
|
||||
export const getAppConfig = (): Promise<AppConfig> =>
|
||||
fetchCapi({ endpoint: `../appConfig.json?nocache=${getNocacheValue()}` });
|
||||
fetchCapi({ endpoint: `./appConfig.json?nocache=${getNocacheValue()}` });
|
||||
|
@ -5,4 +5,4 @@ export interface Env {
|
||||
version: string;
|
||||
}
|
||||
|
||||
export const getEnv = (): Promise<Env> => fetchCapi({ endpoint: `../env.json?nocache=${getNocacheValue()}` });
|
||||
export const getEnv = (): Promise<Env> => fetchCapi({ endpoint: `./env.json?nocache=${getNocacheValue()}` });
|
||||
|
@ -4,9 +4,10 @@ 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 { User, Input } from 'checkout/components';
|
||||
import { Input } from 'checkout/components';
|
||||
import { CardFormInputs } from '../../card-form-inputs';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
import { ReactComponent as UserIcon } from '../../../../../../../ui/icon/user.svg';
|
||||
|
||||
export type CardHolderProps = {
|
||||
register: UseFormRegister<CardFormInputs>;
|
||||
@ -21,7 +22,7 @@ export const CardHolder = ({ register, locale, fieldError, isDirty }: CardHolder
|
||||
required: true,
|
||||
validate: (value) => !validateCardHolder(value) || 'Card holder is invalid'
|
||||
})}
|
||||
icon={<User />}
|
||||
icon={<UserIcon />}
|
||||
placeholder={locale['form.input.cardholder.placeholder']}
|
||||
mark={true}
|
||||
id="card-holder-input"
|
||||
|
@ -2,13 +2,14 @@ import * as React from 'react';
|
||||
import { FieldError, UseFormRegister, UseFormWatch } from 'react-hook-form';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { CardTypeIcon } from './card-type-icon';
|
||||
import { validateCardNumber } from './validate-card-number';
|
||||
import { Card, Input } from 'checkout/components';
|
||||
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';
|
||||
|
||||
const InputContainer = styled.div`
|
||||
width: 100%;
|
||||
@ -36,7 +37,7 @@ export const CardNumber = ({ register, locale, fieldError, isDirty, watch }: Car
|
||||
required: true,
|
||||
validate: (value) => !validateCardNumber(value) || 'Card number is invalid'
|
||||
})}
|
||||
icon={<Card />}
|
||||
icon={<CardIcon />}
|
||||
placeholder={locale['form.input.card.placeholder']}
|
||||
mark={true}
|
||||
type="tel"
|
||||
|
@ -1,58 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { number } from 'card-validator';
|
||||
import styled, { keyframes } from 'styled-components';
|
||||
|
||||
import * as cardIcons from 'checkout/components/ui/icon/card';
|
||||
|
||||
interface CardTypeIconProps {
|
||||
cardNumber: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const growth = keyframes`
|
||||
from {
|
||||
transform: scale(0);
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
}
|
||||
`;
|
||||
|
||||
const cardIconsMapping = {
|
||||
visa: cardIcons.Visa,
|
||||
mastercard: cardIcons.Mastercard,
|
||||
maestro: cardIcons.Maestro,
|
||||
mir: cardIcons.Mir,
|
||||
'american-express': cardIcons.AmericanExpress,
|
||||
'diners-club': cardIcons.DinersClub,
|
||||
discover: cardIcons.Discover,
|
||||
jcb: cardIcons.Jcb,
|
||||
unionpay: cardIcons.Unionpay,
|
||||
elo: cardIcons.Elo,
|
||||
hipercard: cardIcons.Hipercard
|
||||
};
|
||||
|
||||
export function getCardIconClass(cardNumber: string) {
|
||||
const { card } = number(cardNumber);
|
||||
if (!card) {
|
||||
return;
|
||||
}
|
||||
return (cardIconsMapping as any)[card.type];
|
||||
}
|
||||
|
||||
const CardTypeIconDef = styled<React.FC<CardTypeIconProps>>(({ cardNumber, className }) => {
|
||||
const Icon = getCardIconClass(cardNumber);
|
||||
return Icon ? <Icon className={className} /> : null;
|
||||
})`
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
width: 31px;
|
||||
height: 19px;
|
||||
animation: ${growth} 0.5s;
|
||||
background: #fff;
|
||||
`;
|
||||
|
||||
export const CardTypeIcon = ({ cardNumber }: CardTypeIconProps) => {
|
||||
return <CardTypeIconDef cardNumber={cardNumber} />;
|
||||
};
|
@ -1,2 +1 @@
|
||||
export * from './card-number';
|
||||
export * from './card-type-icon';
|
||||
|
@ -4,9 +4,10 @@ import { FieldError, UseFormRegister } from 'react-hook-form';
|
||||
import { validateExpireDate } from './validate-expire-date';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { formatExpiry } from './format-expiry';
|
||||
import { Calendar, Input } from 'checkout/components';
|
||||
import { Input } from 'checkout/components';
|
||||
import { CardFormInputs } from '../../card-form-inputs';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
import { ReactComponent as CalendarIcon } from '../../../../../../../ui/icon/calendar.svg';
|
||||
|
||||
export type ExpireDateProps = {
|
||||
register: UseFormRegister<CardFormInputs>;
|
||||
@ -21,7 +22,7 @@ export const ExpireDate = ({ register, locale, fieldError, isDirty }: ExpireDate
|
||||
required: true,
|
||||
validate: (value) => !validateExpireDate(value) || 'Exp date is invalid'
|
||||
})}
|
||||
icon={<Calendar />}
|
||||
icon={<CalendarIcon />}
|
||||
placeholder={locale['form.input.expiry.placeholder']}
|
||||
mark={true}
|
||||
type="tel"
|
||||
|
@ -5,10 +5,11 @@ import { FieldError, UseFormRegister } from 'react-hook-form';
|
||||
import { validateSecureCode } from './validate-secure-code';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { formatCVC } from './format-cvc';
|
||||
import { Lock, Input } from 'checkout/components';
|
||||
import { Input } from 'checkout/components';
|
||||
import { safeVal } from 'checkout/utils';
|
||||
import { CardFormInputs } from '../../card-form-inputs';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
import { ReactComponent as LockIcon } from '../../../../../../../ui/icon/lock.svg';
|
||||
|
||||
export interface SecureCodeProps {
|
||||
register: UseFormRegister<CardFormInputs>;
|
||||
@ -30,7 +31,7 @@ export const SecureCode = ({ cardNumber, locale, obscureCardCvv, register, field
|
||||
required: true,
|
||||
validate: (value) => !validateSecureCode(value, { cardNumber }) || 'Secure code is invalid'
|
||||
})}
|
||||
icon={<Lock />}
|
||||
icon={<LockIcon />}
|
||||
placeholder={getPlaceholder(cardNumber, locale)}
|
||||
mark={true}
|
||||
type={obscureCardCvv ? 'password' : 'tel'}
|
||||
|
@ -7,8 +7,8 @@ import { validateAmount } from './validate-amount';
|
||||
import { Locale } from 'checkout/locale';
|
||||
import { InvoiceTemplateLineCostRange, InvoiceTemplateLineCostUnlim } from 'checkout/backend';
|
||||
import { formatAmount } from './format-amount';
|
||||
import { Amount as AmountIcon } from 'checkout/components';
|
||||
import isNil from 'checkout/utils/is-nil';
|
||||
import { ReactComponent as AmountIcon } from '../../../../../../ui/icon/amount.svg';
|
||||
|
||||
export type AmountProps = {
|
||||
register: UseFormRegister<any>;
|
||||
|
57
src/app/components/ui/card-type-icon.tsx
Normal file
57
src/app/components/ui/card-type-icon.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import * as React from 'react';
|
||||
import { number } from 'card-validator';
|
||||
import styled, { keyframes } from 'styled-components';
|
||||
|
||||
import { ReactComponent as Mir } from './icon/card/mir.svg';
|
||||
import { ReactComponent as Unionpay } from './icon/card/unionpay.svg';
|
||||
import { ReactComponent as Visa } from './icon/card/visa.svg';
|
||||
import { ReactComponent as Mastercard } from './icon/card/mastercard.svg';
|
||||
import { ReactComponent as Maestro } from './icon/card/maestro.svg';
|
||||
|
||||
const growth = keyframes`
|
||||
from {
|
||||
transform: scale(0);
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
}
|
||||
`;
|
||||
|
||||
const getIconInstance = (cardNumber: string) => {
|
||||
const { card } = number(cardNumber);
|
||||
if (!card) {
|
||||
return null;
|
||||
}
|
||||
switch (card.type) {
|
||||
case 'mir':
|
||||
return Mir;
|
||||
case 'unionpay':
|
||||
return Unionpay;
|
||||
case 'maestro':
|
||||
return Maestro;
|
||||
case 'mastercard':
|
||||
return Mastercard;
|
||||
case 'visa':
|
||||
return Visa;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
type CardTypeIconProps = React.FC<{
|
||||
cardNumber: string;
|
||||
className?: string;
|
||||
}>;
|
||||
|
||||
export const CardTypeIcon = styled<CardTypeIconProps>(({ cardNumber, className }) => {
|
||||
const Icon = getIconInstance(cardNumber);
|
||||
return Icon ? <Icon className={className} /> : null;
|
||||
})`
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
width: 31px;
|
||||
height: 19px;
|
||||
animation: ${growth} 0.5s;
|
||||
background: #fff;
|
||||
`;
|
@ -1,7 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import { ChevronLeft, ChevronRight } from 'checkout/components';
|
||||
import { styled, css } from 'styled-components';
|
||||
|
||||
import { ReactComponent as ChevronLeftIcon } from '../icon/chevron-left.svg';
|
||||
import { ReactComponent as ChevronRightIcon } from '../icon/chevron-right.svg';
|
||||
|
||||
const Button = styled.button<{ disabled?: boolean }>`
|
||||
border: none;
|
||||
background: none;
|
||||
@ -37,6 +39,6 @@ export type ChevronButtonProps = {
|
||||
|
||||
export const ChevronButton: React.FC<ChevronButtonProps> = ({ id, onClick, type, disabled }) => (
|
||||
<Button aria-disabled={disabled} id={id} onClick={onClick} disabled={disabled}>
|
||||
{type === 'left' && <ChevronLeft />} {type === 'right' && <ChevronRight />}
|
||||
{type === 'left' && <ChevronLeftIcon />} {type === 'right' && <ChevronRightIcon />}
|
||||
</Button>
|
||||
);
|
||||
|
@ -1,9 +0,0 @@
|
||||
<svg width="17" height="17" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
id="icon"
|
||||
d="M8.5 7.3l-6-6-1.2 1.2 6 6-6 6 1.2 1.2 6-6 6 6 1.2-1.2-6-6 6-6-1.2-1.2z"
|
||||
stroke="#e75542"
|
||||
fill-rule="nonzero"
|
||||
fill="#e75542"
|
||||
/>
|
||||
</svg>
|
Before Width: | Height: | Size: 265 B |
@ -1,11 +0,0 @@
|
||||
export { default as Mastercard } from './mastercard.svg';
|
||||
export { default as Visa } from './visa.svg';
|
||||
export { default as Mir } from './mir.svg';
|
||||
export { default as Maestro } from './maestro.svg';
|
||||
export { default as AmericanExpress } from './american-express.svg';
|
||||
export { default as DinersClub } from './diners-club.svg';
|
||||
export { default as Discover } from './discover.svg';
|
||||
export { default as Elo } from './elo.svg';
|
||||
export { default as Hipercard } from './hipercard.svg';
|
||||
export { default as Unionpay } from './unionpay.svg';
|
||||
export { default as Jcb } from './jcb.svg';
|
@ -1,8 +0,0 @@
|
||||
<svg viewBox="0 0 18 18" width="18" height="18" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
id="icon"
|
||||
d="M9 7.59L1.93.5.5 1.93 7.6 9 .5 16.07l1.42 1.42L9 10.4l7.07 7.08 1.42-1.42L10.4 9l7.08-7.07L16.07.5 9 7.6z"
|
||||
fill="#FFF"
|
||||
fill-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
Before Width: | Height: | Size: 292 B |
@ -1,14 +0,0 @@
|
||||
export { default as Amount } from './amount.svg';
|
||||
export { default as BoldCross } from './bold-cross.svg';
|
||||
export { default as Calendar } from './calendar.svg';
|
||||
export { default as Card } from './card.svg';
|
||||
export { default as Checkmark } from './checkmark.svg';
|
||||
export { default as ChevronLeft } from './chevron-left.svg';
|
||||
export { default as ChevronRight } from './chevron-right.svg';
|
||||
export { default as Cross } from './cross.svg';
|
||||
export { default as Letter } from './letter.svg';
|
||||
export { default as Lock } from './lock.svg';
|
||||
export { default as Phone } from './phone.svg';
|
||||
export { default as User } from './user.svg';
|
||||
export { default as Bank } from './bank.svg';
|
||||
export * from './card';
|
@ -1,7 +0,0 @@
|
||||
<svg width="19" height="18" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="icon" fill="none" fill-rule="evenodd">
|
||||
<path fill="#FFF" d="M.5 0h18v18H.5z" />
|
||||
<path d="M2 4l6.3 5a2 2 0 0 0 2.4 0L17 4" stroke="#181818" />
|
||||
<rect stroke="#181818" stroke-width="2" x="2" y="4" width="15" height="10" rx="2" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 342 B |
@ -1,11 +0,0 @@
|
||||
<svg width="18" height="18" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="icon" fill="none" fill-rule="evenodd">
|
||||
<path fill="#FFF" d="M0 0h18v18H0z" />
|
||||
<path
|
||||
d="M14 4v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.1.9-2 2-2h6a2 2 0 0 1 2 2z"
|
||||
stroke="#181818"
|
||||
stroke-width="2"
|
||||
/>
|
||||
<path fill="#181818" d="M7 11h4v1H7z" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 397 B |
@ -1,7 +1,6 @@
|
||||
export * from './list';
|
||||
export * from './link';
|
||||
export * from './loader';
|
||||
export * from './icon';
|
||||
export * from './round-icon';
|
||||
export * from './input';
|
||||
export * from './button';
|
||||
|
@ -2,7 +2,7 @@ import * as React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import styled, { css } from 'styled-components';
|
||||
|
||||
import { Checkmark } from 'checkout/components/ui/icon';
|
||||
import { ReactComponent as Checkmark } from '../icon/checkmark.svg';
|
||||
|
||||
const fadeIn = {
|
||||
hidden: { opacity: 0 },
|
||||
|
@ -1,32 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
|
||||
/>
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>Checkout</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
function inIframe() {
|
||||
try {
|
||||
return window.self !== window.top;
|
||||
} catch (e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
parent.window.postMessage('finish-interaction', '*');
|
||||
if (!inIframe()) {
|
||||
try {
|
||||
window.close();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,5 +1,4 @@
|
||||
import { domReady } from './dom-ready';
|
||||
import { HtmlIntegration } from './html-integration';
|
||||
import { PopupInitializer } from './popup-initializer';
|
||||
import { environment, Configurator } from '../environment';
|
||||
|
||||
@ -8,15 +7,5 @@ const init = (origin: string): Configurator => ({
|
||||
});
|
||||
|
||||
domReady().then((origin) => {
|
||||
const ValityCheckout = (environment.ValityCheckout = init(origin));
|
||||
const htmlIntegration = new HtmlIntegration(origin);
|
||||
if (htmlIntegration.isAvailable) {
|
||||
const userConfig = htmlIntegration.getUserConfig();
|
||||
const checkout = ValityCheckout.configure(userConfig);
|
||||
const payButton = htmlIntegration.renderPayButton(userConfig.label);
|
||||
payButton.onclick = (e: Event) => {
|
||||
e.preventDefault();
|
||||
checkout.open();
|
||||
};
|
||||
}
|
||||
environment.ValityCheckout = init(origin);
|
||||
});
|
||||
|
5
types/svg.d.ts
vendored
5
types/svg.d.ts
vendored
@ -1,4 +1 @@
|
||||
declare module '*.svg' {
|
||||
const value: React.FC<React.SVGProps<SVGSVGElement>>;
|
||||
export default value;
|
||||
}
|
||||
/// <reference types="vite-plugin-svgr/client" />
|
||||
|
51
vite.config.app.ts
Normal file
51
vite.config.app.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||
import { viteStaticCopy } from 'vite-plugin-static-copy';
|
||||
import svgr from 'vite-plugin-svgr';
|
||||
|
||||
export default defineConfig({
|
||||
base: './',
|
||||
build: {
|
||||
outDir: 'dist/v1',
|
||||
rollupOptions: {
|
||||
input: {
|
||||
app: './checkout.html'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
react(),
|
||||
svgr(),
|
||||
tsconfigPaths(),
|
||||
viteStaticCopy({
|
||||
targets: [
|
||||
{
|
||||
src: 'src/appConfig.json',
|
||||
dest: './'
|
||||
},
|
||||
{
|
||||
src: 'src/env.json',
|
||||
dest: './'
|
||||
},
|
||||
{
|
||||
src: 'src/assets/*',
|
||||
dest: './assets'
|
||||
},
|
||||
{
|
||||
src: 'src/locale/*.json',
|
||||
dest: './locale'
|
||||
}
|
||||
]
|
||||
})
|
||||
],
|
||||
server: {
|
||||
port: 7050,
|
||||
proxy: {
|
||||
'^/v1': {
|
||||
target: 'http://localhost:7050',
|
||||
rewrite: (path) => path.replace(/^\/v1/, '')
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
16
vite.config.checkout.ts
Normal file
16
vite.config.checkout.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
lib: {
|
||||
entry: './src/initializer/index.ts',
|
||||
name: 'checkout'
|
||||
},
|
||||
rollupOptions: {
|
||||
output: {
|
||||
entryFileNames: 'checkout.js'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
3
vite.config.preview.ts
Normal file
3
vite.config.preview.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
root: './dist'
|
||||
};
|
Loading…
Reference in New Issue
Block a user