Confirmation popup components

Created two new button styles:
- delete
- cancel

Created 3 popup modal styles:
- single file, multi file and collection delete
- delete with input
- confirmation

Added a new validation rule for the input value to equal a string. Used to disabled and enable the delete button.
This commit is contained in:
jasonleyser 2021-05-05 10:51:19 -06:00
parent 7501aad19e
commit 136c32c5cf
3 changed files with 313 additions and 0 deletions

View File

@ -193,3 +193,9 @@ export const isUnityFile = async (file) => {
return false; return false;
} }
}; };
export const isUsernameMatch = (data) => {
if(data.input == data.username) {
return true;
}
}

View File

@ -0,0 +1,167 @@
import * as React from "react";
import * as Constants from "~/common/constants";
import * as Validations from "~/common/validations";
import { css } from "@emotion/react";
import { useState } from "react";
import { ButtonPrimaryFull, ButtonDeleteFull, ButtonDeleteDisabledFull, ButtonCancelFull } from "~/components/system/components/Buttons.js";
import { Input } from "~/components/system/components/Input.js";
const STYLES_TRANSPARENT_BG = css `
background-color: rgba(0,0,0,0.3);
width: 100%;
height: 100vh;
position: fixed;
left: 0;
top: 0;
z-index: 999999;
`;
const STYLES_MAIN_MODAL = css `
width: 380px;
height: auto;
background-color: #fff;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 8px;
padding: 24px;
text-align: left;
`;
const STYLES_HEADER = css `
color: #000;
font-size: 16px;
font-weight: bold;
font-family: 'inter-medium', -apple-system, BlinkMacSystemFont, arial, sans-serif;
`;
const STYLES_SUB_HEADER = css `
color: #8E8E93;
font-size: 14px;
margin-top: 16px;
font-family: 'inter-regular', -apple-system, BlinkMacSystemFont, arial, sans-serif;
`;
const STYLES_INPUT_HEADER = css `
color: #000;
font-size: 12px;
font-weight: bold;
margin-top: 24px;
margin-bottom: 8px;
`;
export const DeleteModal = (props) => {
let header = '';
let subHeader = '';
if(props.data.type == 'multi') {
header = 'Are you sure you want to delete the selected ' + props.data.selected + ' files?';
subHeader = 'These files will be deleted from all connected collections and your file library. You cant undo this action.';
}
if(props.data.type == 'single') {
header = 'Are you sure you want to delete the file "' + props.data.filename + '"?';
subHeader = 'This file will be deleted from all connected collections and your file library. You cant undo this action.';
}
if(props.data.type == 'collection') {
header = 'Are you sure you want to delete the collection “' + props.data.collection + '”?';
subHeader = 'This collection will be deleted but all your files will remain in your file library. You cant undo this action.';
}
const _handleDelete = () => {
props.response(true);
}
const _handleCancel = () => {
props.response(false);
}
return (
<div css={STYLES_TRANSPARENT_BG}>
<div css={STYLES_MAIN_MODAL}>
<div>
<div css={STYLES_HEADER}>{header}</div>
<div css={STYLES_SUB_HEADER}>{subHeader}</div>
<ButtonCancelFull onClick={_handleCancel} style={{ margin: '24px 0px 8px' }}>Cancel</ButtonCancelFull>
<ButtonDeleteFull onClick={_handleDelete}>Delete</ButtonDeleteFull>
</div>
</div>
</div>
);
};
export const DeleteWithInputModal = (props) => {
const [isUsernameMatch, setIsUsernameMatch] = useState(false);
const header = 'Are you sure you want to delete your account @' + props.data.username + '?';
const subHeader = 'You will lose all your files and collections. You cant undo this action.';
const inputHeader = 'Please type your username to confirm';
const inputPlaceholder = 'username';
const _handleDelete = () => {
props.response(true);
}
const _handleCancel = () => {
props.response(false);
}
const _handleOnChange = (e) => {
if(Validations.isUsernameMatch({ input: e.target.value, username: props.data.username })) {
setIsUsernameMatch(true)
}else{
setIsUsernameMatch(false)
}
}
let deleteButton;
if(isUsernameMatch) {
deleteButton = <ButtonDeleteFull onClick={_handleDelete}>Delete</ButtonDeleteFull>;
} else {
deleteButton = <ButtonDeleteDisabledFull>Delete</ButtonDeleteDisabledFull>;
}
return (
<div css={STYLES_TRANSPARENT_BG}>
<div css={STYLES_MAIN_MODAL}>
<div>
<div css={STYLES_HEADER}>{header}</div>
<div css={STYLES_SUB_HEADER}>{subHeader}</div>
<div css={STYLES_INPUT_HEADER}>{inputHeader}</div>
<Input placeholder={inputPlaceholder} onChange={_handleOnChange} />
<ButtonCancelFull onClick={_handleCancel} style={{ margin: '16px 0px 8px' }}>Cancel</ButtonCancelFull>
{deleteButton}
</div>
</div>
</div>
);
};
export const ConfirmModal = (props) => {
const header = 'Making this file private will remove it from the following public slates: ' + props.data.username + '. Do you wish to continue?';
const subHeader = 'Making the file private means its not visible to others unless they have the link.';
const _handleConfirm = () => {
props.response(true);
}
const _handleCancel = () => {
props.response(false);
}
return (
<div css={STYLES_TRANSPARENT_BG}>
<div css={STYLES_MAIN_MODAL}>
<div>
<div css={STYLES_HEADER}>{header}</div>
<div css={STYLES_SUB_HEADER}>{subHeader}</div>
<ButtonCancelFull onClick={_handleCancel} style={{ margin: '16px 0px 8px' }}>Cancel</ButtonCancelFull>
<ButtonPrimaryFull onClick={_handleConfirm}>Confirm</ButtonPrimaryFull>
</div>
</div>
</div>
);
};

