Skip to content

Commit

Permalink
WIP: add Modal
Browse files Browse the repository at this point in the history
  • Loading branch information
up209d committed Oct 3, 2020
1 parent a3a225c commit 3f6c60b
Show file tree
Hide file tree
Showing 52 changed files with 955 additions and 500 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"cp": "yarn clean && mkdir -p unpacked2x && cp -r ./src/static/* unpacked2x",
"clean": "rm -rf unpacked2x",
"reset": "yarn clean && rm -rf ./.cache",
"local": "rm -rf ./node_modules/parcel-plugin-local && yarn install --check-files && yarn reset"
"local": "rm -rf ./node_modules/parcel-plugin-local && yarn install --check-files && yarn reset",
"prettier": "yarn prettier"
},
"alias": {
"app": "./src/app",
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/Button/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import { ButtonWrapper } from './styles';

export const Button = ({ color, children }) => (
<ButtonWrapper color={color}>
export const Button = ({ color, children, onClick, disabled }) => (
<ButtonWrapper color={color} onClick={onClick} disabled={disabled}>
{children}
</ButtonWrapper>
);
Expand Down
37 changes: 22 additions & 15 deletions src/app/components/Button/styles.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import styled from 'styled-components';
import styled, { css } from 'styled-components';
import { adjustHue } from 'polished';
import { ELASTIC_BEZIER } from '/app/styles';
import { ELASTIC_BEZIER } from 'app/styles';

export const ButtonWrapper = styled.button`
border: 0;
border-radius: ${props => props.theme.buttonBorderRadius}px;
background-color: ${props => props.theme[props.color || 'primary']};
color: ${props => props.theme.white};
padding: 10px 20px;
outline: none;
cursor: pointer;
transform: scale(1);
transition: all 0.3s ${ELASTIC_BEZIER};
&:hover {
transform: scale(1.05) translateX(-5px);
background-color: ${props => adjustHue(props.theme.factor * 10, props.theme[props.color || 'primary'])};
}
border: 0;
border-radius: ${props => props.theme.buttonBorderRadius}px;
background-color: ${props => props.theme[props.color || 'primary']};
color: ${props => props.theme.white};
padding: 10px 20px;
outline: none;
cursor: pointer;
transform: scale(1);
transition: all 0.3s ${ELASTIC_BEZIER};
&:hover {
transform: scale(1.05);
background-color: ${props => adjustHue(-50, props.theme[props.color || 'primary'])};
}
${props =>
props.disabled
? css`
background-color: ${props => props.theme.grayScale.gray1};
pointer-events: none;
`
: ``};
`;
58 changes: 58 additions & 0 deletions src/app/components/DownloadList/Modal/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { useContext, useMemo, useState } from 'react';
import {
DownloadListModalWrapper,
DownloadListModalBackdrop,
DownloadInputContainer,
DownloadInputButtonGroup,
} from './styles';
import { StoreContext } from 'app/store';
import Button from '../../Button';
import * as downloadListActions from 'app/store/downloadList';

export const DownloadListModal = props => {
const { isOpen, onClose } = props;
const { state, dispatch } = useContext(StoreContext);
const { downloadList } = state;
const [textArea, setTextArea] = useState(
downloadList
.slice(1)
.map(i => i.url)
.join('\n')
);
const handleTextArea = useMemo(() => e => setTextArea(e.target.value), []);
const handleUrls = useMemo(
() => () => {
if (textArea) {
textArea
.split('\n')
// .reduce((acc, i) => [...acc, ...i.split(/https?:\/\//)], [])
.filter(url => {
return url.startsWith('http');
})
.forEach(url => {
dispatch(downloadListActions.addDownloadItem({ url }));
});
}
onClose && onClose();
},
[textArea, dispatch]
);
return (
<DownloadListModalWrapper isOpen={isOpen}>
<DownloadListModalBackdrop onClick={onClose} />
<DownloadInputContainer isOpen={isOpen}>
<textarea onChange={handleTextArea} value={textArea} />
<DownloadInputButtonGroup>
<Button color={`primary`} onClick={handleUrls}>
Parse URLs
</Button>
<Button color={`danger`} onClick={onClose}>
Cancel
</Button>
</DownloadInputButtonGroup>
</DownloadInputContainer>
</DownloadListModalWrapper>
);
};

export default DownloadListModal;
72 changes: 72 additions & 0 deletions src/app/components/DownloadList/Modal/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import styled, { css } from 'styled-components';
import { rgba } from 'polished';
import { ButtonWrapper } from 'app/components/Button/styles';
import { ELASTIC_BEZIER } from 'app/styles';

export const Z_INDEX = 9;

export const DownloadListModalWrapper = styled.div`
opacity: 0;
pointer-events: none;
transition: opacity 0.15s ease-out;
${props =>
props.isOpen
? css`
opacity: 1;
pointer-events: all;
`
: ``};
`;

export const DownloadListModalBackdrop = styled.div`
position: absolute;
top: 0;
left: 0;
z-index: ${Z_INDEX + 1};
width: 100%;
height: 100%;
background-color: ${props => rgba(props.theme.black, 0.75)};
`;

export const DownloadInputContainer = styled.div`
position: absolute;
width: 80vw;
height: 400px;
top: calc(50% - 200px);
left: calc(50% - 40vw);
z-index: ${Z_INDEX + 2};
box-sizing: border-box;
padding: 20px;
border-radius: ${props => props.theme.buttonBorderRadius}px;
background-color: ${props => props.theme.white};
transform: translateY(-100px);
transition: transform 0.5s ${ELASTIC_BEZIER};
${props =>
props.isOpen
? css`
transform: translateY(0);
`
: ``};
& > textarea {
width: 100%;
height: 310px;
padding: 20px;
border: none;
background-color: ${props => rgba(props.theme.black, 0.05)};
outline: none;
resize: none;
}
`;

export const DownloadInputButtonGroup = styled.div`
padding: 10px 0 0 0;
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: center;
& > ${ButtonWrapper} {
margin-left: 10px;
}
`;
49 changes: 49 additions & 0 deletions src/app/components/DownloadList/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { useContext, useMemo, useState } from 'react';
import {
AddButtonWrapper,
DownloadListItemWrapper,
DownloadListContainer,
DownloadListWrapper,
DownloadListItemUrl,
} from './styles';
import { StoreContext } from 'app/store';
import Button from '../Button';
import { withTheme } from 'styled-components';
import DownloadListModal from './Modal';
import * as downloadListActions from 'app/store/downloadList';

export const DownloadList = () => {
const { state, dispatch } = useContext(StoreContext);
const {
downloadList,
ui: { tab },
} = state;
const [isModalOpen, setIsModalOpen] = useState(false);
const handleClose = useMemo(() => () => setIsModalOpen(false), []);
const handleOpen = useMemo(() => () => setIsModalOpen(true), []);
const handleRemove = item => () => dispatch(downloadListActions.removeDownloadItem(item));
return (
<DownloadListWrapper>
<DownloadListContainer>
{downloadList.map((item, index) => (
<DownloadListItemWrapper key={item.url} highlighted={item.url === tab.url} active={true} done={true}>
<DownloadListItemUrl>{item.url}</DownloadListItemUrl>
{index !== 0 && (
<Button color={`danger`} onClick={handleRemove(item)}>
Remove
</Button>
)}
</DownloadListItemWrapper>
))}
</DownloadListContainer>
<AddButtonWrapper>
<Button color={`primary`} onClick={handleOpen}>
+
</Button>
</AddButtonWrapper>
<DownloadListModal isOpen={isModalOpen} onClose={handleClose} />
</DownloadListWrapper>
);
};

export default withTheme(DownloadList);
81 changes: 81 additions & 0 deletions src/app/components/DownloadList/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import styled, { css } from 'styled-components';
import { rgba } from 'polished';
import { ButtonWrapper } from '../Button/styles';

export const DownloadListWrapper = styled.div``;

export const DownloadListContainer = styled.div`
color: ${props => props.theme.text};
margin: 20px;
padding: 10px 0;
border-radius: ${props => props.theme.buttonBorderRadius}px;
background-color: ${props => props.theme.grayScale.gray1};
`;

export const DownloadListItemWrapper = styled.div`
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
&:not(:last-child) {
border-bottom: 1px dotted ${props => props.theme.grayScale.gray5};
}
${props =>
props.highlighted
? css`
padding-left: 30px;
background-color: ${rgba(props.theme.primary, 0.2)};
font-weight: 800;
position: relative;
`
: ``};
${props =>
props.active
? css`
padding-left: 30px;
background-color: ${rgba(props.theme.secondary, 0.2)};
font-weight: 800;
position: relative;
`
: ``};
${ButtonWrapper} {
padding: 5px 10px;
font-size: 12px;
}
`;

export const DownloadListItemUrl = styled.div`
overflow-wrap: anywhere;
padding-right: 20px;
line-height: 20px;
font-size: 14px;
${props =>
props.active
? css`
&::before {
content: '';
display: block;
position: absolute;
color: white;
top: 15px;
left: 15px;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 5px solid ${props.theme.white};
}
`
: ``};
`;

export const AddButtonWrapper = styled.div`
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
margin: 10px 20px;
`;
32 changes: 23 additions & 9 deletions src/app/components/Header/index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
import React from 'react';
import React, { useMemo, useContext } from 'react';
import { withTheme } from 'styled-components';
import { HeaderWrapper } from './styles';
import ResetButton from '/app/components/ResetButton';
import Button from '/app/components/Button';
import ResetButton from 'app/components/ResetButton';
import Button from 'app/components/Button';
import { StoreContext } from 'app/store';
import { resolveDuplicatedResources } from 'app/utils/file';
import { INITIAL_STATE as UI_INITIAL_STATE } from 'app/store/ui';

export const Header = props => {
const { onSave } = props;
const { state } = useContext(StoreContext);
const {
ui: { status, isSaving },
} = state;
const handleOnSave = useMemo(
() => () => {
const { networkResource, staticResource } = state;
if ((networkResource && networkResource.length) || (staticResource && staticResource.length)) {
onSave && onSave(resolveDuplicatedResources([...(staticResource || []), ...(networkResource || [])]));
}
},
[onSave, state]
);
return (
<HeaderWrapper>
<div>
<span>Resources Saver</span>
<sup>Version: 2.0.0</sup>
<ResetButton
color={props.theme.white}
bgColor={props.theme.danger}
/>
<ResetButton color={props.theme.white} bgColor={props.theme.danger} />
</div>
<Button>
Save All Resources
<Button onClick={handleOnSave} disabled={status !== UI_INITIAL_STATE.status || isSaving}>
{isSaving ? `Saving all resource...` : `Save All Resources`}
</Button>
</HeaderWrapper>
);
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/InputList/styles.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from 'styled-components';
import { adjustHue } from 'polished';
import { ELASTIC_BEZIER } from '/app/styles';
import { ELASTIC_BEZIER } from 'app/styles';

export const InputListWrapper = styled.button`
border: 0;
Expand Down
7 changes: 7 additions & 0 deletions src/app/components/Report/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';

export const Report = props => {
return null;
}

export default Report;
Loading

0 comments on commit 3f6c60b

Please sign in to comment.