Skip to content

Commit

Permalink
♻️ front: introduce confirm modal (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericlinagora committed May 13, 2024
1 parent 7bc6e36 commit ce1180d
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 67 deletions.
4 changes: 3 additions & 1 deletion tdrive/frontend/src/app/atoms/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
import React from 'react';
import _ from 'lodash';

export type ButtonTheme = 'primary' | 'secondary' | 'danger' | 'default' | 'outline' | 'dark' | 'white' | 'green';

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
theme?: 'primary' | 'secondary' | 'danger' | 'default' | 'outline' | 'dark' | 'white' | 'green';
theme?: ButtonTheme;
size?: 'md' | 'lg' | 'sm';
icon?: (props: any) => JSX.Element;
iconSize?: 'md' | 'lg';
Expand Down
60 changes: 60 additions & 0 deletions tdrive/frontend/src/app/atoms/modal/confirm.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useState } from 'react';
import { action } from '@storybook/addon-actions';

import { RecoilRoot } from 'recoil';
import { ComponentStory } from '@storybook/react';
import { CheckCircleIcon, ExclamationCircleIcon } from '@heroicons/react/outline';
import { Title } from '../text';

import { ConfirmModal, ConfirmModalProps } from './confirm';
const icons = {
check: CheckCircleIcon,
exclamation: ExclamationCircleIcon,
none: null,
}
export default {
title: '@atoms/modal/confirm',
component: ConfirmModal,
argTypes: {
theme: {
options: "success danger warning gray".split(' '),
},
buttonTheme: {
options: "primary secondary danger default outline dark white green",
},
open: { table: { disable: true } },
icon: {
options: [...Object.keys(icons)],
mapping: icons,
}
},
args: {
title: "Very brief description",
text: "Long description no one will probably really read",
buttonOkLabel: 'general.continue',
skipCancelOnClose: false,
}
};

const Template: ComponentStory<any> = (props: ConfirmModalProps) => {
const [open, setOpen] = useState(true);

return (
<RecoilRoot>
<button className='dark:text-white' onClick={() => setOpen(true)}>Open</button>
<ConfirmModal
{...props}
open={open}
onClose={(...a) => {
setOpen(false);
action("onClose")(...a);
}}
onOk={action("onOk")}
onCancel={action("onCancel")}
/>
</RecoilRoot>
);
}

export const Default = Template.bind({});
Default.args = {};
59 changes: 59 additions & 0 deletions tdrive/frontend/src/app/atoms/modal/confirm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';

import { Modal, ModalContent, ModalContentTheme } from '.';
import { Button, ButtonTheme } from 'app/atoms/button/button';

import Languages from 'features/global/services/languages-service';

export type ConfirmModalProps = {
open: boolean;
title: string;
text: string;
theme?: ModalContentTheme;
icon: React.ComponentType;
skipCancelOnClose?: boolean;
buttonOkTheme?: ButtonTheme;
buttonOkLabel: string;
buttonCancelLabel?: string;
onClose: () => void;
onCancel?: () => void;
onOk: () => void;
};
export const ConfirmModal = (props: ConfirmModalProps) => {
function dialogCloseHandler(confirm?: boolean) {
return () => {
if (confirm === true)
props.onOk();
else if (confirm === false || !props.skipCancelOnClose)
props.onCancel && props.onCancel();
props.onClose();
};
}
return <>
<Modal open={props.open} onClose={dialogCloseHandler()}>
<ModalContent
title={props.title}
text={props.text}
theme={props.theme}
icon={props.icon}
buttons={
<>
<Button
className="ml-2"
theme='default'
onClick={dialogCloseHandler(false)}
>
{Languages.t(props.buttonCancelLabel || "general.cancel")}
</Button>
<Button
theme={props.buttonOkTheme || "danger"}
onClick={dialogCloseHandler(true)}
>
{Languages.t(props.buttonOkLabel)}
</Button>
</>
}
/>
</Modal>
</>;
};
4 changes: 2 additions & 2 deletions tdrive/frontend/src/app/atoms/modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,15 @@ export const Modal = (props: {
</Transition.Root>
);
};

