Card component with card img wrapper UI

Signed-off-by: Virginie Ky <virginie.ky@gmail.com>
This commit is contained in:
Virginie Ky 2020-03-02 00:21:43 +01:00
parent a6f73e0647
commit cd103ba332
14 changed files with 281 additions and 27 deletions

View File

@ -1,6 +1,10 @@
import styled from 'styled-components';
const Description = styled.p`
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 11px;
color: #b3b5b9;
`;

View File

@ -1,7 +1,15 @@
import styled from 'styled-components';
const Title = styled.p`
width: 100%;
margin-bottom: 3px;
margin-top: 7px;
font-size: 1.3rem;
line-height: normal;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #333740;
`;

View File

@ -2,7 +2,11 @@ import styled from 'styled-components';
const Wrapper = styled.div`
width: 100%;
margin-bottom: 30px;
margin-bottom: 23px;
overflow: hidden;
&:hover {
cursor: pointer;
}
`;
export default Wrapper;

View File

@ -1,23 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Checkbox } from '@buffetjs/core';
import CardImgWrapper from '../CardImgWrapper';
import CardPreview from '../CardPreview';
import Wrapper from './Wrapper';
import Title from './Title';
import Description from './Description';
const Card = ({ abort, error, file, isSmall, isUploading }) => {
const newFile = new File([''], 'img.png');
console.log(newFile);
const Card = ({ abort, error, file, isSmall, isUploading, isSelected }) => {
// TODO - adapt with the real data
const { type, size, name } = file;
return (
<Wrapper>
<div>
<CardImgWrapper isSmall={isSmall}>
<img />
<CardImgWrapper isSmall={isSmall} isSelected={isSelected}>
<CardPreview {...file} />
<div className="card-control-wrapper">
<Checkbox name={`select-${name}`} />
</div>
</CardImgWrapper>
<Title>Ma photo</Title>
<Description>Ma photo</Description>
<Title>{name}</Title>
<Description>{`${type} - ${size}`}</Description>
</div>
</Wrapper>
);
@ -27,6 +32,7 @@ Card.defaultProps = {
abort: () => {},
error: '',
file: null,
isSelected: false,
isSmall: false,
isUploading: false,
};
@ -35,6 +41,7 @@ Card.propTypes = {
abort: PropTypes.func,
error: PropTypes.string,
file: PropTypes.object,
isSelected: PropTypes.bool,
isSmall: PropTypes.bool,
isUploading: PropTypes.bool,
};

View File

@ -8,7 +8,7 @@ const CardImgWrapper = styled.div`
padding-top: ${({ isSmall }) =>
isSmall ? 'calc(156 / 245 * 100%)' : 'calc(397 / 431 * 100%)'};
border-radius: 2px;
background: ${({ withOverlay }) => (withOverlay ? '#F6F6F6' : '#333740')};
background-color: #f6f6f6;
overflow: hidden;
${({ hasError }) => {
@ -22,6 +22,9 @@ const CardImgWrapper = styled.div`
return '';
}}
${({ isSelected }) =>
isSelected && 'border: 2px solid #007EFF;'}
.card-control-wrapper {
display: none;
}
@ -36,14 +39,14 @@ const CardImgWrapper = styled.div`
CardImgWrapper.defaultProps = {
hasError: false,
isSelected: false,
isSmall: false,
withOverlay: false,
};
CardImgWrapper.propTypes = {
hasError: PropTypes.bool,
isSelected: PropTypes.bool,
isSmall: PropTypes.bool,
withOverlay: PropTypes.bool,
};
export default CardImgWrapper;

View File

@ -0,0 +1,12 @@
import styled from 'styled-components';
const Image = styled.img`
display: block;
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
margin: auto;
`;
export default Image;

View File

@ -0,0 +1,22 @@
import styled from 'styled-components';
import PropTypes from 'prop-types';
const Wrapper = styled.div`
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
background-color: ${({ isImg }) => (isImg ? '#333740' : '#F2F3F4')};
`;
Wrapper.defaultProps = {
isImg: false,
};
Wrapper.propTypes = {
isImg: PropTypes.bool,
};
export default Wrapper;

View File

@ -0,0 +1,30 @@
import React from 'react';
import PropTypes from 'prop-types';
import FileIcon from '../FileIcon';
import Wrapper from './Wrapper';
import Image from './Image';
const CardPreview = ({ url, type }) => {
const renderFile = () => {
if (!url) {
return <FileIcon fileType={type} />;
}
return <Image src={url} />;
};
return <Wrapper isImg={!!url}>{renderFile()}</Wrapper>;
};
CardPreview.defaultProps = {
url: null,
type: null,
};
CardPreview.propTypes = {
url: PropTypes.string,
type: PropTypes.string,
};
export default CardPreview;

View File

@ -0,0 +1,24 @@
import styled from 'styled-components';
const Wrapper = styled.div`
font-size: 54px;
margin: auto;
color: ${({ type }) => {
switch (type) {
case 'file-pdf':
return '#E26D6D';
case 'file-image':
return '#8AA066';
case 'file-video':
return '#77C69E';
case 'file-code':
return '#515A6D';
case 'file-archive':
return '#715A31';
default:
return '#BDBFC2';
}
}};
`;
export default Wrapper;

View File

@ -0,0 +1,9 @@
{
"archive": ["rar", "zip"],
"code": ["js", "json", "rb", "erb", "txt", "css", "scss", "html", "jsx", "svg"],
"img": ["jpg", "jpeg", "png", "gif", "ico"],
"pdf": ["pdf"],
"powerpoint": ["ppt", "key", "xls"],
"video": ["mov", "avi", "mpg", "mp4", "m4v"],
"word": ["doc", "pages"]
}

View File

@ -0,0 +1,52 @@
/**
*
*
* FileIcon
*/
import React from 'react';
import PropTypes from 'prop-types';
import { trim } from 'lodash';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import ext from './extensions.json';
import Wrapper from './Wrapper';
function FileIcon({ fileType }) {
const iconType = (() => {
switch (true) {
case ext.archive.includes(trim(fileType, '.')):
return 'file-archive';
case ext.code.includes(trim(fileType, '.')):
return 'file-code';
case ext.img.includes(trim(fileType, '.')):
return 'file-image';
case ext.pdf.includes(trim(fileType, '.')):
return 'file-pdf';
case ext.powerpoint.includes(trim(fileType, '.')):
return 'file-powerpoint';
case ext.video.includes(trim(fileType, '.')):
return 'file-video';
case ext.word.includes(trim(fileType, '.')):
return 'file-word';
default:
return 'file';
}
})();
return (
<Wrapper type={iconType}>
<FontAwesomeIcon icon={['far', iconType]} />
</Wrapper>
);
}
FileIcon.defaultProps = {
fileType: 'zip',
};
FileIcon.propTypes = {
fileType: PropTypes.string,
};
export default FileIcon;

View File

@ -0,0 +1,7 @@
import styled from 'styled-components';
const Wrapper = styled.div`
margin-top: 7px;
`;
export default Wrapper;

View File

@ -1,29 +1,101 @@
import React from 'react';
import PropTypes from 'prop-types';
import createMatrix from '../../utils/createMatrix';
import Card from '../Card';
import Wrapper from './Wrapper';
const List = ({ data }) => {
const matrix = createMatrix(data);
return (
<div className="row">
<div className="col-xs-12 col-md-6 col-lg-4 col-xl-3">
<Card isSmall />
</div>
<div className="col-xs-12 col-md-6 col-lg-4 col-xl-3">
<Card isSmall />
</div>
<div className="col-xs-12 col-md-6 col-lg-4 col-xl-3">
<Card isSmall />
</div>
<div className="col-xs-12 col-md-6 col-lg-4 col-xl-3">
<Card isSmall />
</div>
</div>
<Wrapper>
{matrix.map(({ key, rowContent }) => {
return (
<div className="row" key={key}>
{rowContent.map(item => (
<div
className="col-xs-12 col-md-6 col-xl-3"
key={JSON.stringify(item)}
>
<Card isSmall {...item} />
</div>
))}
</div>
);
})}
</Wrapper>
);
};
List.defaultProps = {
data: [],
data: [
{
file: {
name: 'Chat paysage',
size: 17329,
type: 'image/png',
url:
'https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350',
},
},
{
file: {
name: 'Chat portrait',
size: 17329,
type: 'image/png',
url:
'https://emiliedammedumoulin.com/wp-content/uploads/2018/07/contact-chat-accueil.jpg',
},
},
{
file: {
name: 'Gif',
size: 17329,
type: 'image/png',
url:
'https://user-images.githubusercontent.com/879561/51321923-54024f00-1a64-11e9-8c37-3308350a59c4.gif',
},
},
{
file: {
name: 'Paysage',
size: 17329,
type: 'image/png',
url:
'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcSyHCXO8D0QQrPDuGstvH9dEwhhB7Qv-3mDMWGpLExyY1CF84cL',
},
},
{
file: {
name:
'That kitten is so beautiful that I am not sure to have the place to describe it',
size: 17329,
type: 'image/png',
url:
'https://images.pexels.com/photos/1643457/pexels-photo-1643457.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
},
},
{
file: {
name: 'pdf file',
type: 'pdf',
},
},
{
file: {
name: 'Zip file',
type: 'zip',
},
},
{
file: {
name: 'Doc file',
type: 'docx',
},
},
],
};
List.propTypes = {

View File

@ -124,7 +124,7 @@ const HomePage = () => {
/>
<AddFilterCTA />
</ControlsWrapper>
<List data={data} />
<List />
<ListEmpty onClick={handleClickToggleModal} />
<ModalStepper isOpen={isOpen} onToggle={handleClickToggleModal} />
</Container>