Introduce new DonationErrorModal component

Co-authored-by: ayumi-signal <143036029+ayumi-signal@users.noreply.github.com>
This commit is contained in:
Scott Nonnenberg 2025-07-15 09:06:25 +10:00 committed by GitHub
commit e938e68c7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 180 additions and 6 deletions

View file

@ -0,0 +1,58 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './DonationErrorModal';
import { DonationErrorModal } from './DonationErrorModal';
import { donationErrorTypeSchema } from '../types/Donations';
const { i18n } = window.SignalContext;
export default {
title: 'Components/DonationErrorModal',
} satisfies Meta<PropsType>;
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export function DonationProcessingError(): JSX.Element {
return (
<DonationErrorModal
{...defaultProps}
errorType={donationErrorTypeSchema.Enum.DonationProcessingError}
/>
);
}
export function Failed3dsValidation(): JSX.Element {
return (
<DonationErrorModal
{...defaultProps}
errorType={donationErrorTypeSchema.Enum.Failed3dsValidation}
/>
);
}
export function GeneralError(): JSX.Element {
return (
<DonationErrorModal
{...defaultProps}
errorType={donationErrorTypeSchema.Enum.GeneralError}
/>
);
}
export function PaymentDeclined(): JSX.Element {
return (
<DonationErrorModal
{...defaultProps}
errorType={donationErrorTypeSchema.Enum.PaymentDeclined}
/>
);
}

View file

@ -0,0 +1,68 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { ReactNode } from 'react';
import { missingCaseError } from '../util/missingCaseError';
import { donationErrorTypeSchema } from '../types/Donations';
import type { LocalizerType } from '../types/Util';
import type { DonationErrorType } from '../types/Donations';
import { Button } from './Button';
import { Modal } from './Modal';
export type PropsType = {
i18n: LocalizerType;
onClose: () => void;
errorType: DonationErrorType;
};
export function DonationErrorModal(props: PropsType): JSX.Element {
const { i18n, onClose } = props;
let title: string;
let body: ReactNode;
switch (props.errorType) {
case donationErrorTypeSchema.Enum.DonationProcessingError: {
title = i18n('icu:Donations__ErrorProcessingDonation');
body = i18n('icu:Donations__ErrorProcessingDonation__Description');
break;
}
case donationErrorTypeSchema.Enum.Failed3dsValidation: {
title = i18n('icu:Donations__Failed3dsValidation');
body = i18n('icu:Donations__Failed3dsValidation__Description');
break;
}
case donationErrorTypeSchema.Enum.GeneralError: {
title = i18n('icu:Donations__GenericError');
body = i18n('icu:Donations__GenericError__Description');
break;
}
case donationErrorTypeSchema.Enum.PaymentDeclined: {
title = i18n('icu:Donations__PaymentMethodDeclined');
body = i18n('icu:Donations__PaymentMethodDeclined__Description');
break;
}
default:
throw missingCaseError(props.errorType);
}
return (
<Modal
i18n={i18n}
modalFooter={
<Button onClick={onClose}>{i18n('icu:Confirmation--confirm')}</Button>
}
hasXButton
moduleClassName="DonationErrorModal"
modalName="DonationErrorModal"
onClose={onClose}
title={title}
>
{body}
</Modal>
);
}

View file

@ -13,16 +13,14 @@ export const donationStateSchema = z.enum([
]);
export const donationErrorTypeSchema = z.enum([
// Any 4xx error when adding payment method or confirming intent
'PaymentDeclined',
// Only used if we can't support 3DS validation for our first release
'CardNotSupported',
// Used if the user is redirected back from validation, but continuing forward fails
'Failed3dsValidation',
// Any other HTTPError during the process
'DonationProcessingError',
// Used if the user is redirected back from validation, but continuing forward fails
'Failed3dsValidation',
// Any other error
'GeneralError',
// Any 4xx error when adding payment method or confirming intent
'PaymentDeclined',
]);
export type DonationErrorType = z.infer<typeof donationErrorTypeSchema>;