export type ModalContentTheme = 'success' | 'danger' | 'warning' | 'gray';
export const ModalContent = (props: {
title: ReactNode | string;
text?: string;
textCenter?: boolean;
buttons?: ReactNode;
children?: ReactNode;
icon?: any;
theme?: 'success' | 'danger' | 'warning' | 'gray';
theme?: ModalContentTheme;
}) => {
let color = 'blue';
if (props.theme === 'success') color = 'green';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Input } from 'app/atoms/input/input-text';
import { CheckboxSlider } from 'app/atoms/input/input-checkbox-slider';
import { Button } from 'app/atoms/button/button';
import { ShieldExclamationIcon, CalendarIcon, PencilAltIcon } from '@heroicons/react/outline';
import { Modal, ModalContent } from 'app/atoms/modal';
import { ConfirmModal } from 'app/atoms/modal/confirm';

import Styles from './styles';

Expand Down Expand Up @@ -153,37 +153,18 @@ export const ExpiryEditorRow = (props: {
/>
}
/>

<Modal open={isConfirmingExpiryRemoval} onClose={() => setIsConfirmingExpiryRemoval(false)}>
<ModalContent
title={Languages.t("components.public-link-security_expiration_removal_title")}
text={props.isLinkPasswordProtected
? Languages.t("components.public-link-security_expiration_removal_but_password")
: Languages.t("components.public-link-security_expiration_removal_no_password")
}
theme="danger"
icon={ShieldExclamationIcon}
buttons={
<>
<Button
className="ml-2"
theme='default'
onClick={() => setIsConfirmingExpiryRemoval(false)}
>
{Languages.t("general.cancel")}
</Button>
<Button
theme="danger"
onClick={() => {
setIsConfirmingExpiryRemoval(false)
saveValue(0);
}}
>
{Languages.t("components.public-link-security_expiration_removal_confirm")}
</Button>
</>
}
<ConfirmModal
open={isConfirmingExpiryRemoval}
onClose={() => setIsConfirmingExpiryRemoval(false)}
onOk={() => saveValue(0)}
title={Languages.t("components.public-link-security_expiration_removal_title")}
text={props.isLinkPasswordProtected
? Languages.t("components.public-link-security_expiration_removal_but_password")
: Languages.t("components.public-link-security_expiration_removal_no_password")
}
icon={ShieldExclamationIcon}
buttonOkLabel="components.public-link-security_expiration_removal_confirm"
buttonOkTheme='danger'
/>
</Modal>
</>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Input } from 'app/atoms/input/input-text';
import { CheckboxSlider } from 'app/atoms/input/input-checkbox-slider';
import { Button } from 'app/atoms/button/button';
import { ShieldCheckIcon, PencilAltIcon, ShieldExclamationIcon } from '@heroicons/react/outline';
import { Modal, ModalContent } from 'app/atoms/modal';
import { ConfirmModal } from 'app/atoms/modal/confirm';

import Styles from './styles';

Expand Down Expand Up @@ -136,33 +136,17 @@ export const PasswordEditorRow = (props: {
}
/>

<Modal open={isConfirmingPasswordRemoval} onClose={() => setIsConfirmingPasswordRemoval(false)}>
<ModalContent
title={Languages.t("components.public-link-security_password_removal_title")}
text={Languages.t("components.public-link-security_password_removal_body")}
theme="danger"
icon={ShieldExclamationIcon}
buttons={
<>
<Button
className="ml-2"
theme='default'
onClick={() => setIsConfirmingPasswordRemoval(false)}
>
{Languages.t("general.cancel")}
</Button>
<Button
theme="danger"
onClick={() => {
setIsConfirmingPasswordRemoval(false)
savePassword("");
}}
>
{Languages.t("components.public-link-security_password_removal_confirm")}
</Button>
</>
}
<ConfirmModal
open={isConfirmingPasswordRemoval}
title={Languages.t("components.public-link-security_password_removal_title")}
text={Languages.t("components.public-link-security_password_removal_body")}
theme="danger"
icon={ShieldExclamationIcon}
buttonOkTheme='danger'
buttonOkLabel='components.public-link-security_password_removal_confirm'

onClose={() => setIsConfirmingPasswordRemoval(false)}
onOk={() => savePassword("")}
/>
</Modal>
</>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ export const AccessModal = () => {
open={state.open}
onClose={() => setState({ ...state, open: false })}
>
{!!state.id &&
<AccessModalContent
id={state.id}
/>}
{!!state.id && <AccessModalContent id={state.id} />}
</Modal>
);
};
Expand Down

0 comments on commit ce1180d

Please sign in to comment.