Skip to content

Commit

Permalink
feat(confirmation): add custom countdown content, change time format (#…
Browse files Browse the repository at this point in the history
…804)

add custom countdown content, change countdown time formatting (add hours)
  • Loading branch information
dmitrsavk committed Aug 23, 2021
1 parent 3b50480 commit b87ace1
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 24 deletions.
11 changes: 9 additions & 2 deletions packages/confirmation/src/component.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { forwardRef, useState, useRef, useEffect, useCallback } from 'react';
import React, { forwardRef, useState, useRef, useEffect, useCallback, ReactNode } from 'react';
import cn from 'classnames';
import { Button } from '@alfalab/core-components-button';
import { Link } from '@alfalab/core-components-link';
Expand Down Expand Up @@ -38,7 +38,7 @@ export type ConfirmationProps = {
/**
* Дополнительный контент
*/
additionalContent?: React.ReactNode;
additionalContent?: ReactNode;

/**
* Флаг критичности ошибки подписания.
Expand Down Expand Up @@ -128,6 +128,11 @@ export type ConfirmationProps = {
*/
noAttemptsLeftMessage?: string;

/**
* Кастомный контент для компонента Countdown
*/
countdownContent?: ReactNode;

/**
* Обработчик события завершения ввода кода подписания
*/
Expand Down Expand Up @@ -186,6 +191,7 @@ export const Confirmation = forwardRef<HTMLDivElement, ConfirmationProps>(
buttonRetryText = 'Запросить новый код',
alignContent = 'left',
noAttemptsLeftMessage,
countdownContent,
onInputFinished,
onSmsRetryClick,
onActionWithFatalError,
Expand Down Expand Up @@ -274,6 +280,7 @@ export const Confirmation = forwardRef<HTMLDivElement, ConfirmationProps>(
codeSendingText={codeSendingText}
alignContent={alignContent}
noAttemptsLeftMessage={noAttemptsLeftMessage}
countdownContent={countdownContent}
onInputFinished={onInputFinished}
onInputChange={onInputChange}
onSmsRetryClick={handleSmsRetryClick}
Expand Down
74 changes: 54 additions & 20 deletions packages/confirmation/src/components/countdown/component.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { MouseEvent, FC, useCallback, useState, useRef, useEffect } from 'react';
import React, { MouseEvent, FC, useCallback, useState, useRef, useEffect, ReactNode } from 'react';
import cn from 'classnames';
import { phoneNumber } from '@alfalab/utils';
import { usePrevious } from '@alfalab/hooks';
Expand All @@ -11,22 +11,30 @@ import styles from './index.module.css';

/**
* TODO: Вынести это в utils
* Форматирование миллисекунд в mm:ss.
* Форматирование миллисекунд в hh:mm:ss.
*
* @param {Number} ms миллисекунды
* @returns {String} время в формате mm:ss, но если оно более 100 минут,
* то строка 'более, чем 99:99'
* @returns {String} время в формате mm:ss
*/
export function formatMsAsMinutes(ms: number) {
if (ms >= 6000000) {
return 'более, чем 99:99';
}
const totalSeconds = Math.ceil(ms / 1000);
const totalMinutes = Math.floor(totalSeconds / 60);
const totalHours = Math.floor(totalMinutes / 60);

const seconds = totalSeconds % 60;
const paddedMinutes = `00${totalMinutes}`.slice(-2);
const paddedSeconds = `00${seconds}`.slice(-2);

if (totalHours > 0) {
const minutes = totalMinutes % 60;

const paddedMinutes = `00${minutes}`.slice(-2);
const paddedHours = `00${totalHours}`.slice(-2);

return `${paddedHours}:${paddedMinutes}:${paddedSeconds}`;
}

const paddedMinutes = `00${totalMinutes}`.slice(-2);

return `${paddedMinutes}:${paddedSeconds}`;
}

Expand All @@ -38,10 +46,23 @@ export type CountdownProps = {
buttonRetryText: string;
noAttemptsLeftMessage?: string;
hasError: boolean;
content?: ReactNode;
onCountdownFinished?: () => void;
onRepeatSms: (event: MouseEvent) => void;
};

type ContainerProps = Pick<CountdownProps, 'alignContent' | 'hasError'>;

const Container: FC<ContainerProps> = ({ alignContent, hasError, children }) => (
<div
className={cn(styles.component, styles[alignContent], {
[styles.hasError]: hasError,
})}
>
{children}
</div>
);

export const Countdown: FC<CountdownProps> = ({
duration = 5000,
phone = '',
Expand All @@ -50,6 +71,7 @@ export const Countdown: FC<CountdownProps> = ({
alignContent,
noAttemptsLeftMessage,
hasError,
content,
onRepeatSms,
onCountdownFinished,
}) => {
Expand Down Expand Up @@ -123,10 +145,29 @@ export const Countdown: FC<CountdownProps> = ({

const formattedPhone = phoneNumber.format(phone);

return (
<div
className={cn(styles.component, styles[alignContent], { [styles.hasError]: hasError })}
const retryButton = (
<Button
size='xs'
view='secondary'
onClick={handleRepeatSmsButtonClick}
className={styles.getCodeButton}
>
{buttonRetryText}
</Button>
);

if (content) {
return (
<Container alignContent={alignContent} hasError={hasError}>
<div className={styles.customContent}>{content}</div>

{retryButton}
</Container>
);
}

return (
<Container alignContent={alignContent} hasError={hasError}>
{phone && !hasError && (
<div>
Код отправлен на
Expand All @@ -139,14 +180,7 @@ export const Countdown: FC<CountdownProps> = ({
{noAttemptsLeftMessage ? (
<div className={styles.noAttemptsLeftMessage}>{noAttemptsLeftMessage}</div>
) : repeatSmsButtonShow ? (
<Button
size='xs'
view='secondary'
onClick={handleRepeatSmsButtonClick}
className={styles.getCodeButton}
>
{buttonRetryText}
</Button>
retryButton
) : (
<div>
<div className={styles.info}>Запросить повторно можно через</div>
Expand All @@ -159,6 +193,6 @@ export const Countdown: FC<CountdownProps> = ({
</div>
</div>
)}
</div>
</Container>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
& .info {
margin-top: 0;
}

& .customContent {
margin-bottom: var(--gap-2xl);
}
}

.info {
Expand Down
1 change: 1 addition & 0 deletions packages/confirmation/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './countdown';
export * from './sign-confirmation';
export * from './countdown-loader';
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC, KeyboardEvent, MutableRefObject, useCallback } from 'react';
import React, { FC, KeyboardEvent, MutableRefObject, ReactNode, useCallback } from 'react';
import cn from 'classnames';

import { Link } from '@alfalab/core-components-link';
Expand Down Expand Up @@ -30,6 +30,7 @@ export type SignConfirmationProps = {
alignContent: ContentAlign;
noAttemptsLeftMessage?: string;
buttonRetryText: string;
countdownContent?: ReactNode;
onInputFinished: ({ code }: { code: string }) => void;
onInputChange: ({ code }: { code: string }) => void;
onSmsRetryClick: (event: React.MouseEvent) => void;
Expand Down Expand Up @@ -57,6 +58,7 @@ export const SignConfirmation: FC<SignConfirmationProps> = ({
alignContent,
noAttemptsLeftMessage,
buttonRetryText,
countdownContent,
onInputFinished,
onInputChange,
onSmsRetryClick,
Expand Down Expand Up @@ -138,6 +140,7 @@ export const SignConfirmation: FC<SignConfirmationProps> = ({
noAttemptsLeftMessage={noAttemptsLeftMessage}
hasError={Boolean(displayedError)}
buttonRetryText={buttonRetryText}
content={countdownContent}
onRepeatSms={onSmsRetryClick}
onCountdownFinished={onCountdownFinished}
/>
Expand Down
3 changes: 2 additions & 1 deletion packages/confirmation/src/docs/Component.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import vars from '!!raw-loader!../vars.css';

<Story name='Confirmation'>
{React.createElement(() => {
const [open, setOpen] = React.useState(false);
const [variant, setVariant] = React.useState({ key: 'success', content: 'Успешный сценарий'});
const [value, setValue] = React.useState('');
const [codeChecking, setCodeChecking] = React.useState(false);
Expand Down Expand Up @@ -78,6 +77,8 @@ import vars from '!!raw-loader!../vars.css';
{ key: 'attempts-left', content: 'Сценарий, когда кончились попытки запроса смс'}
]}
onChange={({ selected }) => {
setError('');
setCode('');
setVariant(selected)
}}
selected={variant.key}
Expand Down
1 change: 1 addition & 0 deletions packages/confirmation/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './component';
export * from './components';

0 comments on commit b87ace1

Please sign in to comment.