Files
mcb-platform-monorepo/packages/crypto/install/components/crypto-installer-modal.tsx
T
2025-08-12 01:18:10 +03:00

153 lines
4.0 KiB
TypeScript

import React, { useState, useEffect, useCallback } from 'react';
import { useTheme } from '@emotion/react';
import { BaseModal, ModalSheet, STATUS_ICON } from '@fractal-ui/overlays';
import { useBreakpoints } from '@fractal-ui/styling';
import type { FractalUiTheme, StatusIconType } from '@fractal-ui/styling';
import { useTranslation } from 'react-i18next';
import { useHistory } from 'react-router-dom';
import { ModalFooter, downloadCryptoPlugin, LINUX_TYPES, LOCALE_NAME, isLinux, CheckCryptoView } from '../../core';
import type { ModalButtonProps, Installer } from '../../core';
import { STEP, SOURCES, HEADER, BUTTON_TEXT } from '../constants';
import type { CryptoInstallerProps } from '../interfaces';
import { getActions } from '../utils';
import { Info } from './info';
import { InstallResult } from './install-result';
const Views = {
[STEP.CHECK_INSTALL]: CheckCryptoView,
[STEP.INSTALL]: Info,
[STEP.RESULT]: InstallResult,
};
/**
* МО установки КМ.
*/
export const CryptoInstallerModal: React.FC<CryptoInstallerProps> = ({
linkText,
linkUrl,
onSuccess,
onClose,
isOpen,
source = SOURCES.OTHER,
}) => {
const router = useHistory();
const { t } = useTranslation(LOCALE_NAME);
const [step, setStep] = useState<STEP>(STEP.CHECK_INSTALL);
const { XS } = useBreakpoints();
const Component = XS ? ModalSheet : BaseModal;
const theme = useTheme() as unknown as FractalUiTheme;
const iconStyle = (theme?.colors?.modal?.statusIcon ?? 'light') as StatusIconType;
const IconWarning = STATUS_ICON[iconStyle].warning;
useEffect(() => {
if (isOpen) {
setStep(STEP.CHECK_INSTALL);
}
}, [isOpen]);
const next = useCallback(() => {
switch (step) {
case STEP.CHECK_INSTALL:
setStep(STEP.INSTALL);
return;
case STEP.INSTALL:
setStep(STEP.RESULT);
return;
default:
return;
}
}, [step]);
const header = HEADER[step];
const View = Views[step];
const secondaryButtonText = t(BUTTON_TEXT[source]);
const contextItems = LINUX_TYPES.map(type => ({
text: t(`sign.modal.cryptoInstallerModal.btn.${type}`),
onClick: () => {
void downloadCryptoPlugin(type as keyof Installer);
next();
},
}));
const cancelBtn: ModalButtonProps = {
dataAction: 'CLOSE_OR_REDIRECT',
onClick: () => {
linkUrl ? router?.push(linkUrl) : onClose?.();
},
text: linkText ?? secondaryButtonText,
actionBtnType: 'link',
};
const checkActions: ModalButtonProps[] = isLinux()
? [
{
dataAction: 'INSTALL',
text: t('sign.modal.cryptoInstallerModal.btn.installCryptomodul'),
preventClose: true,
actionBtnType: 'dropdown',
items: contextItems,
},
cancelBtn,
]
: [
{
dataAction: 'INSTALL',
onClick: () => {
void downloadCryptoPlugin();
next();
},
text: t('sign.modal.cryptoInstallerModal.btn.installCryptomodul'),
preventClose: true,
actionBtnType: 'button',
},
cancelBtn,
];
const installActions: ModalButtonProps[] = [cancelBtn];
const resultActions: ModalButtonProps[] = [
{
dataAction: 'TRY_AGAIN',
onClick: () => {
onSuccess?.();
onClose?.();
},
text: t('sign.modal.cryptoInstallerModal.btn.tryAgain'),
preventClose: true,
actionBtnType: 'button',
},
cancelBtn,
];
const actions = getActions({
checkActions,
resultActions,
installActions,
step,
});
return (
<Component
actionsDirection="vertical"
align="center"
footer={<ModalFooter actions={actions} actionsDirection="vertical" onClose={onClose} />}
header={t(header) ?? ''}
icon={IconWarning}
isOpen={isOpen}
padding="modal.status.M"
width="modal.status.width.M"
onClose={onClose}
>
<View next={next} source={source} onClose={onClose} />
</Component>
);
};
CryptoInstallerModal.displayName = 'CryptoInstallerModal';