View File

@ -306,3 +306,143 @@ export const ButtonWarning = (props) => {
/> />
); );
}; };
const STYLES_BUTTON_DELETE = css`
${STYLES_BUTTON}
cursor: pointer;
color: ${Constants.system.white};
background-color: ${Constants.system.red};
box-shadow: 0 0 0 1px ${Constants.system.bgGray} inset;
:hover {
background-color: #b51111;
}
:focus {
outline: 0;
border: 0;
}
`;
const STYLES_BUTTON_DELETE_TRANSPARENT = css`
${STYLES_BUTTON}
cursor: pointer;
background-color: transparent;
color: ${Constants.system.darkGray};
`;
export const ButtonDelete = (props) => {
if (props.loading) {
return (
<button
css={props.transparent ? STYLES_BUTTON_DELETE_TRANSPARENT : STYLES_BUTTON_DELETE}
style={{ width: props.full ? "100%" : "auto", ...props.style }}
>
<LoaderSpinner style={{ height: 16, width: 16 }} />
</button>
);
}
if (props.type === "label") {
return (
<label
css={props.transparent ? STYLES_BUTTON_DELETE_TRANSPARENT : STYLES_BUTTON_DELETE}
style={{ width: props.full ? "100%" : "auto", ...props.style }}
onClick={props.onClick}
children={props.children}
type={props.label}
htmlFor={props.htmlFor}
/>
);
}
return (
<button
css={props.transparent ? STYLES_BUTTON_DELETE_TRANSPARENT : STYLES_BUTTON_DELETE}
onClick={props.onClick}
children={props.children}
style={{ width: props.full ? "100%" : "auto", ...props.style }}
/>
);
};
export const ButtonDeleteFull = (props) => {
return <ButtonDelete full {...props} />;
};
const STYLES_BUTTON_DELETE_DISABLED = css`
${STYLES_BUTTON}
cursor: not-allowed;
background-color: ${Constants.system.bgRed};
color: ${Constants.system.white};
box-shadow: 0 0 0 1px ${Constants.system.bgGray} inset;
:focus {
outline: 0;
border: 0;
}
`;
const STYLES_BUTTON_DELETE_DISABLED_TRANSPARENT = css`
${STYLES_BUTTON}
cursor: not-allowed;
background-color: transparent;
color: ${Constants.system.gray};
`;
export const ButtonDeleteDisabled = (props) => {
return (
<button
css={props.transparent ? STYLES_BUTTON_DELETE_DISABLED_TRANSPARENT : STYLES_BUTTON_DELETE_DISABLED}
onClick={props.onClick}
children={props.children}
type={props.label}
htmlFor={props.htmlFor}
style={{ width: props.full ? "100%" : "auto", ...props.style }}
/>
);
};
export const ButtonDeleteDisabledFull = (props) => {
return <ButtonDeleteDisabled full {...props} />;
};
const STYLES_BUTTON_CANCEL = css`
${STYLES_BUTTON}
cursor: pointer;
color: ${Constants.system.black};
background-color: ${Constants.system.gray20};
box-shadow: 0 0 0 1px ${Constants.system.bgGray} inset;
:hover {
background-color: ${Constants.system.gray30};
}
:focus {
outline: 0;
border: 0;
}
`;
const STYLES_BUTTON_CANCEL_TRANSPARENT = css`
${STYLES_BUTTON}
cursor: pointer;
background-color: transparent;
color: ${Constants.system.darkGray};
`;
export const ButtonCancel = (props) => {
return (
<button
css={props.transparent ? STYLES_BUTTON_CANCEL_TRANSPARENT : STYLES_BUTTON_CANCEL}
onClick={props.onClick}
children={props.children}
style={{ width: props.full ? "100%" : "auto", ...props.style }}
/>
);
};
export const ButtonCancelFull = (props) => {
return <ButtonCancel full {...props} />;
};