1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-11 05:54:15 +01:00

213 lines
8.7 KiB
TypeScript
Raw Normal View History

2021-03-31 16:03:51 +02:00
import React, { ReactNode, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
2021-03-31 17:58:09 +02:00
import { enableMapSet } from 'immer';
import { useImmer } from 'use-immer';
import { HtmlTranslate } from '../../base/html-translate';
import { FabInput } from '../../base/fab-input';
import { Loader } from '../../base/loader';
import { SettingName } from '../../../models/setting';
import SettingAPI from '../../../api/setting';
import PayzenAPI from '../../../api/payzen';
2021-03-31 16:03:51 +02:00
2021-03-31 17:58:09 +02:00
enableMapSet();
2021-03-31 16:03:51 +02:00
interface PayZenKeysFormProps {
onValidKeys: (payZenSettings: Map<SettingName, string>) => void
}
// all settings related to PayZen that are requested by this form
2021-03-31 17:58:09 +02:00
const payZenSettings: Array<SettingName> = [SettingName.PayZenUsername, SettingName.PayZenPassword, SettingName.PayZenEndpoint, SettingName.PayZenHmacKey, SettingName.PayZenPublicKey];
// settings related the to PayZen REST API (server side)
2021-04-02 16:02:50 +02:00
const restApiSettings: Array<SettingName> = [SettingName.PayZenUsername, SettingName.PayZenPassword, SettingName.PayZenEndpoint, SettingName.PayZenHmacKey];
2021-04-02 16:02:50 +02:00
// Prevent multiples call to the payzen keys validation endpoint.
// this cannot be handled by a React state because of their asynchronous nature
let pendingKeysValidation = false;
2021-04-08 09:35:09 +02:00
/**
* Form to set the PayZen's username, password and public key
*/
2021-03-31 16:03:51 +02:00
const PayZenKeysFormComponent: React.FC<PayZenKeysFormProps> = ({ onValidKeys }) => {
const { t } = useTranslation('admin');
2021-04-08 09:35:09 +02:00
// values of the PayZen settings
2021-03-31 17:58:09 +02:00
const [settings, updateSettings] = useImmer<Map<SettingName, string>>(new Map(payZenSettings.map(name => [name, ''])));
2021-04-08 09:35:09 +02:00
// Icon of the fieldset for the PayZen's keys concerning the REST API. Used to display if the key is valid.
2021-03-31 16:03:51 +02:00
const [restApiAddOn, setRestApiAddOn] = useState<ReactNode>(null);
2021-04-08 09:35:09 +02:00
// Style class for the add-on icon, for the REST API
const [restApiAddOnClassName, setRestApiAddOnClassName] = useState<'key-invalid' | 'key-valid' | ''>('');
// Icon of the input field for the PayZen's public key. Used to display if the key is valid.
2021-03-31 16:03:51 +02:00
const [publicKeyAddOn, setPublicKeyAddOn] = useState<ReactNode>(null);
2021-04-08 09:35:09 +02:00
// Style class for the add-on icon, for the public key
const [publicKeyAddOnClassName, setPublicKeyAddOnClassName] = useState<'key-invalid' | 'key-valid' | ''>('');
2021-03-31 16:03:51 +02:00
2021-04-08 09:35:09 +02:00
/**
* When the component loads for the first time, initialize the keys with the values fetched from the API (if any)
*/
2021-03-31 16:03:51 +02:00
useEffect(() => {
const api = new SettingAPI();
api.query(payZenSettings).then(payZenKeys => {
updateSettings(new Map(payZenKeys));
}).catch(error => console.error(error));
2021-03-31 16:03:51 +02:00
}, []);
2021-04-08 09:35:09 +02:00
/**
* When the style class for the public key, and the REST API are updated, check if they indicate valid keys.
* If both are valid, run the 'onValidKeys' callback
*/
2021-03-31 16:03:51 +02:00
useEffect(() => {
const validClassName = 'key-valid';
if (publicKeyAddOnClassName === validClassName && restApiAddOnClassName === validClassName) {
onValidKeys(settings);
}
}, [publicKeyAddOnClassName, restApiAddOnClassName, settings]);
2021-03-31 16:03:51 +02:00
2021-04-02 16:02:50 +02:00
useEffect(() => {
testRestApi();
}, [settings])
2021-03-31 16:03:51 +02:00
/**
2021-04-02 16:02:50 +02:00
* Assign the inputted key to the settings and check if it is valid.
* Depending on the test result, assign an add-on icon and a style to notify the user.
2021-03-31 16:03:51 +02:00
*/
const testPublicKey = (key: string) => {
if (!key.match(/^[0-9]+:/)) {
setPublicKeyAddOn(<i className="fa fa-times" />);
setPublicKeyAddOnClassName('key-invalid');
return;
}
2021-03-31 17:58:09 +02:00
updateSettings(draft => draft.set(SettingName.PayZenPublicKey, key));
2021-03-31 16:03:51 +02:00
setPublicKeyAddOn(<i className="fa fa-check" />);
setPublicKeyAddOnClassName('key-valid');
}
/**
2021-04-02 16:02:50 +02:00
* Send a test call to the payZen REST API to check if the inputted settings key are valid.
* Depending on the test result, assign an add-on icon and a style to notify the user.
2021-03-31 16:03:51 +02:00
*/
2021-04-02 16:02:50 +02:00
const testRestApi = () => {
let valid: boolean = restApiSettings.map(s => !!settings.get(s))
.reduce((acc, val) => acc && val, true);
if (valid && !pendingKeysValidation) {
pendingKeysValidation = true;
PayzenAPI.chargeSDKTest(
settings.get(SettingName.PayZenEndpoint),
settings.get(SettingName.PayZenUsername),
settings.get(SettingName.PayZenPassword)
).then(result => {
pendingKeysValidation = false;
if (result.success) {
setRestApiAddOn(<i className="fa fa-check" />);
setRestApiAddOnClassName('key-valid');
} else {
setRestApiAddOn(<i className="fa fa-times" />);
setRestApiAddOnClassName('key-invalid');
2021-04-02 16:02:50 +02:00
}
}, () => {
pendingKeysValidation = false;
setRestApiAddOn(<i className="fa fa-times" />);
setRestApiAddOnClassName('key-invalid');
});
}
2021-04-02 17:16:27 +02:00
if (!valid) {
setRestApiAddOn(<i className="fa fa-times" />);
setRestApiAddOnClassName('key-invalid');
}
2021-04-02 16:02:50 +02:00
}
/**
* Assign the inputted key to the given settings
*/
const setApiKey = (setting: SettingName.PayZenUsername | SettingName.PayZenPassword | SettingName.PayZenEndpoint | SettingName.PayZenHmacKey) => {
return (key: string) => {
updateSettings(draft => draft.set(setting, key));
}
2021-03-31 16:03:51 +02:00
}
/**
* Check if an add-on icon must be shown for the API settings
*/
const hasApiAddOn = () => {
return restApiAddOn !== null;
}
return (
<div className="payzen-keys-form">
2021-04-07 16:25:14 +02:00
<div className="payzen-keys-info">
<HtmlTranslate trKey="app.admin.invoices.payment.payzen_keys_info_html" />
</div>
2021-03-31 16:03:51 +02:00
<form name="payzenKeysForm">
<fieldset>
<legend>{t('app.admin.invoices.payment.client_keys')}</legend>
<div className="payzen-public-input">
2021-04-06 17:47:47 +02:00
<label htmlFor="payzen_public_key">{ t('app.admin.invoices.payment.payzen.payzen_public_key') } *</label>
2021-03-31 16:03:51 +02:00
<FabInput id="payzen_public_key"
icon={<i className="fas fa-info" />}
2021-04-02 17:16:27 +02:00
defaultValue={settings.get(SettingName.PayZenPublicKey)}
2021-03-31 16:03:51 +02:00
onChange={testPublicKey}
addOn={publicKeyAddOn}
addOnClassName={publicKeyAddOnClassName}
debounce={200}
required />
</div>
</fieldset>
<fieldset>
<legend className={hasApiAddOn() ? 'with-addon' : ''}>
<span>{t('app.admin.invoices.payment.api_keys')}</span>
{hasApiAddOn() && <span className={`fieldset-legend--addon ${restApiAddOnClassName ? restApiAddOnClassName : ''}`}>{restApiAddOn}</span>}
</legend>
<div className="payzen-api-user-input">
2021-04-06 17:47:47 +02:00
<label htmlFor="payzen_username">{ t('app.admin.invoices.payment.payzen.payzen_username') } *</label>
2021-03-31 16:03:51 +02:00
<FabInput id="payzen_username"
type="number"
icon={<i className="fas fa-user-alt" />}
2021-04-02 17:16:27 +02:00
defaultValue={settings.get(SettingName.PayZenUsername)}
2021-04-02 16:02:50 +02:00
onChange={setApiKey(SettingName.PayZenUsername)}
2021-03-31 16:03:51 +02:00
debounce={200}
required />
</div>
<div className="payzen-api-password-input">
2021-04-06 17:47:47 +02:00
<label htmlFor="payzen_password">{ t('app.admin.invoices.payment.payzen.payzen_password') } *</label>
2021-03-31 16:03:51 +02:00
<FabInput id="payzen_password"
icon={<i className="fas fa-key" />}
2021-04-02 17:16:27 +02:00
defaultValue={settings.get(SettingName.PayZenPassword)}
2021-04-02 16:02:50 +02:00
onChange={setApiKey(SettingName.PayZenPassword)}
2021-03-31 16:03:51 +02:00
debounce={200}
required />
</div>
<div className="payzen-api-endpoint-input">
2021-04-06 17:47:47 +02:00
<label htmlFor="payzen_endpoint">{ t('app.admin.invoices.payment.payzen.payzen_endpoint') } *</label>
2021-03-31 16:03:51 +02:00
<FabInput id="payzen_endpoint"
type="url"
icon={<i className="fas fa-link" />}
2021-04-02 17:16:27 +02:00
defaultValue={settings.get(SettingName.PayZenEndpoint)}
2021-04-02 16:02:50 +02:00
onChange={setApiKey(SettingName.PayZenEndpoint)}
2021-03-31 16:03:51 +02:00
debounce={200}
required />
</div>
<div className="payzen-api-hmac-input">
2021-04-06 17:47:47 +02:00
<label htmlFor="payzen_hmac">{ t('app.admin.invoices.payment.payzen.payzen_hmac') } *</label>
2021-03-31 16:03:51 +02:00
<FabInput id="payzen_hmac"
icon={<i className="fas fa-subscript" />}
2021-04-02 17:16:27 +02:00
defaultValue={settings.get(SettingName.PayZenHmacKey)}
2021-04-02 16:02:50 +02:00
onChange={setApiKey(SettingName.PayZenHmacKey)}
2021-03-31 16:03:51 +02:00
debounce={200}
required />
</div>
</fieldset>
</form>
</div>
);
}
export const PayZenKeysForm: React.FC<PayZenKeysFormProps> = ({ onValidKeys }) => {
return (
<Loader>
<PayZenKeysFormComponent onValidKeys={onValidKeys} />
</Loader>
);
}