More styles and components
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import Link from 'react-router/lib/Link';
|
||||
|
||||
import DocumentPreview from 'components/DocumentPreview';
|
||||
import DocumentLink from './components/DocumentLink';
|
||||
|
||||
import styles from './AtlasPreview.scss';
|
||||
import classNames from 'classnames/bind';
|
||||
@@ -21,7 +21,7 @@ class AtlasPreview extends React.Component {
|
||||
{ data.recentDocuments.length > 0 ?
|
||||
data.recentDocuments.map(document => {
|
||||
return (
|
||||
<DocumentPreview document={ document } />)
|
||||
<DocumentLink document={ document } key={ document.id } />)
|
||||
})
|
||||
: (
|
||||
<div className={ styles.description }>No documents. Why not <Link to={ `/atlas/${data.id}/new` }>create one</Link>?</div>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
|
||||
import moment from 'moment';
|
||||
import Link from 'react-router/lib/Link';
|
||||
|
||||
import styles from './DocumentLink.scss';
|
||||
|
||||
const DocumentLink = (props) => {
|
||||
return (
|
||||
<Link to={ `/documents/${props.document.id}` } className={ styles.link }>
|
||||
<h3 className={ styles.title }>{ props.document.title }</h3>
|
||||
<span className={ styles.timestamp }>{ moment(props.document.updatedAt).fromNow() }</span>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default DocumentLink;
|
||||
@@ -0,0 +1,23 @@
|
||||
@import '../../../../utils/constants.scss';
|
||||
|
||||
.link {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: space-between;
|
||||
|
||||
margin-bottom: 20px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: normal;
|
||||
font-size: 15px;
|
||||
color: $textColor;
|
||||
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
font-size: 13px;
|
||||
color: #ccc;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
import DocumentLink from './DocumentLink';
|
||||
export default DocumentLink;
|
||||
@@ -1,5 +1,4 @@
|
||||
.content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
margin: 40px 20px;
|
||||
}
|
||||
11
src/components/Divider/Divider.js
Normal file
11
src/components/Divider/Divider.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
|
||||
import styles from './Divider.scss';
|
||||
|
||||
const Divider = (props) => {
|
||||
return(
|
||||
<div className={ styles.divider }><span></span></div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Divider;
|
||||
13
src/components/Divider/Divider.scss
Normal file
13
src/components/Divider/Divider.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
.divider {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
|
||||
span {
|
||||
display: flex;
|
||||
width: 50%;
|
||||
margin: 20px 0;
|
||||
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
}
|
||||
2
src/components/Divider/index.js
Normal file
2
src/components/Divider/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import Divider from './Divider';
|
||||
export default Divider;
|
||||
@@ -1,24 +1,29 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import marked from 'marked';
|
||||
|
||||
import { Avatar } from 'rebass';
|
||||
import Flex from 'components/Flex';
|
||||
import { Link } from 'react-router';
|
||||
import PublishingInfo from 'components/PublishingInfo';
|
||||
|
||||
import styles from './Document.scss';
|
||||
|
||||
const Document = (props) => {
|
||||
return (
|
||||
<div className={ styles.container }>
|
||||
<Flex align="center" className={ styles.user }>
|
||||
<Avatar src={ props.document.user.avatarUrl } size={ 24 } />
|
||||
<span className={ styles.userName }>
|
||||
{ props.document.user.name } published { moment(document.createdAt).fromNow() }
|
||||
</span>
|
||||
</Flex>
|
||||
class Document extends React.Component {
|
||||
static propTypes = {
|
||||
document: React.PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
<div dangerouslySetInnerHTML={{ __html: props.document.html }} />
|
||||
</div>
|
||||
);
|
||||
render() {
|
||||
return (
|
||||
<div className={ styles.container }>
|
||||
<PublishingInfo
|
||||
avatarUrl={ this.props.document.user.avatarUrl }
|
||||
name={ this.props.document.user.name }
|
||||
timestamp={ this.props.document.createdAt }
|
||||
/>
|
||||
<div dangerouslySetInnerHTML={{ __html: this.props.document.html }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default Document;
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
.container {
|
||||
padding: 20px 0;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.user {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.userName {
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
29
src/components/DocumentList/DocumentList.js
Normal file
29
src/components/DocumentList/DocumentList.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
|
||||
import DocumentPreview from 'components/DocumentPreview';
|
||||
import Divider from 'components/Divider';
|
||||
|
||||
import styles from './DocumentList.scss';
|
||||
|
||||
class DocumentList extends React.Component {
|
||||
static propTypes = {
|
||||
documents: React.PropTypes.arrayOf(React.PropTypes.object),
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{ this.props.documents.map((document) => {
|
||||
return (
|
||||
<div>
|
||||
<DocumentPreview document={ document } />
|
||||
<Divider />
|
||||
</div>
|
||||
);
|
||||
}) }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default DocumentList;
|
||||
0
src/components/DocumentList/DocumentList.scss
Normal file
0
src/components/DocumentList/DocumentList.scss
Normal file
2
src/components/DocumentList/index.js
Normal file
2
src/components/DocumentList/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import DocumentList from './DocumentList';
|
||||
export default DocumentList;
|
||||
@@ -1,26 +1,46 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import Link from 'react-router/lib/Link';
|
||||
import marked from 'marked';
|
||||
|
||||
import styles from './documentPreview.scss';
|
||||
import classNames from 'classnames/bind';
|
||||
const cx = classNames.bind(styles);
|
||||
import { Link } from 'react-router';
|
||||
|
||||
class documentPreview extends React.Component {
|
||||
import PublishingInfo from 'components/PublishingInfo';
|
||||
|
||||
import styles from './DocumentPreview.scss';
|
||||
|
||||
class Document extends React.Component {
|
||||
static propTypes = {
|
||||
document: React.PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
const document = this.props.document;
|
||||
|
||||
return (
|
||||
<Link to={ `/documents/${document.id}` } className={ styles.documentPreview }>
|
||||
<h3>{ document.title }</h3>
|
||||
<span>{ moment(document.updatedAt).fromNow() }</span>
|
||||
</Link>
|
||||
<div className={ styles.container }>
|
||||
<PublishingInfo
|
||||
avatarUrl={ this.props.document.user.avatarUrl }
|
||||
name={ this.props.document.user.name }
|
||||
timestamp={ document.createdAt }
|
||||
/>
|
||||
|
||||
<Link
|
||||
to={ `/documents/${this.props.document.id}` }
|
||||
className={ styles.title }
|
||||
>
|
||||
<h2>{ this.props.document.title }</h2>
|
||||
</Link>
|
||||
|
||||
<div dangerouslySetInnerHTML={{ __html: this.props.document.preview }} />
|
||||
|
||||
<div>
|
||||
<Link
|
||||
to={ `/documents/${this.props.document.id}` }
|
||||
className={ styles.continueLink }
|
||||
>
|
||||
Continue reading...
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default documentPreview;
|
||||
export default Document;
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
@import '../../utils/constants.scss';
|
||||
|
||||
.documentPreview {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: space-between;
|
||||
|
||||
margin-bottom: 20px;
|
||||
text-decoration: none;
|
||||
.container {
|
||||
width: 100%;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: normal;
|
||||
font-size: 15px;
|
||||
.title {
|
||||
color: $textColor;
|
||||
text-decoration: none;
|
||||
|
||||
margin: 0;
|
||||
h2 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 13px;
|
||||
color: #ccc;
|
||||
.continueLink {
|
||||
text-decoration: none;
|
||||
}
|
||||
26
src/components/PublishingInfo/PublishingInfo.js
Normal file
26
src/components/PublishingInfo/PublishingInfo.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { Avatar } from 'rebass';
|
||||
import Flex from 'components/Flex';
|
||||
|
||||
import styles from './PublishingInfo.scss';
|
||||
|
||||
const PublishingInfo = (props) => {
|
||||
return (
|
||||
<Flex align="center" className={ styles.user }>
|
||||
<Avatar src={ props.avatarUrl } size={ 24 } />
|
||||
<span className={ styles.userName }>
|
||||
{ props.name } published { moment(props.timestamp).fromNow() }
|
||||
</span>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
PublishingInfo.propTypes = {
|
||||
avatarUrl: React.PropTypes.string.isRequired,
|
||||
name: React.PropTypes.string.isRequired,
|
||||
timestamp: React.PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default PublishingInfo;
|
||||
9
src/components/PublishingInfo/PublishingInfo.scss
Normal file
9
src/components/PublishingInfo/PublishingInfo.scss
Normal file
@@ -0,0 +1,9 @@
|
||||
.user {
|
||||
margin-bottom: 30px;
|
||||
color: #ccc;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.userName {
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
2
src/components/PublishingInfo/index.js
Normal file
2
src/components/PublishingInfo/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import PublishingInfo from './PublishingInfo';
|
||||
export default PublishingInfo;
|
||||
Reference in New Issue
Block a user