From 622ba52cf013c264da053893cbc0090305217caf Mon Sep 17 00:00:00 2001 From: Caitlyn Chung Date: Thu, 3 May 2018 19:59:15 -0700 Subject: [PATCH] Week 2 Homework --- social-network/package.json | 19 +++ social-network/public/favicon.ico | Bin 0 -> 3870 bytes social-network/public/index.html | 40 ++++++ social-network/public/manifest.json | 15 +++ social-network/src/App.css | 31 +++++ social-network/src/App.js | 16 +++ social-network/src/App.test.js | 9 ++ social-network/src/CreativityPage/Article.css | 91 ++++++++++++++ .../src/CreativityPage/ArticleItem.js | 46 +++++++ .../src/CreativityPage/Creativity.test.js | 17 +++ .../src/CreativityPage/Description.css | 7 ++ .../src/CreativityPage/Description.js | 23 ++++ .../src/CreativityPage/Favorites.js | 17 +++ .../src/CreativityPage/ImageArticle.css | 5 + .../src/CreativityPage/ImageArticle.js | 23 ++++ .../src/CreativityPage/ImageAuthor.css | 5 + .../src/CreativityPage/ImageAuthor.js | 23 ++++ .../src/CreativityPage/MinutesToRead.js | 22 ++++ .../src/CreativityPage/NameAuthor.css | 5 + .../src/CreativityPage/NameAuthor.js | 23 ++++ social-network/src/CreativityPage/PostDate.js | 30 +++++ social-network/src/CreativityPage/Title.css | 7 ++ social-network/src/CreativityPage/Title.js | 23 ++++ social-network/src/CreativityPage/index.js | 41 ++++++ .../src/CreativityPage/missed-articles.json | 47 +++++++ .../src/CreativityPage/your-articles.json | 62 ++++++++++ social-network/src/index.css | 5 + social-network/src/index.js | 8 ++ social-network/src/logo.svg | 7 ++ social-network/src/registerServiceWorker.js | 117 ++++++++++++++++++ 30 files changed, 784 insertions(+) create mode 100644 social-network/package.json create mode 100644 social-network/public/favicon.ico create mode 100644 social-network/public/index.html create mode 100644 social-network/public/manifest.json create mode 100644 social-network/src/App.css create mode 100644 social-network/src/App.js create mode 100644 social-network/src/App.test.js create mode 100644 social-network/src/CreativityPage/Article.css create mode 100644 social-network/src/CreativityPage/ArticleItem.js create mode 100644 social-network/src/CreativityPage/Creativity.test.js create mode 100644 social-network/src/CreativityPage/Description.css create mode 100644 social-network/src/CreativityPage/Description.js create mode 100644 social-network/src/CreativityPage/Favorites.js create mode 100644 social-network/src/CreativityPage/ImageArticle.css create mode 100644 social-network/src/CreativityPage/ImageArticle.js create mode 100644 social-network/src/CreativityPage/ImageAuthor.css create mode 100644 social-network/src/CreativityPage/ImageAuthor.js create mode 100644 social-network/src/CreativityPage/MinutesToRead.js create mode 100644 social-network/src/CreativityPage/NameAuthor.css create mode 100644 social-network/src/CreativityPage/NameAuthor.js create mode 100644 social-network/src/CreativityPage/PostDate.js create mode 100644 social-network/src/CreativityPage/Title.css create mode 100644 social-network/src/CreativityPage/Title.js create mode 100644 social-network/src/CreativityPage/index.js create mode 100644 social-network/src/CreativityPage/missed-articles.json create mode 100644 social-network/src/CreativityPage/your-articles.json create mode 100644 social-network/src/index.css create mode 100644 social-network/src/index.js create mode 100644 social-network/src/logo.svg create mode 100644 social-network/src/registerServiceWorker.js diff --git a/social-network/package.json b/social-network/package.json new file mode 100644 index 0000000..35b3a9f --- /dev/null +++ b/social-network/package.json @@ -0,0 +1,19 @@ +{ + "name": "social-network", + "version": "0.1.0", + "private": true, + "dependencies": { + "react": "^16.3.2", + "react-dom": "^16.3.2", + "react-scripts": "1.1.4" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test --env=jsdom", + "eject": "react-scripts eject" + }, + "devDependencies": { + "react-test-renderer": "^16.3.2" + } +} diff --git a/social-network/public/favicon.ico b/social-network/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a11777cc471a4344702741ab1c8a588998b1311a GIT binary patch literal 3870 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 baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ literal 0 HcmV?d00001 diff --git a/social-network/public/index.html b/social-network/public/index.html new file mode 100644 index 0000000..ed0ebaf --- /dev/null +++ b/social-network/public/index.html @@ -0,0 +1,40 @@ + + + + + + + + + + + React App + + + +
+ + + diff --git a/social-network/public/manifest.json b/social-network/public/manifest.json new file mode 100644 index 0000000..ef19ec2 --- /dev/null +++ b/social-network/public/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + } + ], + "start_url": "./index.html", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/social-network/src/App.css b/social-network/src/App.css new file mode 100644 index 0000000..68392ad --- /dev/null +++ b/social-network/src/App.css @@ -0,0 +1,31 @@ +.App { + text-align: left; + display: block; + margin-left: 10px; + font-family: medium-content-sans-serif-font,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Open Sans","Helvetica Neue",sans-serif; +} + +.App-logo { + animation: App-logo-spin infinite 20s linear; + height: 80px; +} + +.App-header { + background-color: #222; + height: 150px; + padding: 20px; + color: white; +} + +.App-title { + font-size: 1.5em; +} + +.App-intro { + font-size: large; +} + +@keyframes App-logo-spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} diff --git a/social-network/src/App.js b/social-network/src/App.js new file mode 100644 index 0000000..925c60c --- /dev/null +++ b/social-network/src/App.js @@ -0,0 +1,16 @@ +import React, { Component } from 'react'; +import logo from './logo.svg'; +import './App.css'; +import CreativityPage from './CreativityPage'; + +class App extends Component { + render() { + return ( +
+ +
+ ); + } +} + +export default App; diff --git a/social-network/src/App.test.js b/social-network/src/App.test.js new file mode 100644 index 0000000..a754b20 --- /dev/null +++ b/social-network/src/App.test.js @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/social-network/src/CreativityPage/Article.css b/social-network/src/CreativityPage/Article.css new file mode 100644 index 0000000..8be65ee --- /dev/null +++ b/social-network/src/CreativityPage/Article.css @@ -0,0 +1,91 @@ + +.ForYouSection { + display: flex; + flex-wrap: wrap; + border-top: 1px solid lightgrey; +} +.MissedSection { + display: flex; + flex-wrap: wrap; + border-top: 1px solid lightgrey; +} + +.flex-container-box-two-per-row { + display: flex; + /*flex-wrap: nowrap;*/ + flex-direction: row; + border: 1px solid lightgrey; + margin: 10px; + width: 45%; +} +.flex-container-box-three-per-row { + display: flex; + flex-wrap: wrap; + /*flex-wrap: nowrap;*/ + flex-direction: row; + border: 1px solid lightgrey; + margin: 10px; + width: 30%; +} + +.flex-container-box-generic { + display: flex; + flex-wrap: wrap; + flex-direction: row; + margin: 10px; +} + +/* Within a box, this is all the stuff right of the image*/ +.flex-container-contents { + display: flex; + /*flex-wrap: wrap;*/ + flex-direction: column; + padding-left: 10px; + max-width: 300px; +} + +/* Within a container-contents, this is author image, name, date and readtime data*/ +.flex-container-metadata { + display: flex; + /*flex-wrap: wrap;*/ + flex-direction: row; + padding-bottom: 8px; + font-size: 14px; +} + +/* Within flex-container-metadata, this is everything to the right of author pic*/ +.flex-container-md-column { + display: flex; + flex-direction: column; + padding-left: 10px; + color: rgba(0,0,0,.54); +} + +.flex-container-md-row { + display: flex; + /*flex-wrap: wrap;*/ + flex-direction: row; + align-items: center; + padding-bottom: 10px; +} + +/* Within container-metadata, this is the name, date, readtime */ +.flex-container-meta-text { + display: flex; + /*flex-wrap: wrap;*/ + flex-direction: column; +} + +.flex-container-space-filler { + flex-grow: 1; /*grow to fill space to push what comes after to bottom of box*/ +} +.ArticleMinutesToRead { + position: relative; +} +.Circle { + border-radius: 50%; + width: 3px; + height: 3px; + background-color: lightgrey; + margin: 5px; +} \ No newline at end of file diff --git a/social-network/src/CreativityPage/ArticleItem.js b/social-network/src/CreativityPage/ArticleItem.js new file mode 100644 index 0000000..f7bb857 --- /dev/null +++ b/social-network/src/CreativityPage/ArticleItem.js @@ -0,0 +1,46 @@ +import React, { Component } from 'react'; +import Title from './Title'; +import Description from './Description'; +import ImageArticle from './ImageArticle'; +import Favorites from './Favorites'; +import ImageAuthor from './ImageAuthor'; +import PostDate from './PostDate'; +import NameAuthor from './NameAuthor'; +import MinutesToRead from './MinutesToRead'; +import './Article.css' + +class ArticleItem extends Component { + render() { + const articleMetaData = this.props.articleMetaData; + + return ( +
+ +
+ + <Description description={articleMetaData.description} /> + <div className="flex-container-space-filler"></div> + <div className="flex-container-metadata"> + <ImageAuthor image={articleMetaData.author.image} /> + <div className = "flex-container-md-column"> + <div className="flex-container-space-filler"></div> + <div className="flex-container-md-row"> + <NameAuthor authorName={articleMetaData.author.name} /> + <div className="flex-container-space-filler"></div> + <Favorites /> + </div> + <div className="flex-container-space-filler"></div> + <div className="flex-container-md-row"> + <PostDate postDate={articleMetaData.postedDate} /> + <div className="Circle" /> + <MinutesToRead minutesToRead={articleMetaData.minutesToRead} /> + </div> + </div> + </div> + </div> + </div> + ); + } +} + +export default ArticleItem; \ No newline at end of file diff --git a/social-network/src/CreativityPage/Creativity.test.js b/social-network/src/CreativityPage/Creativity.test.js new file mode 100644 index 0000000..c7b5188 --- /dev/null +++ b/social-network/src/CreativityPage/Creativity.test.js @@ -0,0 +1,17 @@ +import React from 'react'; +import CreativityPage from './index'; +import ArticleItem from './ArticleItem'; +import ReactTestRenderer from 'react-test-renderer'; + +describe('CreativityPage component', () => { + it('should render', () => { + const component = ReactTestRenderer.create(<CreativityPage />); + expect(component.toJSON()).toMatchSnapshot(); + }); +}); +describe('ArticleItem component', () => { + it('should render', () => { + const component = ReactTestRenderer.create(<ArticleItem />); + expect(component.toJSON()).toMatchSnapshot(); + }); +}); \ No newline at end of file diff --git a/social-network/src/CreativityPage/Description.css b/social-network/src/CreativityPage/Description.css new file mode 100644 index 0000000..ba7be22 --- /dev/null +++ b/social-network/src/CreativityPage/Description.css @@ -0,0 +1,7 @@ +.ArticleDescription { + color: rgba(0,0,0,.54); + fill: rgba(0,0,0,.54); + font-size: 14px; + position: relative; + padding-top: 10px; +} \ No newline at end of file diff --git a/social-network/src/CreativityPage/Description.js b/social-network/src/CreativityPage/Description.js new file mode 100644 index 0000000..f55cbe9 --- /dev/null +++ b/social-network/src/CreativityPage/Description.js @@ -0,0 +1,23 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import './Description.css' + +class Description extends Component { + + render() { + const articleDescription = this.props.description; + return ( + <div className="ArticleDescription">{articleDescription}</div> + ); + } +} + +Description.propTypes = { + description: PropTypes.string +}; + +Description.defaultProps = { + description: '' +}; + +export default Description; \ No newline at end of file diff --git a/social-network/src/CreativityPage/Favorites.js b/social-network/src/CreativityPage/Favorites.js new file mode 100644 index 0000000..ecbaafa --- /dev/null +++ b/social-network/src/CreativityPage/Favorites.js @@ -0,0 +1,17 @@ +import React, { Component } from 'react'; + +class Favorites extends Component { + render() { + return ( + <svg width="25" height="25" viewBox="0 0 25 25"> + <path d={ + ( + 'M 19 6 c 0 -1.1 -0.9 -2 -2 -2 H 8 c -1.1 0 -2 0.9 -2 2 v 14.66 h 0.012 c 0.01 0.103 0.045 0.204 0.12 0.285 a 0.5 0.5 0 0 0 0.706 0.03 L 12.5 16.85 l 5.662 4.126 a 0.508 0.508 0 0 0 0.708 -0.03 a 0.5 0.5 0 0 0 0.118 -0.285 H 19 V 6 Z m -6.838 9.97 L 7 19.636 V 6 c 0 -0.55 0.45 -1 1 -1 h 9 c 0.55 0 1 0.45 1 1 v 13.637 l -5.162 -3.668 a 0.49 0.49 0 0 0 -0.676 0 Z' + ) + } fillRule='evenodd'></path> + </svg> + ); + } +} + +export default Favorites; \ No newline at end of file diff --git a/social-network/src/CreativityPage/ImageArticle.css b/social-network/src/CreativityPage/ImageArticle.css new file mode 100644 index 0000000..0fb2a52 --- /dev/null +++ b/social-network/src/CreativityPage/ImageArticle.css @@ -0,0 +1,5 @@ +.ImageArticle { + display: flex; + width: 200px; + height: 200px; +} \ No newline at end of file diff --git a/social-network/src/CreativityPage/ImageArticle.js b/social-network/src/CreativityPage/ImageArticle.js new file mode 100644 index 0000000..160ffad --- /dev/null +++ b/social-network/src/CreativityPage/ImageArticle.js @@ -0,0 +1,23 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import './ImageArticle.css' + +class ImageArticle extends Component { + + render() { + const articleImage = this.props.image; + return ( + <img className={"ImageArticle"} src={articleImage} /> + ); + } +} + +ImageArticle.propTypes = { + image: PropTypes.string +}; + +ImageArticle.defaultProps = { + image: '' +}; + +export default ImageArticle; \ No newline at end of file diff --git a/social-network/src/CreativityPage/ImageAuthor.css b/social-network/src/CreativityPage/ImageAuthor.css new file mode 100644 index 0000000..3bd5375 --- /dev/null +++ b/social-network/src/CreativityPage/ImageAuthor.css @@ -0,0 +1,5 @@ +.ImageAuthor { + border-radius: 50%; + width: 50px; + height: 50px; +} \ No newline at end of file diff --git a/social-network/src/CreativityPage/ImageAuthor.js b/social-network/src/CreativityPage/ImageAuthor.js new file mode 100644 index 0000000..98521cb --- /dev/null +++ b/social-network/src/CreativityPage/ImageAuthor.js @@ -0,0 +1,23 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import './ImageAuthor.css' + +class ImageAuthor extends Component { + + render() { + const authorImage = this.props.image; + return ( + <img className={"ImageAuthor"} src={authorImage} /> + ); + } +} + +ImageAuthor.propTypes = { + image: PropTypes.string +}; + +ImageAuthor.defaultProps = { + image: '' +}; + +export default ImageAuthor; \ No newline at end of file diff --git a/social-network/src/CreativityPage/MinutesToRead.js b/social-network/src/CreativityPage/MinutesToRead.js new file mode 100644 index 0000000..90c635d --- /dev/null +++ b/social-network/src/CreativityPage/MinutesToRead.js @@ -0,0 +1,22 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +class MinutesToRead extends Component { + + render() { + const minutesToRead = this.props.minutesToRead; + return ( + <div>{minutesToRead} min read </div> + ); + } +} + +MinutesToRead.propTypes = { + minutesToRead: PropTypes.number +}; + +MinutesToRead.defaultProps = { + minutesToRead: 0 +}; + +export default MinutesToRead; \ No newline at end of file diff --git a/social-network/src/CreativityPage/NameAuthor.css b/social-network/src/CreativityPage/NameAuthor.css new file mode 100644 index 0000000..5c3b67b --- /dev/null +++ b/social-network/src/CreativityPage/NameAuthor.css @@ -0,0 +1,5 @@ +.NameAuthor { + font-size: 14px; + position: relative; + color: rgba(0,0,0,.84); +} \ No newline at end of file diff --git a/social-network/src/CreativityPage/NameAuthor.js b/social-network/src/CreativityPage/NameAuthor.js new file mode 100644 index 0000000..35727b7 --- /dev/null +++ b/social-network/src/CreativityPage/NameAuthor.js @@ -0,0 +1,23 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import './NameAuthor.css' + +class NameAuthor extends Component { + + render() { + const authorName = this.props.authorName; + return ( + <div className="NameAuthor">{authorName}</div> + ); + } +} + +NameAuthor.propTypes = { + authorName: PropTypes.string.isRequired +}; + +NameAuthor.defaultProps = { + authorName: 'Author Unknown' +}; + +export default NameAuthor; \ No newline at end of file diff --git a/social-network/src/CreativityPage/PostDate.js b/social-network/src/CreativityPage/PostDate.js new file mode 100644 index 0000000..5f2ebf6 --- /dev/null +++ b/social-network/src/CreativityPage/PostDate.js @@ -0,0 +1,30 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +class PostDate extends Component { + formatDateStrToMonthDay (dateStr) { + let date = new Date(dateStr); + const months = ([ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' + ]); + return `${months[date.getMonth()]} ${date.getDate()}` + } + + render() { + const postedDate = this.props.postedDate; + return ( + <div>{this.formatDateStrToMonthDay(postedDate)}</div> + ); + } +} + +PostDate.propTypes = { + postedDate: PropTypes.string.isRequired +}; + +PostDate.defaultProps = { + postedDate: '9999-12-31' +}; + +export default PostDate; \ No newline at end of file diff --git a/social-network/src/CreativityPage/Title.css b/social-network/src/CreativityPage/Title.css new file mode 100644 index 0000000..7c2e49b --- /dev/null +++ b/social-network/src/CreativityPage/Title.css @@ -0,0 +1,7 @@ +.ArticleTitle { + text-align: left; + line-height: 20px; + font-size: 16px; + position: relative; + padding-top: 10px; + } \ No newline at end of file diff --git a/social-network/src/CreativityPage/Title.js b/social-network/src/CreativityPage/Title.js new file mode 100644 index 0000000..57846df --- /dev/null +++ b/social-network/src/CreativityPage/Title.js @@ -0,0 +1,23 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import './Title.css' + +class Title extends Component { + + render() { + const articleTitle = this.props.title; + return ( + <div className="ArticleTitle">{articleTitle}</div> + ); + } +} + +Title.propTypes = { + title: PropTypes.string.isRequired +}; + +Title.defaultProps = { + title: 'Title Unknown' +}; + +export default Title; \ No newline at end of file diff --git a/social-network/src/CreativityPage/index.js b/social-network/src/CreativityPage/index.js new file mode 100644 index 0000000..8371e52 --- /dev/null +++ b/social-network/src/CreativityPage/index.js @@ -0,0 +1,41 @@ +import React, { Component } from 'react'; +import yourArticles from './your-articles.json'; +import missedArticles from './missed-articles.json'; +import ArticleItem from './ArticleItem'; +import './Article.css' + +class CreativityPage extends Component { + + render() { + /* don't forget idx*/ + const yourArticleSection = yourArticles.map((articleMetaData, idx) => { + return ( + <div className="flex-container-box-two-per-row" key={idx}> + <ArticleItem articleMetaData={articleMetaData}/> + </div> + ); + }) + const missedArticleSection = missedArticles.map((articleMetaData, idx) => { + return ( + <div className="flex-container-box-three-per-row" key={idx}> + <ArticleItem articleMetaData={articleMetaData}/> + </div> + ); + }) + + return ( + <div> + <h3>For you</h3> + <div className="ForYouSection"> + {yourArticleSection} + </div> + <h3>In case you missed it</h3> + <div className="MissedSection"> + {missedArticleSection} + </div> + </div> + ); + } +} + +export default CreativityPage; \ No newline at end of file diff --git a/social-network/src/CreativityPage/missed-articles.json b/social-network/src/CreativityPage/missed-articles.json new file mode 100644 index 0000000..d783e3e --- /dev/null +++ b/social-network/src/CreativityPage/missed-articles.json @@ -0,0 +1,47 @@ +[ + { + "title": "What Would Happen If You Did These Things Every Day...", + "description": "For thirty days...", + "image": "https://cdn-images-1.medium.com/max/800/1*NosScbnZp8m_clHHaPQ3mg.jpeg", + "link": "https://entrepreneurs.maqtoob.com/what-would-happen-if-you-did-these-things-every-day-7e39f62a6335", + "author": { + "name": "Alex Mathers", + "image": "https://cdn-images-1.medium.com/fit/c/80/80/1*wsP97tix16onOIkq4STxuw.jpeg", + "isMediumMember": true + }, + "postedDate": "2018-04-22T07:00:00.000Z", + "minutesToRead": 3, + "hasAudioAvailable": false, + "memberPreview": false + }, + { + "title": "10 Strategies for Creating Viral and Powerful Content", + "description": "", + "image": "https://cdn-images-1.medium.com/max/800/0*jxP3G649xndI9S_m.", + "link": "https://medium.com/@zdravko/10-strategies-for-creating-viral-and-powerful-content-b4ce7bbb4904", + "author": { + "name": "Zdravko Cvijetic", + "image": "https://cdn-images-1.medium.com/fit/c/80/80/1*0OAF2WviyXwa7MuRKtKUpA@2x.jpeg", + "isMediumMember": true + }, + "postedDate": "2018-04-22T07:00:00.000Z", + "minutesToRead": 6, + "hasAudioAvailable": false, + "memberPreview": false + }, + { + "title": "Useful Tools for Writers", + "description": "Jumpstart your process.", + "image": "https://cdn-images-1.medium.com/max/800/1*Msq_1dsr2maPq3ujjTVu3w.jpeg", + "link": "https://medium.com/@jaxonleerose/useful-tools-for-writers-46eb0736d660", + "author": { + "name": "JLRose", + "image": "https://cdn-images-1.medium.com/fit/c/80/80/1*-W7euf25bzL36c83YA5qeQ.jpeg", + "isMediumMember": true + }, + "postedDate": "2018-04-21T07:00:00.000Z", + "minutesToRead": 8, + "hasAudioAvailable": false, + "memberPreview": true + } +] \ No newline at end of file diff --git a/social-network/src/CreativityPage/your-articles.json b/social-network/src/CreativityPage/your-articles.json new file mode 100644 index 0000000..bb947fb --- /dev/null +++ b/social-network/src/CreativityPage/your-articles.json @@ -0,0 +1,62 @@ +[ + { + "title": "The 7 Habits of Highly Creative People", + "description": "\"What a good artist understands is that nothing comes from nowhere. Nothing is completely original.\"", + "image": "https://cdn-images-1.medium.com/max/800/1*PIC-U670COEqmGwt4cvXAA.jpeg", + "link": "https://artplusmarketing.com/the-7-habits-of-highly-creative-people-6cfe6471af31", + "author": { + "name": "Louis Chew", + "image": "https://cdn-images-1.medium.com/fit/c/80/80/1*NGHEMBPNbIQmmAkvCjaspA.jpeg", + "isMediumMember": true + }, + "postedDate": "2018-04-04T07:00:00.000Z", + "minutesToRead": 8, + "hasAudioAvailable": false, + "memberPreview": false + }, + { + "title": "This Handy Chart Automatically Generates a Pitch for Your New Novel", + "description": "Feeling stuck? We help you skip the writing and go straight to the press release", + "image": "https://cdn-images-1.medium.com/max/800/1*KHs6OgOb7_aJhmQvOKj_dg.jpeg", + "link": "https://electricliterature.com/how-to-write-elevator-pitch-novel-publicity-infographic-a8ec74ecf7ce", + "author": { + "name": "Electric Literature", + "image": "https://cdn-images-1.medium.com/fit/c/80/80/1*bs47qwmiIR_bU01Jm6ZI9Q.jpeg", + "isMediumMember": false + }, + "postedDate": "2018-03-28T07:00:00.000Z", + "minutesToRead": 2, + "hasAudioAvailable": false, + "memberPreview": false + }, + { + "title": "Do Something You Can't Win At", + "description": "And make it something you love", + "image": "https://cdn-images-1.medium.com/max/800/1*cioT9CBBV2s0svet9LqKZA.png", + "link": "https://medium.com/@krisgage/do-something-you-cant-win-at-cb2e5d2ad3c1", + "author": { + "name": "Kris Gage", + "image": "https://cdn-images-1.medium.com/fit/c/80/80/1*e7o4kbk8ofT6eKaLrO0jaw.png", + "isMediumMember": false + }, + "postedDate": "2018-03-30T07:00:00.000Z", + "minutesToRead": 3, + "hasAudioAvailable": false, + "memberPreview": false + }, + { + "title": "Art as a Second Language", + "description": "Drawing is a translation of all my voices and words — an attempt to draw nothing", + "image": "https://cdn-images-1.medium.com/max/800/1*_NTwW2r8Konom4d5vIPkuw.png", + "link": "https://medium.com/@bluebed/speaking-different-languages-through-art-710e0a992dd3", + "author": { + "name": "Roman Muradov", + "image": "https://cdn-images-1.medium.com/fit/c/80/80/0*3PeNTwOh_hQpAuw0.png", + "isMediumMember": false + }, + "postedDate": "2018-03-27T07:00:00.000Z", + "minutesToRead": 6, + "hasAudioAvailable": true, + "memberPreview": true + } +] \ No newline at end of file diff --git a/social-network/src/index.css b/social-network/src/index.css new file mode 100644 index 0000000..b4cc725 --- /dev/null +++ b/social-network/src/index.css @@ -0,0 +1,5 @@ +body { + margin: 0; + padding: 0; + font-family: sans-serif; +} diff --git a/social-network/src/index.js b/social-network/src/index.js new file mode 100644 index 0000000..fae3e35 --- /dev/null +++ b/social-network/src/index.js @@ -0,0 +1,8 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import './index.css'; +import App from './App'; +import registerServiceWorker from './registerServiceWorker'; + +ReactDOM.render(<App />, document.getElementById('root')); +registerServiceWorker(); diff --git a/social-network/src/logo.svg b/social-network/src/logo.svg new file mode 100644 index 0000000..6b60c10 --- /dev/null +++ b/social-network/src/logo.svg @@ -0,0 +1,7 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"> + <g fill="#61DAFB"> + <path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/> + <circle cx="420.9" cy="296.5" r="45.7"/> + <path d="M520.5 78.1z"/> + </g> +</svg> diff --git a/social-network/src/registerServiceWorker.js b/social-network/src/registerServiceWorker.js new file mode 100644 index 0000000..a3e6c0c --- /dev/null +++ b/social-network/src/registerServiceWorker.js @@ -0,0 +1,117 @@ +// In production, we register a service worker to serve assets from local cache. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on the "N+1" visit to a page, since previously +// cached resources are updated in the background. + +// To learn more about the benefits of this model, read https://goo.gl/KwvDNy. +// This link also includes instructions on opting out of this behavior. + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.1/8 is considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) +); + +export default function register() { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Lets check if a service worker still exists or not. + checkValidServiceWorker(swUrl); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://goo.gl/SC7cgQ' + ); + }); + } else { + // Is not local host. Just register service worker + registerValidSW(swUrl); + } + }); + } +} + +function registerValidSW(swUrl) { + navigator.serviceWorker + .register(swUrl) + .then(registration => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the old content will have been purged and + // the fresh content will have been added to the cache. + // It's the perfect time to display a "New content is + // available; please refresh." message in your web app. + console.log('New content is available; please refresh.'); + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + } + } + }; + }; + }) + .catch(error => { + console.error('Error during service worker registration:', error); + }); +} + +function checkValidServiceWorker(swUrl) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl) + .then(response => { + // Ensure service worker exists, and that we really are getting a JS file. + if ( + response.status === 404 || + response.headers.get('content-type').indexOf('javascript') === -1 + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then(registration => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl); + } + }) + .catch(() => { + console.log( + 'No internet connection found. App is running in offline mode.' + ); + }); +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready.then(registration => { + registration.unregister(); + }); + } +}