├── .all-contributorsrc
├── .gitignore
├── README.md
├── _params.yaml
├── code
├── 10
│ ├── content-search.js
│ ├── header-click.js
│ ├── header-no-click.js
│ ├── header-search.js
│ ├── interactionBindings.js
│ ├── mousemove.js
│ ├── search-form.js
│ └── working-search.js
├── 01
│ └── .keep
├── 03
│ └── app1.html
├── 04
│ ├── container.jsx
│ ├── container2.jsx
│ ├── content1.jsx
│ ├── header.jsx
│ └── timeline1.jsx
├── 05
│ ├── activity_item.jsx
│ ├── content1.jsx
│ ├── content2.jsx
│ ├── content3.jsx
│ ├── content4.jsx
│ ├── header1.jsx
│ └── header2.jsx
├── 06
│ ├── header1.js
│ └── timer1.jsx
├── 07
│ ├── container1.js
│ ├── content1.js
│ ├── content2.js
│ └── timer1.js
├── 08
│ ├── basic-proptypes.js
│ ├── collection-proptypes.js
│ ├── element-proptypes.js
│ ├── object-proptypes.js
│ └── proptypes1.js
└── 09
│ ├── header1.js
│ └── inline-header.js
├── day-01
├── cover.jpg
├── doc
│ └── doc.mkd
├── post.md
└── public
│ └── index.html
├── day-02
├── cover.jpg
├── doc
│ └── doc.mkd
├── post.md
└── public
│ └── index.html
├── day-03
├── cover.jpg
├── doc
│ └── doc.mkd
├── post.md
└── public
│ ├── app.html
│ └── app2.html
├── day-04
├── cover.jpg
├── doc
│ └── doc.mkd
├── post.md
└── public
│ ├── Timeline.css
│ ├── app1.html
│ ├── app2.html
│ └── assets
│ └── images
│ ├── breakdown-2.jpg
│ ├── breakdown-2.png
│ ├── breakdown.jpg
│ ├── breakdown.png
│ └── part4.sketch
├── day-05
├── cover.jpg
├── doc
│ └── doc.mkd
├── post.md
└── public
│ ├── content.html
│ ├── content2.html
│ ├── content3.html
│ ├── header.html
│ ├── header2.html
│ └── header3.html
├── day-06
├── cover.jpg
├── doc
│ └── doc.mkd
├── post.md
└── public
│ ├── Clock.css
│ ├── clock-state.html
│ └── clock.html
├── day-07
├── cover.jpg
├── doc
│ └── doc.mkd
├── post.md
└── public
│ ├── clock.html
│ ├── container.html
│ ├── content.html
│ └── data.js
├── day-08
├── BasicProptypes.js
├── CollectionProptypes.js
├── ElementProptypes.js
├── ObjectProptypes.js
├── Proptypes1.js
├── UserLink.js
├── cover.jpg
├── doc
│ └── doc.mkd
└── post.md
├── day-09
├── cover.jpg
├── doc
│ └── doc.mkd
├── post.md
└── public
│ ├── header-inline.html
│ ├── header.html
│ ├── styles.css
│ └── text-color.html
├── day-10
├── cover.jpg
├── doc
│ └── doc.mkd
├── post.md
└── public
│ ├── header-click.html
│ ├── header-search-form-onchange.html
│ ├── header-search-form.html
│ ├── interaction-event-bindings.html
│ ├── mouse-move-react.html
│ ├── mouse-move.html
│ ├── search.html
│ └── styles.css
├── day-11
├── cover.jpg
├── doc
│ └── doc.mkd
├── post.md
└── public
│ └── clock.html
├── day-12
├── .gitignore
├── README.md
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── components
│ │ ├── Content.js
│ │ └── Header.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── day-13
├── README.md
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── components
│ │ ├── Repeater.js
│ │ ├── ShowA.js
│ │ └── Timer
│ │ │ ├── Ampm.js
│ │ │ ├── CleanerFormatter.js
│ │ │ ├── Clock.js
│ │ │ ├── Formatter.js
│ │ │ ├── Hour.js
│ │ │ ├── Minute.js
│ │ │ ├── Second.js
│ │ │ └── Separator.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── day-14
├── cover.jpg
├── doc
│ └── doc.mkd
└── post.md
├── day-15
├── README.md
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── getCurrentTimeCallback.js
│ ├── getCurrentTimeHandlerId.js
│ ├── getCurrentTimeOnFail.js
│ ├── getCurrentTimePromise.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── day-16
├── README.md
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── TimeForm.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── day-17
├── README.md
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── SimpleRouter.js
│ ├── TwoLinkedRoutes.js
│ ├── TwoLinkedSingleRenderedRoutes.js
│ ├── TwoLinkedSingleRoutes.js
│ ├── TwoRoutes.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── day-18
├── cover.jpg
├── doc
│ └── doc.mkd
└── post.md
├── day-19
├── README.md
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.test.js
│ ├── containers
│ │ ├── App.js
│ │ ├── Root.js
│ │ └── views
│ │ │ ├── About
│ │ │ └── About.js
│ │ │ └── Home
│ │ │ └── Home.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── redux
│ │ ├── configureStore.js
│ │ ├── reducers.js
│ │ └── types.js
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── day-20
├── README.md
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.test.js
│ ├── containers
│ │ ├── App.js
│ │ ├── Root.js
│ │ └── views
│ │ │ ├── About
│ │ │ └── About.js
│ │ │ └── Home
│ │ │ └── Home.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── redux
│ │ ├── actionCreators.js
│ │ ├── configureStore.js
│ │ ├── currentUser.js
│ │ ├── reducers.js
│ │ └── types.js
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── day-21
├── README.md
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.test.js
│ ├── containers
│ │ ├── App.js
│ │ ├── Root.js
│ │ └── views
│ │ │ ├── About
│ │ │ └── About.js
│ │ │ └── Home
│ │ │ └── Home.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── redux
│ │ ├── actionCreators.js
│ │ ├── apiMiddleware.js
│ │ ├── configureStore.js
│ │ ├── currentTime.js
│ │ ├── currentUser.js
│ │ ├── loggingMiddleware.js
│ │ ├── reducers.js
│ │ └── types.js
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── day-22
├── cover.jpg
├── doc
│ └── doc.mkd
└── post.md
├── day-23
├── README.md
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── components
│ │ └── Timeline
│ │ │ ├── Timeline.css
│ │ │ ├── Timeline.js
│ │ │ └── __tests__
│ │ │ └── Timeline-test.js
│ ├── index.js
│ └── logo.svg
└── yarn.lock
├── day-24
├── README.md
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── components
│ │ └── Timeline
│ │ │ ├── Timeline.css
│ │ │ ├── Timeline.js
│ │ │ └── __tests__
│ │ │ └── Timeline-test.js
│ ├── index.js
│ └── logo.svg
└── yarn.lock
├── day-25
├── README.md
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── components
│ │ └── Timeline
│ │ │ ├── ActivityItem.js
│ │ │ ├── Header.js
│ │ │ ├── Timeline.css
│ │ │ ├── Timeline.js
│ │ │ └── __tests__
│ │ │ ├── Timeline-test-test-utils.js
│ │ │ └── Timeline-test.js
│ ├── data.json
│ ├── index.js
│ ├── logo.svg
│ └── setupTests.js
└── yarn.lock
├── day-26
├── cover.jpg
├── doc
│ └── doc.mkd
├── nightwatch.json
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ └── index.html
├── reports
│ ├── CHROME_57.0.2987.133_MAC_auth-flow.xml
│ └── CHROME_79.0.3945.79_Linux_auth-flow.xml
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── Root.js
│ ├── components
│ │ ├── Form
│ │ │ ├── Form.js
│ │ │ └── Input.js
│ │ └── Nav
│ │ │ └── Navbar.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── redux
│ │ ├── actions
│ │ │ └── auth.js
│ │ ├── configureStore.js
│ │ ├── reducers
│ │ │ ├── auth.js
│ │ │ └── index.js
│ │ └── types.js
│ ├── styles
│ │ └── index.css
│ └── views
│ │ ├── About.js
│ │ ├── Home.js
│ │ └── Login.js
├── tests
│ └── auth-flow.js
└── yarn.lock
├── day-27
├── config
│ ├── development.config.env
│ ├── env.js
│ ├── jest
│ │ ├── cssTransform.js
│ │ └── fileTransform.js
│ ├── modules.js
│ ├── paths.js
│ ├── pnpTs.js
│ ├── production.config.env
│ ├── webpack.config.js
│ └── webpackDevServer.config.js
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── scripts
│ ├── build.js
│ ├── start.js
│ └── test.js
├── src
│ ├── App.css
│ ├── App.test.js
│ ├── containers
│ │ ├── App.js
│ │ ├── Root.js
│ │ └── views
│ │ │ ├── About
│ │ │ └── About.js
│ │ │ └── Home
│ │ │ └── Home.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── redux
│ │ ├── actionCreators.js
│ │ ├── apiMiddleware.js
│ │ ├── configureStore.js
│ │ ├── currentTime.js
│ │ ├── currentUser.js
│ │ ├── loggingMiddleware.js
│ │ ├── reducers.js
│ │ └── types.js
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── day-28
├── cover.jpg
├── doc
│ └── doc.mkd
└── post.md
├── day-29
├── .travis.yml
├── config
│ ├── development.config.env
│ ├── env.js
│ ├── jest
│ │ ├── cssTransform.js
│ │ └── fileTransform.js
│ ├── modules.js
│ ├── paths.js
│ ├── pnpTs.js
│ ├── production.config.env
│ ├── webpack.config.js
│ └── webpackDevServer.config.js
├── cover.jpg
├── doc
│ └── doc.mkd
├── package.json
├── post.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── scripts
│ ├── build.js
│ ├── deploy.sh
│ ├── release.js
│ ├── start.js
│ └── test.js
├── src
│ ├── App.css
│ ├── App.test.js
│ ├── containers
│ │ ├── App.js
│ │ ├── Root.js
│ │ └── views
│ │ │ ├── About
│ │ │ └── About.js
│ │ │ └── Home
│ │ │ └── Home.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── redux
│ │ ├── actionCreators.js
│ │ ├── apiMiddleware.js
│ │ ├── configureStore.js
│ │ ├── currentTime.js
│ │ ├── currentUser.js
│ │ ├── loggingMiddleware.js
│ │ ├── reducers.js
│ │ └── types.js
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── day-30
├── cover.jpg
├── doc
│ └── doc.mkd
└── post.md
├── images
├── 12
│ ├── app.jpg
│ ├── app.png
│ ├── build.jpg
│ ├── build.png
│ ├── chrome-start.jpg
│ ├── chrome-start.png
│ ├── create-app.jpg
│ ├── create-app.png
│ ├── index-html.jpg
│ ├── index-html.png
│ ├── install-create-react-app.jpg
│ ├── install-create-react-app.png
│ ├── npm-start.jpg
│ ├── npm-start.png
│ ├── tree.jpg
│ └── tree.png
├── 13
│ ├── children-map.jpg
│ ├── children-map.png
│ ├── run-no-key.jpg
│ └── run-no-key.png
├── 14
│ ├── install-fetch.jpg
│ └── install-fetch.png
├── 17
│ ├── install-react-router.jpg
│ └── install-react-router.png
├── 19
│ ├── home-time.jpg
│ ├── home-time.png
│ ├── install-redux.jpg
│ ├── install-redux.png
│ ├── no-reducer.jpg
│ ├── no-reducer.png
│ ├── structure.jpg
│ └── structure.png
├── 20
│ ├── home-time.jpg
│ ├── home-time.png
│ └── login-logout.gif
├── 23
│ ├── first-tests.jpg
│ ├── first-tests.png
│ ├── second-tests.jpg
│ └── second-tests.png
├── 24
│ ├── failing-test-1.jpg
│ ├── failing-test-1.png
│ ├── failing-test-2.jpg
│ ├── failing-test-2.png
│ ├── navbar.jpg
│ ├── navbar.png
│ ├── passing-test-1.jpg
│ ├── passing-test-1.png
│ └── passing-test.png
├── 25
│ ├── enzyme-test-1.jpg
│ ├── enzyme-test-1.png
│ ├── enzyme-test-2.jpg
│ ├── enzyme-test-2.png
│ ├── enzyme-test-3.jpg
│ └── enzyme-test-3.png
├── 26
│ ├── nightwatch-1.jpg
│ ├── nightwatch-1.png
│ ├── nightwatch-2.jpg
│ ├── nightwatch-2.png
│ ├── nightwatch-3.jpg
│ ├── nightwatch-3.png
│ ├── npm-start.jpg
│ ├── npm-start.png
│ ├── selenium-server.jpg
│ └── selenium-server.png
├── 28
│ ├── bitballoon.jpg
│ ├── bitballoon.png
│ ├── gh-pages.jpg
│ ├── gh-pages.png
│ ├── git-branch.jpg
│ ├── git-branch.png
│ ├── github-pages.jpg
│ ├── github-pages.png
│ ├── github-repo.jpg
│ ├── github-repo.png
│ ├── github-url.jpg
│ ├── github-url.png
│ ├── heroku-create.jpg
│ ├── heroku-create.png
│ ├── heroku-deploy.jpg
│ ├── heroku-deploy.png
│ ├── heroku-login.jpg
│ ├── heroku-login.png
│ ├── heroku-plugin.jpg
│ ├── heroku-plugin.png
│ ├── heroku-static-init.jpg
│ ├── heroku-static-init.png
│ ├── heroku.jpg
│ ├── heroku.png
│ ├── npm-build.jpg
│ ├── npm-build.png
│ ├── pancake.jpg
│ ├── pancake.png
│ ├── s3.jpg
│ ├── s3.png
│ ├── surge-deploy.jpg
│ ├── surge-deploy.png
│ ├── surge.jpg
│ └── surge.png
├── 29
│ ├── deploy-fail.jpg
│ ├── deploy-fail.png
│ ├── deploy-script.jpg
│ ├── deploy-script.png
│ ├── travis-activate-repo.jpg
│ ├── travis-activate-repo.png
│ ├── travis-output.jpg
│ ├── travis-output.png
│ ├── travis-select-repo.jpg
│ ├── travis-select-repo.png
│ ├── travis-setup.jpg
│ └── travis-setup.png
├── 04
│ ├── breakdown-2.jpg
│ ├── breakdown-2.png
│ ├── breakdown.jpg
│ ├── breakdown.png
│ └── part4.sketch
├── headings
│ ├── 1.jpg
│ ├── 10.jpg
│ ├── 10_wide.jpg
│ ├── 11.jpg
│ ├── 11_wide.jpg
│ ├── 12.jpg
│ ├── 12_wide.jpg
│ ├── 13.jpg
│ ├── 13_wide.jpg
│ ├── 14.jpg
│ ├── 14_wide.jpg
│ ├── 15.jpg
│ ├── 15_wide.jpg
│ ├── 16.jpg
│ ├── 16_wide.jpg
│ ├── 17.jpg
│ ├── 17_wide.jpg
│ ├── 18.jpg
│ ├── 18_wide.jpg
│ ├── 19.jpg
│ ├── 19_wide.jpg
│ ├── 1_wide.jpg
│ ├── 2.jpg
│ ├── 20.jpg
│ ├── 20_wide.jpg
│ ├── 21.jpg
│ ├── 21_wide.jpg
│ ├── 22.jpg
│ ├── 22_wide.jpg
│ ├── 23.jpg
│ ├── 23_wide.jpg
│ ├── 24.jpg
│ ├── 24_wide.jpg
│ ├── 25.jpg
│ ├── 25_wide.jpg
│ ├── 26.jpg
│ ├── 26_wide.jpg
│ ├── 27.jpg
│ ├── 27_wide.jpg
│ ├── 28.jpg
│ ├── 28_wide.jpg
│ ├── 29.jpg
│ ├── 29_wide.jpg
│ ├── 2_wide.jpg
│ ├── 3.jpg
│ ├── 30.jpg
│ ├── 30_wide.jpg
│ ├── 3_wide.jpg
│ ├── 4.jpg
│ ├── 4_wide.jpg
│ ├── 5.jpg
│ ├── 5_wide.jpg
│ ├── 6.jpg
│ ├── 6_wide.jpg
│ ├── 7.jpg
│ ├── 7_wide.jpg
│ ├── 8.jpg
│ ├── 8_wide.jpg
│ ├── 9.jpg
│ └── 9_wide.jpg
└── readme
│ ├── 30-days-of-react-book-cover-2-as-book-220.png
│ ├── download-the-pdf-button.png
│ └── fullstack-react-hero-book.png
├── index.html
├── internal
├── package.json
├── readme-chapters.js
└── yarn.lock
└── styles.css
/_params.yaml:
--------------------------------------------------------------------------------
1 | note: 'This file is for fullstackreact.com internal use'
2 | series: 30-days-of-react
3 | isPrinting: false
4 | published: false
5 | draft: false
6 | author: auser
7 | autotoc: true
8 | fileMetaKeyHeadingsAllowed: true
9 | containerintro: 'partials/series/30-days-of-react/what-is-this.html'
10 | containerfooter: 'partials/series/30-days-of-react/postcontents.html'
11 | bodyClasses: thirty-days landingpage
12 | editOnGithubUrl: __GITHUB_REPO__/blob/master/day-__DAY_DIR__/post.md
13 | githubRepo: https://github.com/fullstackreact/30-days-of-react
14 | articleEntry: '30-days-of-react/__PERMALINK__-code/index'
15 | codeRoot: '__FILE_PATH__/code/__DAY_DIR__'
16 | imagesDir: '../../../assets/images/series/30-days-of-react/__DAY_DIR__'
17 | githubRepo: 'https://github.com/fullstackreact/30-days-of-react'
18 | variables:
19 | __DAY_DIR__: dayDir
20 | __GITHUB_REPO__: githubRepo
21 | __PERMALINK__: permalink
22 |
--------------------------------------------------------------------------------
/code/01/.keep:
--------------------------------------------------------------------------------
1 | .keep
--------------------------------------------------------------------------------
/code/03/app1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Hello world
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/code/04/container.jsx:
--------------------------------------------------------------------------------
1 | class App extends React.Component {
2 | render() {
3 | return (
4 |
5 |
6 | {/* content goes here */}
7 |
8 |
9 | )
10 | }
11 | }
--------------------------------------------------------------------------------
/code/04/container2.jsx:
--------------------------------------------------------------------------------
1 | class App extends React.Component {
2 | render() {
3 | return (
4 |
10 | )
11 | }
12 | }
--------------------------------------------------------------------------------
/code/04/content1.jsx:
--------------------------------------------------------------------------------
1 | class Content extends React.Component {
2 | render() {
3 | return (
4 |
5 |
6 |
7 | {/* Timeline item */}
8 |
9 |
10 |

11 | Doug
12 |
13 |
14 |
15 | An hour ago
16 |
17 |
Ate lunch
18 |
19 | 2
20 |
21 |
22 |
23 | {/* ... */}
24 |
25 |
26 | )
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/code/04/header.jsx:
--------------------------------------------------------------------------------
1 | class Header extends React.Component {
2 | render() {
3 | return (
4 |
5 |
6 |
7 |
Timeline
8 |
9 |
13 |
14 |
15 |
16 | )
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/code/05/activity_item.jsx:
--------------------------------------------------------------------------------
1 | class ActivityItem extends React.Component {
2 | render() {
3 | const {activity} = this.props; // ES6 destructuring
4 |
5 | return (
6 |
7 |
8 |

9 | {activity.user.name}
10 |
11 |
12 |
13 | {activity.timestamp}
14 |
15 |
{activity.text}
16 |
17 | {activity.comments.length}
18 |
19 |
20 | )
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/code/05/content1.jsx:
--------------------------------------------------------------------------------
1 | class Content extends React.Component {
2 | render() {
3 | return (
4 |
5 |
6 |
7 | {/* Timeline item */}
8 |
9 |
10 |

11 | Doug
12 |
13 |
14 |
15 | An hour ago
16 |
17 |
Ate lunch
18 |
19 | 2
20 |
21 |
22 |
23 |
24 | )
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/code/05/content2.jsx:
--------------------------------------------------------------------------------
1 | class Content extends React.Component {
2 | render() {
3 | const {activity} = this.props; // ES6 destructuring
4 |
5 | return (
6 |
7 |
8 |
9 | {/* Timeline item */}
10 |
11 |
12 |

13 | {activity.user.name}
14 |
15 |
16 |
17 | {activity.timestamp}
18 |
19 |
{activity.text}
20 |
21 | {activity.comments.length}
22 |
23 |
24 |
25 | )
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/code/05/content3.jsx:
--------------------------------------------------------------------------------
1 | class Content extends React.Component {
2 | render() {
3 | const {activities} = this.props; // ES6 destructuring
4 |
5 | return (
6 |
7 |
8 |
9 | {/* Timeline item */}
10 | {activities.map((activity) => {
11 | return (
12 |
13 |
14 |

15 | {activity.user.name}
16 |
17 |
18 |
19 | {activity.timestamp}
20 |
21 |
{activity.text}
22 |
23 | {activity.comments.length}
24 |
25 |
26 | );
27 | })}
28 |
29 |
30 | )
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/code/05/content4.jsx:
--------------------------------------------------------------------------------
1 | class Content extends React.Component {
2 | render() {
3 | const {activities} = this.props; // ES6 destructuring
4 |
5 | return (
6 |
7 |
8 |
9 | {/* Timeline item */}
10 | {activities.map((activity) => (
11 |
13 | ))}
14 |
15 |
16 | )
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/code/05/header1.jsx:
--------------------------------------------------------------------------------
1 | class Header extends React.Component {
2 | render() {
3 | return (
4 |
5 |
6 |
7 |
Timeline
8 |
9 |
13 |
14 |
15 |
16 | )
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/code/05/header2.jsx:
--------------------------------------------------------------------------------
1 | class Header extends React.Component {
2 | render() {
3 | return (
4 |
5 |
6 |
7 |
8 | {this.props.title}
9 |
10 |
11 |
15 |
16 |
17 |
18 | )
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/code/07/container1.js:
--------------------------------------------------------------------------------
1 | class Container extends React.Component {
2 | constructor(props) {
3 | super(props);
4 |
5 | this.state = {refreshing: false}
6 | }
7 |
8 | // Bound to the refresh button
9 | refresh() {
10 | this.setState({refreshing: true})
11 | }
12 |
13 | // Callback from the `Content` component
14 | onComponentRefresh() {
15 | this.setState({refreshing: false});
16 | }
17 |
18 | render() {
19 | const {refreshing} = this.state;
20 | return (
21 |
22 |
23 | {/* refreshing is the component's state */}
24 |
28 | {/* A container for styling */}
29 |
35 |
36 | )
37 | }
38 | }
--------------------------------------------------------------------------------
/code/07/content1.js:
--------------------------------------------------------------------------------
1 | class Content extends React.Component {
2 | render() {
3 | const {activities} = this.props; // ES6 destructuring
4 |
5 | return (
6 |
7 |
8 |
9 | {/* Timeline item */}
10 | {activities.map((activity) => (
11 |
13 | ))}
14 |
15 |
16 | )
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/code/07/timer1.js:
--------------------------------------------------------------------------------
1 | class Clock extends React.Component {
2 | constructor(props) {
3 | super(props);
4 | this.state = this.getTime();
5 | }
6 |
7 | componentDidMount() {
8 | this.setTimer();
9 | }
10 |
11 | setTimer() {
12 | this.timeout = setTimeout(this.updateClock.bind(this), 1000);
13 | }
14 |
15 | updateClock() {
16 | this.setState(this.getTime, this.setTimer);
17 | }
18 |
19 | getTime() {
20 | const currentTime = new Date();
21 | return {
22 | hours: currentTime.getHours(),
23 | minutes: currentTime.getMinutes(),
24 | seconds: currentTime.getSeconds(),
25 | ampm: currentTime.getHours() >= 12 ? 'pm' : 'am'
26 | }
27 | }
28 |
29 | // ...
30 | }
--------------------------------------------------------------------------------
/code/08/basic-proptypes.js:
--------------------------------------------------------------------------------
1 | Clock.propTypes = {
2 | title: React.PropTypes.string,
3 | count: React.PropTypes.number,
4 | isOn: React.PropTypes.bool,
5 | onDisplay: React.PropTypes.func,
6 | symbol: React.PropTypes.symbol,
7 | user: React.PropTypes.object,
8 |
9 | name: React.PropTypes.node
10 | }
--------------------------------------------------------------------------------
/code/08/collection-proptypes.js:
--------------------------------------------------------------------------------
1 | Clock.propTypes = {
2 | counts: React.PropTypes.array,
3 | users: React.PropTypes.arrayOf(React.PropTypes.object),
4 | alarmColor: React.PropTypes.oneOf(['red', 'blue']),
5 | description: React.PropTypes.oneOfType([
6 | React.PropTypes.string,
7 | React.PropTypes.instanceOf(Title)
8 | ]),
9 | }
--------------------------------------------------------------------------------
/code/08/element-proptypes.js:
--------------------------------------------------------------------------------
1 | Clock.propTypes = {
2 | displayEle: React.PropTypes.element
3 | }
--------------------------------------------------------------------------------
/code/08/object-proptypes.js:
--------------------------------------------------------------------------------
1 | Clock.propTypes = {
2 | basicObject: React.PropTypes.object,
3 |
4 | numbers: React.PropTypes
5 | .objectOf(React.PropTypes.numbers),
6 |
7 | messages: React.PropTypes
8 | .instanceOf(Message),
9 |
10 | contactList: React.PropTypes.shape({
11 | name: React.PropTypes.string,
12 | phone: React.PropTypes.string,
13 | })
14 | }
--------------------------------------------------------------------------------
/code/08/proptypes1.js:
--------------------------------------------------------------------------------
1 | class Clock extends React.Component {
2 | // ...
3 | }
4 |
5 | Clock.propTypes = {
6 | // key is the name of the prop and
7 | // value is the PropType
8 | }
--------------------------------------------------------------------------------
/code/09/header1.js:
--------------------------------------------------------------------------------
1 | class Header extends React.Component {
2 | render() {
3 | return (
4 |
10 |
15 |
16 |
{this.props.title}
17 |
18 |
19 |
20 |
21 |
22 | );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/10/header-no-click.js:
--------------------------------------------------------------------------------
1 | class Header extends React.Component {
2 | render() {
3 | // Classes to add to the element
4 | let searchInputClasses = ["searchInput"];
5 |
6 | // Update the class array if the state is visible
7 | if (this.state.searchVisible) {
8 | searchInputClasses.push("active");
9 | }
10 |
11 | return (
12 |
13 |
14 |
15 |
16 | {this.props.title}
17 |
18 |
19 |
23 |
24 |
25 |
26 | )
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/code/10/mousemove.js:
--------------------------------------------------------------------------------
1 | class MouseMove extends React.Component {
2 | constructor(props) {
3 | super(props);
4 | this.state = {
5 | x: -1,
6 | y: -1
7 | }
8 | }
9 | mouseMoved(e) {
10 | this.setState({
11 | x: e.screenX,
12 | y: e.screenY
13 | })
14 | }
15 | render() {
16 | const {x, y} = this.state;
17 | return (
18 |
19 | Mouse is at {x}, {y}
20 |
21 | )
22 | }
23 | }
--------------------------------------------------------------------------------
/code/10/search-form.js:
--------------------------------------------------------------------------------
1 | class SearchForm extends React.Component {
2 | static propTypes = {
3 | onSubmit: T.func.isRequired,
4 | searchVisible: T.bool
5 | }
6 |
7 | static defaultProps = {
8 | onSubmit: () => {},
9 | searchVisible: false
10 | }
11 |
12 | constructor(props) {
13 | super(props);
14 |
15 | this.state = {
16 | searchText: ''
17 | }
18 | }
19 |
20 | updateSearchInput(e) {
21 | const val = e.target.value;
22 | this.setState({
23 | searchText: val
24 | });
25 | }
26 |
27 | submitForm(e) {
28 | e.preventDefault();
29 |
30 | const {searchText} = this.state;
31 | this.props.onSubmit(searchText);
32 | }
33 |
34 | render() {
35 | const {searchVisible, className} = this.props;
36 |
37 | return (
38 |
47 | );
48 | }
49 | }
--------------------------------------------------------------------------------
/day-01/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-01/cover.jpg
--------------------------------------------------------------------------------
/day-01/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hello world
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/day-02/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-02/cover.jpg
--------------------------------------------------------------------------------
/day-02/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello world
6 |
7 |
9 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/day-03/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-03/cover.jpg
--------------------------------------------------------------------------------
/day-03/public/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello world
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/day-03/public/app2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Hello world 2
7 |
8 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/day-04/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-04/cover.jpg
--------------------------------------------------------------------------------
/day-04/public/assets/images/breakdown-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-04/public/assets/images/breakdown-2.jpg
--------------------------------------------------------------------------------
/day-04/public/assets/images/breakdown-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-04/public/assets/images/breakdown-2.png
--------------------------------------------------------------------------------
/day-04/public/assets/images/breakdown.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-04/public/assets/images/breakdown.jpg
--------------------------------------------------------------------------------
/day-04/public/assets/images/breakdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-04/public/assets/images/breakdown.png
--------------------------------------------------------------------------------
/day-04/public/assets/images/part4.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-04/public/assets/images/part4.sketch
--------------------------------------------------------------------------------
/day-05/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-05/cover.jpg
--------------------------------------------------------------------------------
/day-06/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-06/cover.jpg
--------------------------------------------------------------------------------
/day-06/public/Clock.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --firstColor: rgba(0, 169, 158, 1);
3 | --secondColor: rgba(0, 191, 150, 1);
4 | --textColor: #fff;
5 | }
6 |
7 | .clock {
8 | position: relative;
9 | border-radius: 0.5em;
10 | margin: 10px auto;
11 | font-family: "Open Sans", sans-serif;
12 | text-align: center;
13 | font-size: 60px;
14 | color: var(--textColor);
15 | line-height: 2em;
16 | background: #eee;
17 | /* Old browsers */
18 | background: var(--firstColor);
19 | }
20 |
21 | @media only screen and (min-width: 700px) and (max-width: 1000px) {
22 | .clock {
23 | font-size: 50px;
24 | }
25 | }
26 |
27 | @media only screen and (min-width: 500px) and (max-width: 699px) {
28 | .clock {
29 | font-size: 45px;
30 | }
31 | }
32 |
33 | @media only screen and (min-width: 200px) and (max-width: 499px) {
34 | .clock {
35 | font-size: 40px;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/day-07/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-07/cover.jpg
--------------------------------------------------------------------------------
/day-08/BasicProptypes.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | Clock.propTypes = {
4 | title: PropTypes.string,
5 | count: PropTypes.number,
6 | isOn: PropTypes.bool,
7 | onDisplay: PropTypes.func,
8 | symbol: PropTypes.symbol,
9 | user: PropTypes.object,
10 |
11 | name: PropTypes.node
12 | };
13 |
--------------------------------------------------------------------------------
/day-08/CollectionProptypes.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | Clock.propTypes = {
4 | counts: PropTypes.array,
5 | users: PropTypes.arrayOf(PropTypes.object),
6 | alarmColor: PropTypes.oneOf(['red', 'blue']),
7 | description: PropTypes.oneOfType([
8 | PropTypes.string,
9 | PropTypes.instanceOf(Title)
10 | ])
11 | };
12 |
--------------------------------------------------------------------------------
/day-08/ElementProptypes.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | Clock.propTypes = {
4 | displayEle: PropTypes.element
5 | };
6 |
--------------------------------------------------------------------------------
/day-08/ObjectProptypes.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 |
3 | Clock.propTypes = {
4 | basicObject: PropTypes.object,
5 |
6 | numbers: PropTypes.objectOf(PropTypes.numbers),
7 |
8 | messages: PropTypes.instanceOf(Message),
9 |
10 | contactList: PropTypes.shape({
11 | name: PropTypes.string,
12 | phone: PropTypes.string
13 | })
14 | };
15 |
--------------------------------------------------------------------------------
/day-08/Proptypes1.js:
--------------------------------------------------------------------------------
1 | class Clock extends React.Component {
2 | // ...
3 | }
4 |
5 | Clock.propTypes = {
6 | // key is the name of the prop and
7 | // value is the PropType
8 | }
--------------------------------------------------------------------------------
/day-08/UserLink.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | class UserLink extends React.Component {
4 | render() {
5 | const { user } = this.props
6 | return (
7 |
8 | Welcome back {user.name}
9 |
10 | )
11 | }
12 | }
13 |
14 | UserLink.propTypes = {
15 | user: (props, propName, componentName) => {
16 | if (!props[propName] || !props[propName].name) {
17 | return new Error(
18 | "Invalid " + propName + ": No name property defined for component " + componentName
19 | )
20 | }
21 | }
22 | }
23 |
24 | export default UserLink
--------------------------------------------------------------------------------
/day-08/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-08/cover.jpg
--------------------------------------------------------------------------------
/day-09/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-09/cover.jpg
--------------------------------------------------------------------------------
/day-09/public/styles.css:
--------------------------------------------------------------------------------
1 | .demo .notificationsFrame .header {
2 | background: rgba(251, 202, 43, 1);
3 | }
4 | .demo .notificationsFrame .header .searchIcon,
5 | .demo .notificationsFrame .header .title {
6 | color: #333333;
7 | }
8 |
9 | .demo .notificationsFrame .header .menuIcon .dashTop,
10 | .demo .notificationsFrame .header .menuIcon .dashBottom,
11 | .demo .notificationsFrame .header .menuIcon .circle {
12 | background-color: #333333;
13 | }
14 |
--------------------------------------------------------------------------------
/day-09/public/text-color.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Color Blue
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/day-10/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-10/cover.jpg
--------------------------------------------------------------------------------
/day-10/public/mouse-move.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Mouse Move
7 |
8 |
9 |
10 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/day-10/public/styles.css:
--------------------------------------------------------------------------------
1 | .demo {
2 | max-width: 800px;
3 | margin: 20px auto;
4 | }
5 | .eventContainer ul {
6 | margin: 0;
7 | padding: 0;
8 | }
9 | .eventContainer ul li.eventListing {
10 | list-style-type: none;
11 | font-size: 0.9em;
12 | position: relative;
13 | z-index: 2;
14 | padding: 20px 10px;
15 | box-shadow: 0px 1px 1px 0 rgba(0, 0, 0, 0.3);
16 | }
17 | .eventContainer ul li.eventListing .reset,
18 | .eventContainer ul li.eventListing .name,
19 | .eventContainer ul li.eventListing .trigger {
20 | position: absolute;
21 | top: 8px;
22 | }
23 | .eventContainer ul li.eventListing .reset {
24 | left: 5px;
25 | }
26 | .eventContainer ul li.eventListing .name {
27 | left: 35px;
28 | }
29 | .eventContainer ul li.eventListing .trigger {
30 | right: 15px;
31 | }
32 | .eventContainer ul li.eventListing .trigger i {
33 | color: rgba(95, 152, 205, 1);
34 | }
35 |
--------------------------------------------------------------------------------
/day-11/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-11/cover.jpg
--------------------------------------------------------------------------------
/day-12/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/day-12/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-12/cover.jpg
--------------------------------------------------------------------------------
/day-12/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-12",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.12.0",
10 | "react-dom": "^16.12.0",
11 | "react-scripts": "3.3.0"
12 | },
13 | "scripts": {
14 | "start": "react-scripts start",
15 | "build": "react-scripts build",
16 | "test": "react-scripts test",
17 | "eject": "react-scripts eject"
18 | },
19 | "eslintConfig": {
20 | "extends": "react-app"
21 | },
22 | "browserslist": {
23 | "production": [
24 | ">0.2%",
25 | "not dead",
26 | "not op_mini all"
27 | ],
28 | "development": [
29 | "last 1 chrome version",
30 | "last 1 firefox version",
31 | "last 1 safari version"
32 | ]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/day-12/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-12/public/favicon.ico
--------------------------------------------------------------------------------
/day-12/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-12/public/logo192.png
--------------------------------------------------------------------------------
/day-12/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-12/public/logo512.png
--------------------------------------------------------------------------------
/day-12/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-12/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-12/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/day-12/src/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import Header from "./components/Header";
4 | import Content from "./components/Content";
5 |
6 | function App() {
7 | return (
8 |
9 |
10 |
11 |
12 | );
13 | }
14 |
15 | export default App;
16 |
--------------------------------------------------------------------------------
/day-12/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/day-12/src/components/Content.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 |
3 | class Content extends Component {
4 | render() {
5 | return Content goes here
;
6 | }
7 | }
8 |
9 | export default Content;
10 |
--------------------------------------------------------------------------------
/day-12/src/components/Header.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 |
3 | class Header extends Component {
4 | render() {
5 | return (
6 |
9 | );
10 | }
11 | }
12 |
13 | export default Header;
14 |
--------------------------------------------------------------------------------
/day-12/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/day-12/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/day-12/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/day-13/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-13/cover.jpg
--------------------------------------------------------------------------------
/day-13/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-13",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.12.0",
10 | "react-dom": "^16.12.0",
11 | "react-scripts": "3.3.0"
12 | },
13 | "scripts": {
14 | "start": "react-scripts start",
15 | "build": "react-scripts build",
16 | "test": "react-scripts test",
17 | "eject": "react-scripts eject"
18 | },
19 | "eslintConfig": {
20 | "extends": "react-app"
21 | },
22 | "browserslist": {
23 | "production": [
24 | ">0.2%",
25 | "not dead",
26 | "not op_mini all"
27 | ],
28 | "development": [
29 | "last 1 chrome version",
30 | "last 1 firefox version",
31 | "last 1 safari version"
32 | ]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/day-13/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-13/public/favicon.ico
--------------------------------------------------------------------------------
/day-13/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-13/public/logo192.png
--------------------------------------------------------------------------------
/day-13/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-13/public/logo512.png
--------------------------------------------------------------------------------
/day-13/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-13/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-13/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/day-13/src/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const a = [1, 10, 100, 1000, 10000];
4 | const App = props => {
5 | return (
6 |
7 | {React.Children.map(a, i => (
8 | - {i}
9 | ))}
10 |
11 | );
12 | };
13 |
14 | export default App;
15 |
--------------------------------------------------------------------------------
/day-13/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/day-13/src/components/Repeater.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const a = [1, 10, 100, 1000, 10000];
4 | const Repeater = () => {
5 | return (
6 |
7 | {a.map(i => {
8 | return - {i}
;
9 | })}
10 |
11 | );
12 | };
13 |
14 | export default Repeater;
15 |
--------------------------------------------------------------------------------
/day-13/src/components/ShowA.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | const a = 10;
3 | const ShowA = () => {a}
;
4 | const MultipleA = () => {a * a}
;
5 |
--------------------------------------------------------------------------------
/day-13/src/components/Timer/Ampm.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Ampm = ({hours}) => ({hours >= 12 ? 'pm' : 'am'})
4 |
5 | export default Ampm
--------------------------------------------------------------------------------
/day-13/src/components/Timer/CleanerFormatter.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import Hour from "./Hour";
4 | import Minute from "./Minute";
5 | import Second from "./Second";
6 | import Ampm from "./Ampm";
7 | import Separator from "./Separator";
8 |
9 | const Formatter = props => {
10 | let children = props.format.split("").map(e => {
11 | if (e === "h") {
12 | return ;
13 | } else if (e === "m") {
14 | return ;
15 | } else if (e === "s") {
16 | return ;
17 | } else if (e === "p") {
18 | return ;
19 | } else if (e === " ") {
20 | return ;
21 | } else {
22 | return ;
23 | }
24 | });
25 | return (
26 |
27 | {React.Children.map(children, c => React.cloneElement(c, props))}
28 |
29 | );
30 | };
31 |
32 | export default Formatter;
33 |
--------------------------------------------------------------------------------
/day-13/src/components/Timer/Formatter.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Hour from './Hour';
4 | import Minute from './Minute';
5 | import Second from './Second';
6 | import Ampm from './Ampm';
7 | import Separator from './Separator';
8 |
9 | const Formatter = (props) => {
10 | let children = props.format.split('').map((e, idx) => {
11 | if (e === 'h') {
12 | return
13 | } else if (e === 'm') {
14 | return
15 | } else if (e === 's') {
16 | return
17 | } else if (e === 'p') {
18 | return
19 | } else if (e === ' ') {
20 | return ;
21 | } else {
22 | return
23 | }
24 | });
25 |
26 | return {children};
27 | }
28 |
29 | export default Formatter
--------------------------------------------------------------------------------
/day-13/src/components/Timer/Hour.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Hour = (props) => {
4 | let {hours} = props;
5 | if (hours === 0) { hours = 12; }
6 | if (props.twelveHours) { hours -= 12; }
7 | return ({hours})
8 | }
9 |
10 | export default Hour
--------------------------------------------------------------------------------
/day-13/src/components/Timer/Minute.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Minute = ({minutes}) => ({minutes<10 && '0'}{minutes})
4 |
5 | export default Minute
--------------------------------------------------------------------------------
/day-13/src/components/Timer/Second.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Second = ({seconds}) => ({seconds<10 && '0'}{seconds})
4 |
5 | export default Second
--------------------------------------------------------------------------------
/day-13/src/components/Timer/Separator.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Separator = ({separator}) => ({separator || ':'})
4 |
5 | export default Separator
--------------------------------------------------------------------------------
/day-13/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/day-13/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/day-13/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/day-14/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-14/cover.jpg
--------------------------------------------------------------------------------
/day-15/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-15/cover.jpg
--------------------------------------------------------------------------------
/day-15/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-15",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.12.0",
10 | "react-dom": "^16.12.0",
11 | "react-scripts": "3.3.0",
12 | "whatwg-fetch": "^3.0.0"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": "react-app"
22 | },
23 | "browserslist": {
24 | "production": [
25 | ">0.2%",
26 | "not dead",
27 | "not op_mini all"
28 | ],
29 | "development": [
30 | "last 1 chrome version",
31 | "last 1 firefox version",
32 | "last 1 safari version"
33 | ]
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/day-15/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-15/public/favicon.ico
--------------------------------------------------------------------------------
/day-15/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-15/public/logo192.png
--------------------------------------------------------------------------------
/day-15/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-15/public/logo512.png
--------------------------------------------------------------------------------
/day-15/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-15/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-15/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/day-15/src/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "whatwg-fetch";
3 |
4 | const App = props => {
5 | return ;
6 | };
7 |
8 | export default App;
9 |
--------------------------------------------------------------------------------
/day-15/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/day-15/src/getCurrentTimeCallback.js:
--------------------------------------------------------------------------------
1 | export default function getCurrentTimeCallback(callback) {
2 | // Get the current 'global' time from an API
3 | return setTimeout(function() {
4 | var currentTime = new Date();
5 | callback(currentTime);
6 | }, 2000);
7 | }
8 |
--------------------------------------------------------------------------------
/day-15/src/getCurrentTimeHandlerId.js:
--------------------------------------------------------------------------------
1 | export default function getCurrentTimeHandlerId() {
2 | // Get the current 'global' time from an API
3 | return setTimeout(function() {
4 | return new Date();
5 | }, 2000);
6 | }
7 |
--------------------------------------------------------------------------------
/day-15/src/getCurrentTimeOnFail.js:
--------------------------------------------------------------------------------
1 | export default function getCurrentTimeOnFail(onSuccess, onFail) {
2 | // Get the current 'global' time from an API
3 | return setTimeout(function() {
4 | // randomly decide if the date is retrieved or not
5 | var didSucceed = Math.random() >= 0.5;
6 | if (didSucceed) {
7 | var currentTime = new Date();
8 | onSuccess(currentTime);
9 | } else {
10 | onFail("Unknown error");
11 | }
12 | }, 2000);
13 | }
14 |
--------------------------------------------------------------------------------
/day-15/src/getCurrentTimePromise.js:
--------------------------------------------------------------------------------
1 | export default function getCurrentTimePromise() {
2 | // Get the current 'global' time from an API using Promise
3 | return new Promise((resolve, reject) => {
4 | setTimeout(function() {
5 | var didSucceed = Math.random() >= 0.5;
6 | didSucceed ? resolve(new Date()) : reject("Error");
7 | }, 2000);
8 | });
9 | }
10 |
--------------------------------------------------------------------------------
/day-15/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/day-15/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/day-16/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-16/cover.jpg
--------------------------------------------------------------------------------
/day-16/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-16",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.12.0",
10 | "react-dom": "^16.12.0",
11 | "react-scripts": "3.3.0",
12 | "whatwg-fetch": "^3.0.0"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": "react-app"
22 | },
23 | "browserslist": {
24 | "production": [
25 | ">0.2%",
26 | "not dead",
27 | "not op_mini all"
28 | ],
29 | "development": [
30 | "last 1 chrome version",
31 | "last 1 firefox version",
32 | "last 1 safari version"
33 | ]
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/day-16/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-16/public/favicon.ico
--------------------------------------------------------------------------------
/day-16/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-16/public/logo192.png
--------------------------------------------------------------------------------
/day-16/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-16/public/logo512.png
--------------------------------------------------------------------------------
/day-16/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-16/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-16/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/day-16/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/day-16/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/day-16/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import "./index.css";
4 | import App from "./App";
5 | import * as serviceWorker from "./serviceWorker";
6 |
7 | ReactDOM.render(, document.getElementById("root"));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/day-16/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/day-17/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-17/cover.jpg
--------------------------------------------------------------------------------
/day-17/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-17",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.12.0",
10 | "react-dom": "^16.12.0",
11 | "react-frame-component": "^4.1.1",
12 | "react-router-dom": "^5.1.2",
13 | "react-scripts": "3.3.0"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test",
19 | "eject": "react-scripts eject"
20 | },
21 | "eslintConfig": {
22 | "extends": "react-app"
23 | },
24 | "browserslist": {
25 | "production": [
26 | ">0.2%",
27 | "not dead",
28 | "not op_mini all"
29 | ],
30 | "development": [
31 | "last 1 chrome version",
32 | "last 1 firefox version",
33 | "last 1 safari version"
34 | ]
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/day-17/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-17/public/favicon.ico
--------------------------------------------------------------------------------
/day-17/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-17/public/logo192.png
--------------------------------------------------------------------------------
/day-17/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-17/public/logo512.png
--------------------------------------------------------------------------------
/day-17/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-17/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-17/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/day-17/src/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { BrowserRouter as Router, Route } from "react-router-dom";
4 |
5 | const Home = () => (
6 |
7 |
Welcome home
8 |
9 | );
10 |
11 | class App extends React.Component {
12 | render() {
13 | return (
14 |
15 |
16 |
17 | );
18 | }
19 | }
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/day-17/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/day-17/src/SimpleRouter.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { BrowserRouter as Router, Route } from "react-router-dom";
4 |
5 | const Home = () => (
6 |
7 |
Welcome home
8 |
9 | );
10 |
11 | class App extends React.Component {
12 | render() {
13 | return (
14 |
15 |
16 |
17 | );
18 | }
19 | }
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/day-17/src/TwoLinkedRoutes.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { BrowserRouter as Router, Route, Link } from "react-router-dom";
4 |
5 | const Home = () => (
6 |
7 |
Welcome home
8 | Go to about
9 |
10 | );
11 | const About = () => (
12 |
13 |
About
14 | Go home
15 |
16 | );
17 |
18 | class App extends React.Component {
19 | render() {
20 | return (
21 |
22 |
23 |
24 |
25 |
26 |
27 | );
28 | }
29 | }
30 |
31 | export default App;
32 |
--------------------------------------------------------------------------------
/day-17/src/TwoLinkedSingleRoutes.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
4 |
5 | const Home = () => (
6 |
7 |
Welcome home
8 | Go to about
9 |
10 | );
11 | const About = () => (
12 |
13 |
About
14 | Go home
15 |
16 | );
17 |
18 | class App extends React.Component {
19 | render() {
20 | return (
21 |
22 |
23 |
24 |
25 |
26 |
27 | );
28 | }
29 | }
30 |
31 | export default App;
32 |
--------------------------------------------------------------------------------
/day-17/src/TwoRoutes.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { BrowserRouter as Router, Route } from "react-router-dom";
4 |
5 | const Home = () => (
6 |
7 |
Welcome home
8 |
9 | );
10 | const About = () => (
11 |
12 |
About
13 |
14 | );
15 |
16 | class App extends React.Component {
17 | render() {
18 | return (
19 |
20 |
21 |
22 |
23 |
24 |
25 | );
26 | }
27 | }
28 |
29 | export default App;
30 |
--------------------------------------------------------------------------------
/day-17/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/day-17/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/day-18/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-18/cover.jpg
--------------------------------------------------------------------------------
/day-19/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-19/cover.jpg
--------------------------------------------------------------------------------
/day-19/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-19",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.12.0",
10 | "react-dom": "^16.12.0",
11 | "react-redux": "^7.1.3",
12 | "react-router-dom": "^5.1.2",
13 | "react-scripts": "3.3.0",
14 | "redux": "^4.0.4"
15 | },
16 | "scripts": {
17 | "start": "react-scripts start",
18 | "build": "react-scripts build",
19 | "test": "react-scripts test",
20 | "eject": "react-scripts eject"
21 | },
22 | "eslintConfig": {
23 | "extends": "react-app"
24 | },
25 | "browserslist": {
26 | "production": [
27 | ">0.2%",
28 | "not dead",
29 | "not op_mini all"
30 | ],
31 | "development": [
32 | "last 1 chrome version",
33 | "last 1 firefox version",
34 | "last 1 safari version"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/day-19/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-19/public/favicon.ico
--------------------------------------------------------------------------------
/day-19/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-19/public/logo192.png
--------------------------------------------------------------------------------
/day-19/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-19/public/logo512.png
--------------------------------------------------------------------------------
/day-19/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-19/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-19/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/day-19/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/day-19/src/containers/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
4 |
5 | // We'll load our views from the `src/views`
6 | // directory
7 | import Home from "./views/Home/Home";
8 | import About from "./views/About/About";
9 |
10 | const App = props => {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | };
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/day-19/src/containers/Root.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Provider } from "react-redux";
3 | import App from "./App";
4 | import configureStore from "../redux/configureStore";
5 |
6 | const Root = props => {
7 | const store = configureStore();
8 | return (
9 |
10 |
11 |
12 | );
13 | };
14 |
15 | export default Root;
16 |
--------------------------------------------------------------------------------
/day-19/src/containers/views/About/About.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | const About = () => (
5 |
6 |
About
7 | Go home
8 |
9 | );
10 |
11 | export default About;
12 |
--------------------------------------------------------------------------------
/day-19/src/containers/views/Home/Home.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import { connect } from "react-redux";
4 |
5 | const mapStateToProps = state => {
6 | return {
7 | currentTime: state.currentTime
8 | };
9 | };
10 |
11 | const Home = props => (
12 |
13 |
Welcome home
14 |
Current time: {props.currentTime}
15 |
Go to about
16 |
17 | );
18 |
19 | export default connect(mapStateToProps)(Home);
20 |
--------------------------------------------------------------------------------
/day-19/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/day-19/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import Root from "./containers/Root";
4 | import "./index.css";
5 |
6 | ReactDOM.render(, document.getElementById("root"));
7 |
--------------------------------------------------------------------------------
/day-19/src/redux/configureStore.js:
--------------------------------------------------------------------------------
1 | import { createStore } from "redux";
2 | import { rootReducer, initialState } from "./reducers";
3 |
4 | export const configureStore = () => {
5 | const store = createStore(
6 | rootReducer, // root reducer
7 | initialState // our initialState
8 | );
9 | return store;
10 | };
11 | export default configureStore;
12 |
--------------------------------------------------------------------------------
/day-19/src/redux/reducers.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 | // Initial (starting) state
3 | export const initialState = {
4 | currentTime: new Date().toString()
5 | };
6 |
7 | // Our root reducer starts with the initial state
8 | // and must return a representation of the next state
9 | export const rootReducer = (state = initialState, action) => {
10 | switch (action.type) {
11 | case types.FETCH_NEW_TIME:
12 | return {
13 | ...state,
14 | currentTime: action.payload
15 | };
16 | default:
17 | return state;
18 | }
19 | };
20 |
--------------------------------------------------------------------------------
/day-19/src/redux/types.js:
--------------------------------------------------------------------------------
1 | export const FETCH_NEW_TIME = "FETCH_NEW_TIME";
2 |
--------------------------------------------------------------------------------
/day-19/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/day-20/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-20/cover.jpg
--------------------------------------------------------------------------------
/day-20/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-20",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.12.0",
10 | "react-dom": "^16.12.0",
11 | "react-redux": "^7.1.3",
12 | "react-router-dom": "^5.1.2",
13 | "react-scripts": "3.3.0",
14 | "redux": "^4.0.4"
15 | },
16 | "scripts": {
17 | "start": "react-scripts start",
18 | "build": "react-scripts build",
19 | "test": "react-scripts test",
20 | "eject": "react-scripts eject"
21 | },
22 | "eslintConfig": {
23 | "extends": "react-app"
24 | },
25 | "browserslist": {
26 | "production": [
27 | ">0.2%",
28 | "not dead",
29 | "not op_mini all"
30 | ],
31 | "development": [
32 | "last 1 chrome version",
33 | "last 1 firefox version",
34 | "last 1 safari version"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/day-20/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-20/public/favicon.ico
--------------------------------------------------------------------------------
/day-20/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-20/public/logo192.png
--------------------------------------------------------------------------------
/day-20/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-20/public/logo512.png
--------------------------------------------------------------------------------
/day-20/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-20/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-20/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/day-20/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/day-20/src/containers/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
4 |
5 | // We'll load our views from the `src/views`
6 | // directory
7 | import Home from "./views/Home/Home";
8 | import About from "./views/About/About";
9 |
10 | const App = props => {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | };
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/day-20/src/containers/Root.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Provider } from "react-redux";
3 | import App from "./App";
4 | import configureStore from "../redux/configureStore";
5 |
6 | const Root = props => {
7 | const store = configureStore();
8 | return (
9 |
10 |
11 |
12 | );
13 | };
14 |
15 | export default Root;
16 |
--------------------------------------------------------------------------------
/day-20/src/containers/views/About/About.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | const About = () => (
5 |
6 |
About
7 | Go home
8 |
9 | );
10 |
11 | export default About;
12 |
--------------------------------------------------------------------------------
/day-20/src/containers/views/Home/Home.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | // import { Link } from "react-router-dom";
3 | import { connect } from "react-redux";
4 | import { fetchNewTime } from "../../../redux/actionCreators";
5 |
6 | const mapStateToProps = state => {
7 | return {
8 | currentTime: state.time.currentTime
9 | };
10 | };
11 |
12 | const mapDispatchToProps = dispatch => ({
13 | updateTime: () => dispatch(fetchNewTime())
14 | });
15 |
16 | const Home = props => (
17 |
18 |
Welcome home
19 |
Current time: {props.currentTime}
20 |
21 | {/*
Go to about */}
22 |
23 | );
24 |
25 | export default connect(mapStateToProps, mapDispatchToProps)(Home);
26 |
--------------------------------------------------------------------------------
/day-20/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/day-20/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import Root from "./containers/Root";
4 | import "./index.css";
5 |
6 | ReactDOM.render(, document.getElementById("root"));
7 |
--------------------------------------------------------------------------------
/day-20/src/redux/actionCreators.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 |
3 | export const fetchNewTime = () => ({
4 | type: types.FETCH_NEW_TIME,
5 | payload: new Date().toString()
6 | });
7 |
8 | export const login = user => ({
9 | type: types.LOGIN,
10 | payload: user
11 | });
12 |
13 | export const logout = () => ({
14 | type: types.LOGOUT
15 | });
16 |
--------------------------------------------------------------------------------
/day-20/src/redux/configureStore.js:
--------------------------------------------------------------------------------
1 | import { createStore, combineReducers } from "redux";
2 |
3 | import { rootReducer, initialState } from "./reducers";
4 | import { reducer, initialState as userInitialState } from "./currentUser";
5 |
6 | export const configureStore = () => {
7 | const store = createStore(
8 | combineReducers({
9 | time: rootReducer,
10 | user: reducer
11 | }), // root reducer
12 | {
13 | time: initialState,
14 | user: userInitialState
15 | } // our initialState
16 | );
17 |
18 | return store;
19 | };
20 |
21 | export default configureStore;
22 |
--------------------------------------------------------------------------------
/day-20/src/redux/currentUser.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 |
3 | export const initialState = {
4 | user: {},
5 | loggedIn: false
6 | };
7 |
8 | export const reducer = (state = initialState, action) => {
9 | switch (action.type) {
10 | case types.LOGIN:
11 | return {
12 | ...state,
13 | user: action.payload,
14 | loggedIn: true
15 | };
16 | case types.LOGOUT:
17 | return {
18 | ...state,
19 | user: {},
20 | loggedIn: false
21 | };
22 | default:
23 | return state;
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/day-20/src/redux/reducers.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 | // Initial (starting) state
3 | export const initialState = {
4 | currentTime: new Date().toString()
5 | };
6 |
7 | // Our root reducer starts with the initial state
8 | // and must return a representation of the next state
9 | export const rootReducer = (state = initialState, action) => {
10 | switch (action.type) {
11 | case types.FETCH_NEW_TIME:
12 | return {
13 | ...state,
14 | currentTime: action.payload
15 | };
16 | default:
17 | return state;
18 | }
19 | };
20 |
--------------------------------------------------------------------------------
/day-20/src/redux/types.js:
--------------------------------------------------------------------------------
1 | export const FETCH_NEW_TIME = "FETCH_NEW_TIME";
2 | export const LOGIN = "USER_LOGIN";
3 | export const LOGOUT = "USER_LOGOUT";
4 |
--------------------------------------------------------------------------------
/day-20/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/day-21/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-21/cover.jpg
--------------------------------------------------------------------------------
/day-21/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-21",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.12.0",
10 | "react-dom": "^16.12.0",
11 | "react-redux": "^7.1.3",
12 | "react-router-dom": "^5.1.2",
13 | "react-scripts": "3.3.0",
14 | "redux": "^4.0.4"
15 | },
16 | "scripts": {
17 | "start": "react-scripts start",
18 | "build": "react-scripts build",
19 | "test": "react-scripts test",
20 | "eject": "react-scripts eject"
21 | },
22 | "eslintConfig": {
23 | "extends": "react-app"
24 | },
25 | "browserslist": {
26 | "production": [
27 | ">0.2%",
28 | "not dead",
29 | "not op_mini all"
30 | ],
31 | "development": [
32 | "last 1 chrome version",
33 | "last 1 firefox version",
34 | "last 1 safari version"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/day-21/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-21/public/favicon.ico
--------------------------------------------------------------------------------
/day-21/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-21/public/logo192.png
--------------------------------------------------------------------------------
/day-21/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-21/public/logo512.png
--------------------------------------------------------------------------------
/day-21/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-21/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-21/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/day-21/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { render } from "@testing-library/react";
3 | import App from "./containers/Root";
4 |
5 | test("renders welcom home text", () => {
6 | const { getByText } = render();
7 | const textElement = getByText(/welcome home/i);
8 | expect(textElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/day-21/src/containers/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
4 |
5 | // We'll load our views from the `src/views`
6 | // directory
7 | import Home from "./views/Home/Home";
8 | import About from "./views/About/About";
9 |
10 | const App = props => {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | };
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/day-21/src/containers/Root.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Provider } from "react-redux";
3 | import App from "./App";
4 | import configureStore from "../redux/configureStore";
5 |
6 | const Root = props => {
7 | const store = configureStore();
8 | return (
9 |
10 |
11 |
12 | );
13 | };
14 |
15 | export default Root;
16 |
--------------------------------------------------------------------------------
/day-21/src/containers/views/About/About.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | const About = () => (
5 |
6 |
About
7 | Go home
8 |
9 | );
10 |
11 | export default About;
12 |
--------------------------------------------------------------------------------
/day-21/src/containers/views/Home/Home.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | // import { Link } from "react-router-dom";
3 | import { connect } from "react-redux";
4 | import { fetchNewTime } from "../../../redux/actionCreators";
5 |
6 | const mapStateToProps = state => {
7 | return {
8 | currentTime: state.currentTime.currentTime
9 | };
10 | };
11 |
12 | const mapDispatchToProps = dispatch => ({
13 | updateTime: () => dispatch(fetchNewTime())
14 | });
15 |
16 | const Home = props => (
17 |
18 |
Welcome home
19 |
Current time: {props.currentTime}
20 |
21 | {/*
Go to about */}
22 |
23 | );
24 |
25 | export default connect(mapStateToProps, mapDispatchToProps)(Home);
26 |
--------------------------------------------------------------------------------
/day-21/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/day-21/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import Root from "./containers/Root";
4 | import "./index.css";
5 |
6 | ReactDOM.render(, document.getElementById("root"));
7 |
--------------------------------------------------------------------------------
/day-21/src/redux/actionCreators.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 |
3 | const host = "https://andthetimeis.com";
4 | export const fetchNewTime = (timezone = "pst", str = "now") => ({
5 | type: types.FETCH_NEW_TIME,
6 | payload: new Date().toString(),
7 | meta: {
8 | type: "api",
9 | url: host + "/" + timezone + "/" + str + ".json"
10 | }
11 | });
12 |
13 | export const login = user => ({
14 | type: types.LOGIN,
15 | payload: user
16 | });
17 |
18 | export const logout = () => ({
19 | type: types.LOGOUT
20 | });
21 |
--------------------------------------------------------------------------------
/day-21/src/redux/apiMiddleware.js:
--------------------------------------------------------------------------------
1 | const apiMiddleware = store => next => action => {
2 | if (!action.meta || action.meta.type !== "api") {
3 | return next(action);
4 | }
5 | // This is an api request
6 |
7 | // Find the request URL and compose request options from meta
8 | const { url } = action.meta;
9 | const fetchOptions = Object.assign({}, action.meta);
10 |
11 | // Make the request
12 | fetch(url, fetchOptions)
13 | // convert the response to json
14 | .then(resp => resp.json())
15 | .then(json => {
16 | if (typeof action.meta.onSuccess === "function") {
17 | action.meta.onSuccess(json);
18 | }
19 | return json; // For the next promise in the chain
20 | })
21 | .then(json => {
22 | // respond back to the user
23 | // by dispatching the original action without
24 | // the meta object
25 | let newAction = Object.assign({}, action, {
26 | payload: json.dateString
27 | });
28 | delete newAction.meta;
29 | store.dispatch(newAction);
30 | });
31 | };
32 |
33 | export default apiMiddleware;
34 |
--------------------------------------------------------------------------------
/day-21/src/redux/configureStore.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from "redux";
2 |
3 | import { rootReducer, initialState } from "./reducers";
4 | import loggingMiddleware from "./loggingMiddleware";
5 | import apiMiddleware from "./apiMiddleware";
6 |
7 | export const configureStore = () => {
8 | const store = createStore(
9 | rootReducer,
10 | initialState,
11 | applyMiddleware(loggingMiddleware, apiMiddleware)
12 | );
13 | return store;
14 | };
15 |
16 | export default configureStore;
17 |
--------------------------------------------------------------------------------
/day-21/src/redux/currentTime.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 |
3 | export const initialState = {
4 | currentTime: new Date().toString()
5 | };
6 |
7 | export const reducer = (state = initialState, action) => {
8 | switch (action.type) {
9 | case types.FETCH_NEW_TIME:
10 | return { ...state, currentTime: action.payload };
11 | default:
12 | return state;
13 | }
14 | };
15 |
16 | export default reducer;
17 |
--------------------------------------------------------------------------------
/day-21/src/redux/currentUser.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 |
3 | export const initialState = {
4 | user: {},
5 | loggedIn: false
6 | };
7 |
8 | export const reducer = (state = initialState, action) => {
9 | switch (action.type) {
10 | case types.LOGIN:
11 | return {
12 | ...state,
13 | user: action.payload,
14 | loggedIn: true
15 | };
16 | case types.LOGOUT:
17 | return {
18 | ...state,
19 | user: {},
20 | loggedIn: false
21 | };
22 | default:
23 | return state;
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/day-21/src/redux/loggingMiddleware.js:
--------------------------------------------------------------------------------
1 | const loggingMiddleware = store => next => action => {
2 | // Our middleware
3 | console.log(`Redux Log:`, action);
4 | // call the next function
5 | next(action);
6 | };
7 |
8 | export default loggingMiddleware;
9 |
--------------------------------------------------------------------------------
/day-21/src/redux/reducers.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from "redux";
2 |
3 | import * as currentUser from "./currentUser";
4 | import * as currentTime from "./currentTime";
5 |
6 | export const rootReducer = combineReducers({
7 | currentTime: currentTime.reducer,
8 | currentUser: currentUser.reducer
9 | });
10 |
11 | export const initialState = {
12 | currentTime: currentTime.initialState,
13 | currentUser: currentUser.initialState
14 | };
15 |
16 | export default rootReducer;
17 |
--------------------------------------------------------------------------------
/day-21/src/redux/types.js:
--------------------------------------------------------------------------------
1 | export const FETCH_NEW_TIME = "FETCH_NEW_TIME";
2 | export const LOGIN = "USER_LOGIN";
3 | export const LOGOUT = "USER_LOGOUT";
4 |
--------------------------------------------------------------------------------
/day-21/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/day-22/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-22/cover.jpg
--------------------------------------------------------------------------------
/day-23/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-23/cover.jpg
--------------------------------------------------------------------------------
/day-23/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-23",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "font-awesome": "^4.7.0",
7 | "moment": "^2.24.0",
8 | "react": "^16.12.0",
9 | "react-dom": "^16.12.0",
10 | "react-scripts": "3.3.0"
11 | },
12 | "scripts": {
13 | "start": "react-scripts start",
14 | "build": "react-scripts build",
15 | "test": "react-scripts test --env=jsdom",
16 | "eject": "react-scripts eject"
17 | },
18 | "eslintConfig": {
19 | "extends": "react-app"
20 | },
21 | "browserslist": {
22 | "production": [
23 | ">0.2%",
24 | "not dead",
25 | "not op_mini all"
26 | ],
27 | "development": [
28 | "last 1 chrome version",
29 | "last 1 firefox version",
30 | "last 1 safari version"
31 | ]
32 | },
33 | "devDependencies": {
34 | "babel-jest": "^24.9.0",
35 | "babel-preset-stage-0": "^6.24.1",
36 | "enzyme": "^3.10.0",
37 | "jest-cli": "^24.9.0",
38 | "react-addons-test-utils": "^15.6.2",
39 | "react-test-renderer": "^16.12.0",
40 | "redux-mock-store": "^1.5.4",
41 | "sinon": "^7.5.0"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/day-23/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-23/public/favicon.ico
--------------------------------------------------------------------------------
/day-23/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-23/public/logo192.png
--------------------------------------------------------------------------------
/day-23/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-23/public/logo512.png
--------------------------------------------------------------------------------
/day-23/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-23/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-23/src/components/Timeline/__tests__/Timeline-test.js:
--------------------------------------------------------------------------------
1 | describe("Timeline", () => {
2 | it("passing test", () => {
3 | expect(true).toBeTruthy();
4 | });
5 |
6 | it("failing test", () => {
7 | expect(false).toBeFalsy();
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/day-23/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import "font-awesome/css/font-awesome.css";
4 |
5 | import Timeline from "./components/Timeline/Timeline";
6 |
7 | export const load = () => {
8 | ReactDOM.render(, document.getElementById("root"));
9 | };
10 |
11 | try {
12 | load();
13 | } catch (e) {}
14 |
--------------------------------------------------------------------------------
/day-24/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-24/cover.jpg
--------------------------------------------------------------------------------
/day-24/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-24",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "font-awesome": "^4.7.0",
7 | "moment": "^2.24.0",
8 | "react": "^16.12.0",
9 | "react-dom": "^16.12.0",
10 | "react-scripts": "3.3.0"
11 | },
12 | "scripts": {
13 | "start": "react-scripts start",
14 | "build": "react-scripts build",
15 | "test": "react-scripts test --env=jsdom",
16 | "eject": "react-scripts eject"
17 | },
18 | "eslintConfig": {
19 | "extends": "react-app"
20 | },
21 | "browserslist": {
22 | "production": [
23 | ">0.2%",
24 | "not dead",
25 | "not op_mini all"
26 | ],
27 | "development": [
28 | "last 1 chrome version",
29 | "last 1 firefox version",
30 | "last 1 safari version"
31 | ]
32 | },
33 | "devDependencies": {
34 | "babel-jest": "^24.9.0",
35 | "babel-preset-stage-0": "^6.24.1",
36 | "enzyme": "^3.10.0",
37 | "jest-cli": "^24.9.0",
38 | "react-addons-test-utils": "^15.6.2",
39 | "react-test-renderer": "^16.12.0",
40 | "redux-mock-store": "^1.5.4",
41 | "sinon": "^7.5.0"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/day-24/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-24/public/favicon.ico
--------------------------------------------------------------------------------
/day-24/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-24/public/logo192.png
--------------------------------------------------------------------------------
/day-24/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-24/public/logo512.png
--------------------------------------------------------------------------------
/day-24/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-24/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-24/src/components/Timeline/__tests__/Timeline-test.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import TestUtils from "react-dom/test-utils";
3 | import Timeline from "../Timeline";
4 |
5 | describe("Timeline", () => {
6 | it("wraps content in a div with .notificationsFrame class", () => {
7 | const wrapper = TestUtils.renderIntoDocument();
8 | const node = TestUtils.findRenderedDOMComponentWithClass(
9 | wrapper,
10 | "notificationsFrame"
11 | );
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/day-24/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import "font-awesome/css/font-awesome.css";
4 |
5 | import Timeline from "./components/Timeline/Timeline";
6 |
7 | export const load = () => {
8 | ReactDOM.render(, document.getElementById("root"));
9 | };
10 |
11 | try {
12 | load();
13 | } catch (e) {}
14 |
--------------------------------------------------------------------------------
/day-25/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-25/cover.jpg
--------------------------------------------------------------------------------
/day-25/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-25",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "font-awesome": "^4.7.0",
7 | "moment": "^2.24.0",
8 | "react": "^16.12.0",
9 | "react-dom": "^16.12.0",
10 | "react-scripts": "3.3.0"
11 | },
12 | "scripts": {
13 | "start": "react-scripts start",
14 | "build": "react-scripts build",
15 | "test": "react-scripts test --env=jsdom",
16 | "eject": "react-scripts eject"
17 | },
18 | "eslintConfig": {
19 | "extends": "react-app"
20 | },
21 | "browserslist": {
22 | "production": [
23 | ">0.2%",
24 | "not dead",
25 | "not op_mini all"
26 | ],
27 | "development": [
28 | "last 1 chrome version",
29 | "last 1 firefox version",
30 | "last 1 safari version"
31 | ]
32 | },
33 | "devDependencies": {
34 | "babel-jest": "^24.9.0",
35 | "babel-preset-stage-0": "^6.24.1",
36 | "enzyme": "^3.10.0",
37 | "enzyme-adapter-react-16": "^1.15.1",
38 | "jest-cli": "^24.9.0",
39 | "react-addons-test-utils": "^15.6.2",
40 | "react-test-renderer": "^16.12.0",
41 | "redux-mock-store": "^1.5.4",
42 | "sinon": "^7.5.0"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/day-25/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-25/public/favicon.ico
--------------------------------------------------------------------------------
/day-25/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-25/public/logo192.png
--------------------------------------------------------------------------------
/day-25/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-25/public/logo512.png
--------------------------------------------------------------------------------
/day-25/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-25/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-25/src/components/Timeline/ActivityItem.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import './Timeline.css'
3 |
4 | export class ActivityItem extends React.Component {
5 | render() {
6 | const { activity } = this.props;
7 |
8 | return (
9 |
10 |
11 |

14 | {activity.user.name}
15 |
16 |
17 |
18 | {activity.timestamp}
19 |
20 |
21 |
{activity.text}
22 |
23 | {activity.comments.length}
24 |
25 |
26 | )
27 | }
28 | }
29 |
30 | export default ActivityItem
--------------------------------------------------------------------------------
/day-25/src/components/Timeline/Timeline.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import Header from "./Header";
4 | import ActivityItem from "./ActivityItem";
5 | import "./Timeline.css";
6 |
7 | // Could be fetched from a server
8 | const activities = require("../../data.json");
9 |
10 | // Don't do it like this. This is for example only
11 | class Timeline extends React.Component {
12 | render() {
13 | return (
14 |
15 |
16 |
17 |
18 |
19 |
20 | {activities &&
21 | activities.map(activity => (
22 |
23 | ))}
24 |
25 |
26 |
27 | );
28 | }
29 | }
30 |
31 | export default Timeline;
32 |
--------------------------------------------------------------------------------
/day-25/src/components/Timeline/__tests__/Timeline-test-test-utils.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import TestUtils from "react-dom/test-utils";
3 |
4 | import Timeline from "../Timeline";
5 |
6 | describe("Timeline", () => {
7 | it("wraps content in a div with .notificationsFrame class", () => {
8 | const wrapper = TestUtils.renderIntoDocument();
9 | TestUtils.findRenderedDOMComponentWithClass(wrapper, "notificationsFrame");
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/day-25/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import "font-awesome/css/font-awesome.css";
4 |
5 | import Timeline from "./components/Timeline/Timeline";
6 |
7 | export const load = () => {
8 | ReactDOM.render(, document.getElementById("root"));
9 | };
10 |
11 | try {
12 | load();
13 | } catch (e) {
14 | console.log(e);
15 | }
16 |
--------------------------------------------------------------------------------
/day-25/src/setupTests.js:
--------------------------------------------------------------------------------
1 | import { configure } from "enzyme";
2 | import Adapter from "enzyme-adapter-react-16";
3 |
4 | configure({ adapter: new Adapter() });
5 |
--------------------------------------------------------------------------------
/day-26/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-26/cover.jpg
--------------------------------------------------------------------------------
/day-26/nightwatch.json:
--------------------------------------------------------------------------------
1 | {
2 | "src_folders": ["tests"],
3 | "output_folder": "reports",
4 |
5 | "selenium": {
6 | "start_process": false,
7 | "server_path": "",
8 | "log_path": "",
9 | "host": "127.0.0.1",
10 | "port": 4444,
11 | "cli_args": {
12 | "webdriver.chrome.driver": "",
13 | "webdriver.ie.driver": ""
14 | }
15 | },
16 |
17 | "test_settings": {
18 | "default": {
19 | "launch_url": "http://localhost:3000",
20 | "selenium_port": 4444,
21 | "selenium_host": "localhost",
22 | "silent": true,
23 | "screenshots": {
24 | "enabled": false,
25 | "path": ""
26 | },
27 | "desiredCapabilities": {
28 | "browserName": "chrome",
29 | "javascriptEnabled": true,
30 | "acceptSslCerts": true,
31 | "chromeOptions": {
32 | "w3c": false
33 | }
34 | }
35 | },
36 |
37 | "chrome": {
38 | "desiredCapabilities": {
39 | "browserName": "chrome",
40 | "javascriptEnabled": true,
41 | "acceptSslCerts": true
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/day-26/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "day-26",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "font-awesome": "^4.7.0",
10 | "nightwatch": "^1.3.2",
11 | "react": "^16.12.0",
12 | "react-dom": "^16.12.0",
13 | "react-redux": "^7.1.3",
14 | "react-router-dom": "^5.1.2",
15 | "react-scripts": "3.3.0",
16 | "redux": "^4.0.4"
17 | },
18 | "scripts": {
19 | "start": "react-scripts start",
20 | "build": "react-scripts build",
21 | "test": "react-scripts test",
22 | "eject": "react-scripts eject"
23 | },
24 | "eslintConfig": {
25 | "extends": "react-app"
26 | },
27 | "browserslist": {
28 | "production": [
29 | ">0.2%",
30 | "not dead",
31 | "not op_mini all"
32 | ],
33 | "development": [
34 | "last 1 chrome version",
35 | "last 1 firefox version",
36 | "last 1 safari version"
37 | ]
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/day-26/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-26/public/favicon.ico
--------------------------------------------------------------------------------
/day-26/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | React App
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/day-26/reports/CHROME_57.0.2987.133_MAC_auth-flow.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/day-26/reports/CHROME_79.0.3945.79_Linux_auth-flow.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/day-26/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/day-26/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | });
9 |
--------------------------------------------------------------------------------
/day-26/src/Root.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Provider } from 'react-redux';
3 | import configureStore from './redux/configureStore';
4 | import App from './App';
5 |
6 | export const Root = props => {
7 | const store = configureStore();
8 | return (
9 |
10 |
13 |
14 | )
15 | }
16 |
17 | export default Root;
--------------------------------------------------------------------------------
/day-26/src/components/Form/Form.js:
--------------------------------------------------------------------------------
1 | import React, { Children as C, Component } from 'react';
2 |
3 | class Form extends Component {
4 | state = { fields: {} }
5 |
6 | handleChange = (key, value) => {
7 | const fields = {
8 | ...this.state.fields,
9 | [key]: value
10 | }
11 | this.setState({
12 | fields
13 | })
14 | }
15 |
16 | handleSubmit = e => {
17 | e.preventDefault()
18 | this.props.onSubmit(this.state.fields)
19 | }
20 |
21 | render() {
22 | return (
23 |
32 | )
33 | }
34 | }
35 |
36 | export default Form
--------------------------------------------------------------------------------
/day-26/src/components/Form/Input.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const Input = ({ onChange, name, type, ...rest }) => {
4 | return (
5 |
6 | onChange(name, e.target.value)}
9 | placeholder={name} />
10 |
11 | )
12 | }
13 |
14 | export default Input
--------------------------------------------------------------------------------
/day-26/src/components/Nav/Navbar.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | Link
4 | } from 'react-router-dom';
5 |
6 | export const Navbar = ({ auth, logout, ...rest }) => {
7 |
8 | return (
9 |
10 |
11 |
12 | Logo
13 |
14 |
15 | {
16 | auth.isLoggedIn ? (
17 |
18 | Logout
19 |
20 | ) : (
21 |
22 | Login please
23 |
24 | )
25 | }
26 |
27 | About
28 |
29 |
30 |
31 | )
32 | }
33 |
34 | export default Navbar
--------------------------------------------------------------------------------
/day-26/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import 'font-awesome/css/font-awesome.css';
5 |
6 | import Root from './Root';
7 |
8 | export const load = () => {
9 | ReactDOM.render(, document.getElementById('demo1'));
10 | };
11 |
12 | try {
13 | load();
14 | } catch (e) {
15 | console.log(e);
16 | }
17 |
--------------------------------------------------------------------------------
/day-26/src/redux/actions/auth.js:
--------------------------------------------------------------------------------
1 | import * as types from '../types';
2 |
3 | export const tryLogin = ({ username, password }) => {
4 | if (username === 'admin' && password === 'secret') {
5 | return {
6 | type: types.LOGIN_SUCCESS,
7 | payload: { username, password }
8 | }
9 | } else {
10 | return {
11 | type: types.LOGIN_FAILURE,
12 | payload: 'Invalid username or password'
13 | }
14 | }
15 | }
16 |
17 | export const tryLogout = () => ({
18 | type: types.LOGOUT
19 | })
--------------------------------------------------------------------------------
/day-26/src/redux/configureStore.js:
--------------------------------------------------------------------------------
1 | import { createStore } from 'redux';
2 | import { rootReducer, initialState } from './reducers';
3 |
4 | export const configureStore = () => {
5 | const store = createStore(
6 | rootReducer,
7 | initialState,
8 | )
9 |
10 | return store;
11 | }
12 |
13 | export default configureStore
--------------------------------------------------------------------------------
/day-26/src/redux/reducers/auth.js:
--------------------------------------------------------------------------------
1 | import * as types from '../types';
2 |
3 | export const initialState = {
4 | isLoggedIn: false,
5 | userData: null,
6 | pending: false,
7 | errors: null
8 | };
9 |
10 | export const reducer = (state = initialState, action) => {
11 | switch (action.type) {
12 | case types.TRY_LOGIN:
13 | return { ...state, pending: true }
14 | case types.LOGIN_SUCCESS:
15 | return {
16 | ...state,
17 | pending: false,
18 | isLoggedIn: true,
19 | userData: action.payload,
20 | errors: null,
21 | }
22 | case types.LOGIN_FAILURE:
23 | return {
24 | ...state,
25 | pending: false,
26 | isLoggedIn: false,
27 | userData: null,
28 | errors: action.payload,
29 | }
30 | case types.LOGOUT:
31 | return {
32 | ...state, pending: false, isLoggedIn: false, userData: null
33 | }
34 | default:
35 | return state;
36 | }
37 | }
--------------------------------------------------------------------------------
/day-26/src/redux/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 |
3 | import * as auth from './auth';
4 |
5 | export const initialState = {
6 | auth: auth.initialState,
7 | }
8 |
9 | export const rootReducer = combineReducers({
10 | auth: auth.reducer
11 | })
--------------------------------------------------------------------------------
/day-26/src/redux/types.js:
--------------------------------------------------------------------------------
1 | export const TRY_LOGIN = 'AUTH_TRY_LOGIN';
2 | export const LOGIN_SUCCESS = 'AUTH_LOGIN_SUCCESS';
3 | export const LOGIN_FAILURE = 'AUTH_LOGIN_FAILURE';
4 | export const LOGOUT = 'AUTH_LOGOUT';
5 |
--------------------------------------------------------------------------------
/day-26/src/views/About.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const About = (props) => (
4 |
5 |
About us
6 |
7 | )
8 |
9 | export default About
--------------------------------------------------------------------------------
/day-26/src/views/Home.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export const Home = ({ auth }) => (
4 |
5 |
{auth.isLoggedIn ? "Welcome home!" : "You need to know the secret"}
6 |
7 | );
8 |
9 | export default Home;
10 |
--------------------------------------------------------------------------------
/day-27/config/development.config.env:
--------------------------------------------------------------------------------
1 | TIME_SERVER='https://fullstacktime.herokuapp.com'
--------------------------------------------------------------------------------
/day-27/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/en/webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/day-27/config/pnpTs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const { resolveModuleName } = require('ts-pnp');
4 |
5 | exports.resolveModuleName = (
6 | typescript,
7 | moduleName,
8 | containingFile,
9 | compilerOptions,
10 | resolutionHost
11 | ) => {
12 | return resolveModuleName(
13 | moduleName,
14 | containingFile,
15 | compilerOptions,
16 | resolutionHost,
17 | typescript.resolveModuleName
18 | );
19 | };
20 |
21 | exports.resolveTypeReferenceDirective = (
22 | typescript,
23 | moduleName,
24 | containingFile,
25 | compilerOptions,
26 | resolutionHost
27 | ) => {
28 | return resolveModuleName(
29 | moduleName,
30 | containingFile,
31 | compilerOptions,
32 | resolutionHost,
33 | typescript.resolveTypeReferenceDirective
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/day-27/config/production.config.env:
--------------------------------------------------------------------------------
1 | TIME_SERVER='https://fullstacktime.herokuapp.com'
--------------------------------------------------------------------------------
/day-27/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-27/cover.jpg
--------------------------------------------------------------------------------
/day-27/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-27/public/favicon.ico
--------------------------------------------------------------------------------
/day-27/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-27/public/logo192.png
--------------------------------------------------------------------------------
/day-27/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-27/public/logo512.png
--------------------------------------------------------------------------------
/day-27/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-27/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-27/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/day-27/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { render } from "@testing-library/react";
3 | import App from "./containers/Root";
4 |
5 | test("renders welcom home text", () => {
6 | const { getByText } = render();
7 | const textElement = getByText(/welcome home/i);
8 | expect(textElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/day-27/src/containers/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
4 |
5 | // We'll load our views from the `src/views`
6 | // directory
7 | import Home from "./views/Home/Home";
8 | import About from "./views/About/About";
9 |
10 | const App = props => {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | };
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/day-27/src/containers/Root.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Provider } from "react-redux";
3 | import App from "./App";
4 | import configureStore from "../redux/configureStore";
5 |
6 | const Root = props => {
7 | const store = configureStore();
8 | return (
9 |
10 |
11 |
12 | );
13 | };
14 |
15 | export default Root;
16 |
--------------------------------------------------------------------------------
/day-27/src/containers/views/About/About.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | const About = () => (
5 |
6 |
About
7 | Go home
8 |
9 | );
10 |
11 | export default About;
12 |
--------------------------------------------------------------------------------
/day-27/src/containers/views/Home/Home.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | // import { Link } from "react-router-dom";
3 | import { connect } from "react-redux";
4 | import { fetchNewTime } from "../../../redux/actionCreators";
5 |
6 | const mapStateToProps = state => {
7 | return {
8 | currentTime: state.currentTime.currentTime
9 | };
10 | };
11 |
12 | const mapDispatchToProps = dispatch => ({
13 | updateTime: () => dispatch(fetchNewTime())
14 | });
15 |
16 | const Home = props => (
17 |
18 |
Welcome home
19 |
Current time: {props.currentTime}
20 |
21 | {/*
Go to about */}
22 |
23 | );
24 |
25 | export default connect(mapStateToProps, mapDispatchToProps)(Home);
26 |
--------------------------------------------------------------------------------
/day-27/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/day-27/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import Root from "./containers/Root";
4 | import "./index.css";
5 |
6 | ReactDOM.render(, document.getElementById("root"));
7 |
--------------------------------------------------------------------------------
/day-27/src/redux/actionCreators.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 |
3 | // const host = "https://andthetimeis.com";
4 | const host = process.env.TIME_SERVER;
5 | export const fetchNewTime = (timezone = "pst", str = "now") => ({
6 | type: types.FETCH_NEW_TIME,
7 | payload: new Date().toString(),
8 | meta: {
9 | type: "api",
10 | url: host + "/" + timezone + "/" + str + ".json"
11 | }
12 | });
13 |
14 | export const login = user => ({
15 | type: types.LOGIN,
16 | payload: user
17 | });
18 |
19 | export const logout = () => ({
20 | type: types.LOGOUT
21 | });
22 |
--------------------------------------------------------------------------------
/day-27/src/redux/apiMiddleware.js:
--------------------------------------------------------------------------------
1 | const apiMiddleware = store => next => action => {
2 | if (!action.meta || action.meta.type !== "api") {
3 | return next(action);
4 | }
5 | // This is an api request
6 |
7 | // Find the request URL and compose request options from meta
8 | const { url } = action.meta;
9 | const fetchOptions = Object.assign({}, action.meta);
10 |
11 | // Make the request
12 | fetch(url, fetchOptions)
13 | // convert the response to json
14 | .then(resp => resp.json())
15 | .then(json => {
16 | if (typeof action.meta.onSuccess === "function") {
17 | action.meta.onSuccess(json);
18 | }
19 | return json; // For the next promise in the chain
20 | })
21 | .then(json => {
22 | // respond back to the user
23 | // by dispatching the original action without
24 | // the meta object
25 | let newAction = Object.assign({}, action, {
26 | payload: json.dateString
27 | });
28 | delete newAction.meta;
29 | store.dispatch(newAction);
30 | });
31 | };
32 |
33 | export default apiMiddleware;
34 |
--------------------------------------------------------------------------------
/day-27/src/redux/configureStore.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from "redux";
2 |
3 | import { rootReducer, initialState } from "./reducers";
4 | import loggingMiddleware from "./loggingMiddleware";
5 | import apiMiddleware from "./apiMiddleware";
6 |
7 | let middleware = [apiMiddleware];
8 |
9 | if ("development" === process.env.NODE_ENV) {
10 | middleware.unshift(loggingMiddleware);
11 | }
12 |
13 | export const configureStore = () => {
14 | const store = createStore(
15 | rootReducer,
16 | initialState,
17 | applyMiddleware(...middleware)
18 | );
19 | return store;
20 | };
21 |
22 | export default configureStore;
23 |
--------------------------------------------------------------------------------
/day-27/src/redux/currentTime.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 |
3 | export const initialState = {
4 | currentTime: new Date().toString()
5 | };
6 |
7 | export const reducer = (state = initialState, action) => {
8 | switch (action.type) {
9 | case types.FETCH_NEW_TIME:
10 | return { ...state, currentTime: action.payload };
11 | default:
12 | return state;
13 | }
14 | };
15 |
16 | export default reducer;
17 |
--------------------------------------------------------------------------------
/day-27/src/redux/currentUser.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 |
3 | export const initialState = {
4 | user: {},
5 | loggedIn: false
6 | };
7 |
8 | export const reducer = (state = initialState, action) => {
9 | switch (action.type) {
10 | case types.LOGIN:
11 | return {
12 | ...state,
13 | user: action.payload,
14 | loggedIn: true
15 | };
16 | case types.LOGOUT:
17 | return {
18 | ...state,
19 | user: {},
20 | loggedIn: false
21 | };
22 | default:
23 | return state;
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/day-27/src/redux/loggingMiddleware.js:
--------------------------------------------------------------------------------
1 | const loggingMiddleware = store => next => action => {
2 | // Our middleware
3 | console.log(`Redux Log:`, action);
4 | // call the next function
5 | next(action);
6 | };
7 |
8 | export default loggingMiddleware;
9 |
--------------------------------------------------------------------------------
/day-27/src/redux/reducers.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from "redux";
2 |
3 | import * as currentUser from "./currentUser";
4 | import * as currentTime from "./currentTime";
5 |
6 | export const rootReducer = combineReducers({
7 | currentTime: currentTime.reducer,
8 | currentUser: currentUser.reducer
9 | });
10 |
11 | export const initialState = {
12 | currentTime: currentTime.initialState,
13 | currentUser: currentUser.initialState
14 | };
15 |
16 | export default rootReducer;
17 |
--------------------------------------------------------------------------------
/day-27/src/redux/types.js:
--------------------------------------------------------------------------------
1 | export const FETCH_NEW_TIME = "FETCH_NEW_TIME";
2 | export const LOGIN = "USER_LOGIN";
3 | export const LOGOUT = "USER_LOGOUT";
4 |
--------------------------------------------------------------------------------
/day-27/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/day-28/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-28/cover.jpg
--------------------------------------------------------------------------------
/day-29/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "10.15.0"
4 | before_deploy:
5 | - npm run build
6 | deploy:
7 | provider: script
8 | skip_cleanup: true
9 | script: sh scripts/deploy.sh
10 | on:
11 | branch: master
12 |
--------------------------------------------------------------------------------
/day-29/config/development.config.env:
--------------------------------------------------------------------------------
1 | TIME_SERVER='https://fullstacktime.herokuapp.com'
--------------------------------------------------------------------------------
/day-29/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/en/webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/day-29/config/pnpTs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const { resolveModuleName } = require('ts-pnp');
4 |
5 | exports.resolveModuleName = (
6 | typescript,
7 | moduleName,
8 | containingFile,
9 | compilerOptions,
10 | resolutionHost
11 | ) => {
12 | return resolveModuleName(
13 | moduleName,
14 | containingFile,
15 | compilerOptions,
16 | resolutionHost,
17 | typescript.resolveModuleName
18 | );
19 | };
20 |
21 | exports.resolveTypeReferenceDirective = (
22 | typescript,
23 | moduleName,
24 | containingFile,
25 | compilerOptions,
26 | resolutionHost
27 | ) => {
28 | return resolveModuleName(
29 | moduleName,
30 | containingFile,
31 | compilerOptions,
32 | resolutionHost,
33 | typescript.resolveTypeReferenceDirective
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/day-29/config/production.config.env:
--------------------------------------------------------------------------------
1 | TIME_SERVER='https://fullstacktime.herokuapp.com'
--------------------------------------------------------------------------------
/day-29/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-29/cover.jpg
--------------------------------------------------------------------------------
/day-29/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-29/public/favicon.ico
--------------------------------------------------------------------------------
/day-29/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-29/public/logo192.png
--------------------------------------------------------------------------------
/day-29/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-29/public/logo512.png
--------------------------------------------------------------------------------
/day-29/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/day-29/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/day-29/scripts/deploy.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | surge -p build --domain https://healthy-pail.surge.sh/
--------------------------------------------------------------------------------
/day-29/scripts/release.js:
--------------------------------------------------------------------------------
1 | process.env.NODE_ENV = "test";
2 | process.env.CI = true;
3 |
4 | var chalk = require("chalk");
5 | const exec = require("child_process").exec;
6 |
7 | var output = [];
8 |
9 | function runCmd(cmd) {
10 | return new Promise((resolve, reject) => {
11 | const testProcess = exec(cmd, { stdio: [0, 1, 2] });
12 | testProcess.stdout.on("data", msg => output.push(msg));
13 | testProcess.stderr.on("data", msg => output.push(msg));
14 | testProcess.on("close", code => (code === 0 ? resolve() : reject()));
15 | });
16 | }
17 |
18 | function build() {
19 | console.log(chalk.cyan("Building app"));
20 | return runCmd("npm run build");
21 | }
22 |
23 | function runTests() {
24 | console.log(chalk.cyan("Running tests..."));
25 | return runCmd("npm test");
26 | }
27 |
28 | function deploy() {
29 | console.log(chalk.green("Deploying..."));
30 | return runCmd(`sh -c "${__dirname}/deploy.sh"`);
31 | }
32 |
33 | function error() {
34 | console.log(chalk.red("There was an error"));
35 | output.forEach(msg => process.stdout.write(msg));
36 | }
37 |
38 | build()
39 | .then(runTests)
40 | .then(deploy)
41 | .catch(error);
42 |
--------------------------------------------------------------------------------
/day-29/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/day-29/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { render } from "@testing-library/react";
3 | import App from "./containers/Root";
4 |
5 | test("renders welcom home text", () => {
6 | const { getByText } = render();
7 | const textElement = getByText(/welcome home/i);
8 | expect(textElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/day-29/src/containers/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
4 |
5 | // We'll load our views from the `src/views`
6 | // directory
7 | import Home from "./views/Home/Home";
8 | import About from "./views/About/About";
9 |
10 | const App = props => {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | };
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/day-29/src/containers/Root.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Provider } from "react-redux";
3 | import App from "./App";
4 | import configureStore from "../redux/configureStore";
5 |
6 | const Root = props => {
7 | const store = configureStore();
8 | return (
9 |
10 |
11 |
12 | );
13 | };
14 |
15 | export default Root;
16 |
--------------------------------------------------------------------------------
/day-29/src/containers/views/About/About.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | const About = () => (
5 |
6 |
About
7 | Go home
8 |
9 | );
10 |
11 | export default About;
12 |
--------------------------------------------------------------------------------
/day-29/src/containers/views/Home/Home.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | // import { Link } from "react-router-dom";
3 | import { connect } from "react-redux";
4 | import { fetchNewTime } from "../../../redux/actionCreators";
5 |
6 | const mapStateToProps = state => {
7 | return {
8 | currentTime: state.currentTime.currentTime
9 | };
10 | };
11 |
12 | const mapDispatchToProps = dispatch => ({
13 | updateTime: () => dispatch(fetchNewTime())
14 | });
15 |
16 | const Home = props => (
17 |
18 |
Welcome home
19 |
Current time: {props.currentTime}
20 |
21 | {/*
Go to about */}
22 |
23 | );
24 |
25 | export default connect(mapStateToProps, mapDispatchToProps)(Home);
26 |
--------------------------------------------------------------------------------
/day-29/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/day-29/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import Root from "./containers/Root";
4 | import "./index.css";
5 |
6 | ReactDOM.render(, document.getElementById("root"));
7 |
--------------------------------------------------------------------------------
/day-29/src/redux/actionCreators.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 |
3 | // const host = "https://andthetimeis.com";
4 | const host = process.env.TIME_SERVER;
5 | export const fetchNewTime = (timezone = "pst", str = "now") => ({
6 | type: types.FETCH_NEW_TIME,
7 | payload: new Date().toString(),
8 | meta: {
9 | type: "api",
10 | url: host + "/" + timezone + "/" + str + ".json"
11 | }
12 | });
13 |
14 | export const login = user => ({
15 | type: types.LOGIN,
16 | payload: user
17 | });
18 |
19 | export const logout = () => ({
20 | type: types.LOGOUT
21 | });
22 |
--------------------------------------------------------------------------------
/day-29/src/redux/apiMiddleware.js:
--------------------------------------------------------------------------------
1 | const apiMiddleware = store => next => action => {
2 | if (!action.meta || action.meta.type !== "api") {
3 | return next(action);
4 | }
5 | // This is an api request
6 |
7 | // Find the request URL and compose request options from meta
8 | const { url } = action.meta;
9 | const fetchOptions = Object.assign({}, action.meta);
10 |
11 | // Make the request
12 | fetch(url, fetchOptions)
13 | // convert the response to json
14 | .then(resp => resp.json())
15 | .then(json => {
16 | if (typeof action.meta.onSuccess === "function") {
17 | action.meta.onSuccess(json);
18 | }
19 | return json; // For the next promise in the chain
20 | })
21 | .then(json => {
22 | // respond back to the user
23 | // by dispatching the original action without
24 | // the meta object
25 | let newAction = Object.assign({}, action, {
26 | payload: json.dateString
27 | });
28 | delete newAction.meta;
29 | store.dispatch(newAction);
30 | });
31 | };
32 |
33 | export default apiMiddleware;
34 |
--------------------------------------------------------------------------------
/day-29/src/redux/configureStore.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from "redux";
2 |
3 | import { rootReducer, initialState } from "./reducers";
4 | import loggingMiddleware from "./loggingMiddleware";
5 | import apiMiddleware from "./apiMiddleware";
6 |
7 | let middleware = [apiMiddleware];
8 |
9 | if ("development" === process.env.NODE_ENV) {
10 | middleware.unshift(loggingMiddleware);
11 | }
12 |
13 | export const configureStore = () => {
14 | const store = createStore(
15 | rootReducer,
16 | initialState,
17 | applyMiddleware(...middleware)
18 | );
19 | return store;
20 | };
21 |
22 | export default configureStore;
23 |
--------------------------------------------------------------------------------
/day-29/src/redux/currentTime.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 |
3 | export const initialState = {
4 | currentTime: new Date().toString()
5 | };
6 |
7 | export const reducer = (state = initialState, action) => {
8 | switch (action.type) {
9 | case types.FETCH_NEW_TIME:
10 | return { ...state, currentTime: action.payload };
11 | default:
12 | return state;
13 | }
14 | };
15 |
16 | export default reducer;
17 |
--------------------------------------------------------------------------------
/day-29/src/redux/currentUser.js:
--------------------------------------------------------------------------------
1 | import * as types from "./types";
2 |
3 | export const initialState = {
4 | user: {},
5 | loggedIn: false
6 | };
7 |
8 | export const reducer = (state = initialState, action) => {
9 | switch (action.type) {
10 | case types.LOGIN:
11 | return {
12 | ...state,
13 | user: action.payload,
14 | loggedIn: true
15 | };
16 | case types.LOGOUT:
17 | return {
18 | ...state,
19 | user: {},
20 | loggedIn: false
21 | };
22 | default:
23 | return state;
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/day-29/src/redux/loggingMiddleware.js:
--------------------------------------------------------------------------------
1 | const loggingMiddleware = store => next => action => {
2 | // Our middleware
3 | console.log(`Redux Log:`, action);
4 | // call the next function
5 | next(action);
6 | };
7 |
8 | export default loggingMiddleware;
9 |
--------------------------------------------------------------------------------
/day-29/src/redux/reducers.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from "redux";
2 |
3 | import * as currentUser from "./currentUser";
4 | import * as currentTime from "./currentTime";
5 |
6 | export const rootReducer = combineReducers({
7 | currentTime: currentTime.reducer,
8 | currentUser: currentUser.reducer
9 | });
10 |
11 | export const initialState = {
12 | currentTime: currentTime.initialState,
13 | currentUser: currentUser.initialState
14 | };
15 |
16 | export default rootReducer;
17 |
--------------------------------------------------------------------------------
/day-29/src/redux/types.js:
--------------------------------------------------------------------------------
1 | export const FETCH_NEW_TIME = "FETCH_NEW_TIME";
2 | export const LOGIN = "USER_LOGIN";
3 | export const LOGOUT = "USER_LOGOUT";
4 |
--------------------------------------------------------------------------------
/day-29/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/day-30/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/day-30/cover.jpg
--------------------------------------------------------------------------------
/images/04/breakdown-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/04/breakdown-2.jpg
--------------------------------------------------------------------------------
/images/04/breakdown-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/04/breakdown-2.png
--------------------------------------------------------------------------------
/images/04/breakdown.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/04/breakdown.jpg
--------------------------------------------------------------------------------
/images/04/breakdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/04/breakdown.png
--------------------------------------------------------------------------------
/images/04/part4.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/04/part4.sketch
--------------------------------------------------------------------------------
/images/12/app.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/app.jpg
--------------------------------------------------------------------------------
/images/12/app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/app.png
--------------------------------------------------------------------------------
/images/12/build.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/build.jpg
--------------------------------------------------------------------------------
/images/12/build.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/build.png
--------------------------------------------------------------------------------
/images/12/chrome-start.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/chrome-start.jpg
--------------------------------------------------------------------------------
/images/12/chrome-start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/chrome-start.png
--------------------------------------------------------------------------------
/images/12/create-app.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/create-app.jpg
--------------------------------------------------------------------------------
/images/12/create-app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/create-app.png
--------------------------------------------------------------------------------
/images/12/index-html.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/index-html.jpg
--------------------------------------------------------------------------------
/images/12/index-html.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/index-html.png
--------------------------------------------------------------------------------
/images/12/install-create-react-app.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/install-create-react-app.jpg
--------------------------------------------------------------------------------
/images/12/install-create-react-app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/install-create-react-app.png
--------------------------------------------------------------------------------
/images/12/npm-start.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/npm-start.jpg
--------------------------------------------------------------------------------
/images/12/npm-start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/npm-start.png
--------------------------------------------------------------------------------
/images/12/tree.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/tree.jpg
--------------------------------------------------------------------------------
/images/12/tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/12/tree.png
--------------------------------------------------------------------------------
/images/13/children-map.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/13/children-map.jpg
--------------------------------------------------------------------------------
/images/13/children-map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/13/children-map.png
--------------------------------------------------------------------------------
/images/13/run-no-key.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/13/run-no-key.jpg
--------------------------------------------------------------------------------
/images/13/run-no-key.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/13/run-no-key.png
--------------------------------------------------------------------------------
/images/14/install-fetch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/14/install-fetch.jpg
--------------------------------------------------------------------------------
/images/14/install-fetch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/14/install-fetch.png
--------------------------------------------------------------------------------
/images/17/install-react-router.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/17/install-react-router.jpg
--------------------------------------------------------------------------------
/images/17/install-react-router.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/17/install-react-router.png
--------------------------------------------------------------------------------
/images/19/home-time.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/19/home-time.jpg
--------------------------------------------------------------------------------
/images/19/home-time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/19/home-time.png
--------------------------------------------------------------------------------
/images/19/install-redux.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/19/install-redux.jpg
--------------------------------------------------------------------------------
/images/19/install-redux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/19/install-redux.png
--------------------------------------------------------------------------------
/images/19/no-reducer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/19/no-reducer.jpg
--------------------------------------------------------------------------------
/images/19/no-reducer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/19/no-reducer.png
--------------------------------------------------------------------------------
/images/19/structure.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/19/structure.jpg
--------------------------------------------------------------------------------
/images/19/structure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/19/structure.png
--------------------------------------------------------------------------------
/images/20/home-time.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/20/home-time.jpg
--------------------------------------------------------------------------------
/images/20/home-time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/20/home-time.png
--------------------------------------------------------------------------------
/images/20/login-logout.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/20/login-logout.gif
--------------------------------------------------------------------------------
/images/23/first-tests.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/23/first-tests.jpg
--------------------------------------------------------------------------------
/images/23/first-tests.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/23/first-tests.png
--------------------------------------------------------------------------------
/images/23/second-tests.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/23/second-tests.jpg
--------------------------------------------------------------------------------
/images/23/second-tests.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/23/second-tests.png
--------------------------------------------------------------------------------
/images/24/failing-test-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/24/failing-test-1.jpg
--------------------------------------------------------------------------------
/images/24/failing-test-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/24/failing-test-1.png
--------------------------------------------------------------------------------
/images/24/failing-test-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/24/failing-test-2.jpg
--------------------------------------------------------------------------------
/images/24/failing-test-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/24/failing-test-2.png
--------------------------------------------------------------------------------
/images/24/navbar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/24/navbar.jpg
--------------------------------------------------------------------------------
/images/24/navbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/24/navbar.png
--------------------------------------------------------------------------------
/images/24/passing-test-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/24/passing-test-1.jpg
--------------------------------------------------------------------------------
/images/24/passing-test-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/24/passing-test-1.png
--------------------------------------------------------------------------------
/images/24/passing-test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/24/passing-test.png
--------------------------------------------------------------------------------
/images/25/enzyme-test-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/25/enzyme-test-1.jpg
--------------------------------------------------------------------------------
/images/25/enzyme-test-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/25/enzyme-test-1.png
--------------------------------------------------------------------------------
/images/25/enzyme-test-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/25/enzyme-test-2.jpg
--------------------------------------------------------------------------------
/images/25/enzyme-test-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/25/enzyme-test-2.png
--------------------------------------------------------------------------------
/images/25/enzyme-test-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/25/enzyme-test-3.jpg
--------------------------------------------------------------------------------
/images/25/enzyme-test-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/25/enzyme-test-3.png
--------------------------------------------------------------------------------
/images/26/nightwatch-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/26/nightwatch-1.jpg
--------------------------------------------------------------------------------
/images/26/nightwatch-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/26/nightwatch-1.png
--------------------------------------------------------------------------------
/images/26/nightwatch-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/26/nightwatch-2.jpg
--------------------------------------------------------------------------------
/images/26/nightwatch-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/26/nightwatch-2.png
--------------------------------------------------------------------------------
/images/26/nightwatch-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/26/nightwatch-3.jpg
--------------------------------------------------------------------------------
/images/26/nightwatch-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/26/nightwatch-3.png
--------------------------------------------------------------------------------
/images/26/npm-start.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/26/npm-start.jpg
--------------------------------------------------------------------------------
/images/26/npm-start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/26/npm-start.png
--------------------------------------------------------------------------------
/images/26/selenium-server.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/26/selenium-server.jpg
--------------------------------------------------------------------------------
/images/26/selenium-server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/26/selenium-server.png
--------------------------------------------------------------------------------
/images/28/bitballoon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/bitballoon.jpg
--------------------------------------------------------------------------------
/images/28/bitballoon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/bitballoon.png
--------------------------------------------------------------------------------
/images/28/gh-pages.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/gh-pages.jpg
--------------------------------------------------------------------------------
/images/28/gh-pages.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/gh-pages.png
--------------------------------------------------------------------------------
/images/28/git-branch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/git-branch.jpg
--------------------------------------------------------------------------------
/images/28/git-branch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/git-branch.png
--------------------------------------------------------------------------------
/images/28/github-pages.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/github-pages.jpg
--------------------------------------------------------------------------------
/images/28/github-pages.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/github-pages.png
--------------------------------------------------------------------------------
/images/28/github-repo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/github-repo.jpg
--------------------------------------------------------------------------------
/images/28/github-repo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/github-repo.png
--------------------------------------------------------------------------------
/images/28/github-url.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/github-url.jpg
--------------------------------------------------------------------------------
/images/28/github-url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/github-url.png
--------------------------------------------------------------------------------
/images/28/heroku-create.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku-create.jpg
--------------------------------------------------------------------------------
/images/28/heroku-create.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku-create.png
--------------------------------------------------------------------------------
/images/28/heroku-deploy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku-deploy.jpg
--------------------------------------------------------------------------------
/images/28/heroku-deploy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku-deploy.png
--------------------------------------------------------------------------------
/images/28/heroku-login.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku-login.jpg
--------------------------------------------------------------------------------
/images/28/heroku-login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku-login.png
--------------------------------------------------------------------------------
/images/28/heroku-plugin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku-plugin.jpg
--------------------------------------------------------------------------------
/images/28/heroku-plugin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku-plugin.png
--------------------------------------------------------------------------------
/images/28/heroku-static-init.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku-static-init.jpg
--------------------------------------------------------------------------------
/images/28/heroku-static-init.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku-static-init.png
--------------------------------------------------------------------------------
/images/28/heroku.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku.jpg
--------------------------------------------------------------------------------
/images/28/heroku.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/heroku.png
--------------------------------------------------------------------------------
/images/28/npm-build.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/npm-build.jpg
--------------------------------------------------------------------------------
/images/28/npm-build.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/npm-build.png
--------------------------------------------------------------------------------
/images/28/pancake.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/pancake.jpg
--------------------------------------------------------------------------------
/images/28/pancake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/pancake.png
--------------------------------------------------------------------------------
/images/28/s3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/s3.jpg
--------------------------------------------------------------------------------
/images/28/s3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/s3.png
--------------------------------------------------------------------------------
/images/28/surge-deploy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/surge-deploy.jpg
--------------------------------------------------------------------------------
/images/28/surge-deploy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/surge-deploy.png
--------------------------------------------------------------------------------
/images/28/surge.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/surge.jpg
--------------------------------------------------------------------------------
/images/28/surge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/28/surge.png
--------------------------------------------------------------------------------
/images/29/deploy-fail.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/deploy-fail.jpg
--------------------------------------------------------------------------------
/images/29/deploy-fail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/deploy-fail.png
--------------------------------------------------------------------------------
/images/29/deploy-script.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/deploy-script.jpg
--------------------------------------------------------------------------------
/images/29/deploy-script.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/deploy-script.png
--------------------------------------------------------------------------------
/images/29/travis-activate-repo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/travis-activate-repo.jpg
--------------------------------------------------------------------------------
/images/29/travis-activate-repo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/travis-activate-repo.png
--------------------------------------------------------------------------------
/images/29/travis-output.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/travis-output.jpg
--------------------------------------------------------------------------------
/images/29/travis-output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/travis-output.png
--------------------------------------------------------------------------------
/images/29/travis-select-repo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/travis-select-repo.jpg
--------------------------------------------------------------------------------
/images/29/travis-select-repo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/travis-select-repo.png
--------------------------------------------------------------------------------
/images/29/travis-setup.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/travis-setup.jpg
--------------------------------------------------------------------------------
/images/29/travis-setup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/29/travis-setup.png
--------------------------------------------------------------------------------
/images/headings/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/1.jpg
--------------------------------------------------------------------------------
/images/headings/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/10.jpg
--------------------------------------------------------------------------------
/images/headings/10_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/10_wide.jpg
--------------------------------------------------------------------------------
/images/headings/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/11.jpg
--------------------------------------------------------------------------------
/images/headings/11_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/11_wide.jpg
--------------------------------------------------------------------------------
/images/headings/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/12.jpg
--------------------------------------------------------------------------------
/images/headings/12_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/12_wide.jpg
--------------------------------------------------------------------------------
/images/headings/13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/13.jpg
--------------------------------------------------------------------------------
/images/headings/13_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/13_wide.jpg
--------------------------------------------------------------------------------
/images/headings/14.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/14.jpg
--------------------------------------------------------------------------------
/images/headings/14_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/14_wide.jpg
--------------------------------------------------------------------------------
/images/headings/15.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/15.jpg
--------------------------------------------------------------------------------
/images/headings/15_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/15_wide.jpg
--------------------------------------------------------------------------------
/images/headings/16.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/16.jpg
--------------------------------------------------------------------------------
/images/headings/16_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/16_wide.jpg
--------------------------------------------------------------------------------
/images/headings/17.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/17.jpg
--------------------------------------------------------------------------------
/images/headings/17_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/17_wide.jpg
--------------------------------------------------------------------------------
/images/headings/18.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/18.jpg
--------------------------------------------------------------------------------
/images/headings/18_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/18_wide.jpg
--------------------------------------------------------------------------------
/images/headings/19.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/19.jpg
--------------------------------------------------------------------------------
/images/headings/19_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/19_wide.jpg
--------------------------------------------------------------------------------
/images/headings/1_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/1_wide.jpg
--------------------------------------------------------------------------------
/images/headings/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/2.jpg
--------------------------------------------------------------------------------
/images/headings/20.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/20.jpg
--------------------------------------------------------------------------------
/images/headings/20_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/20_wide.jpg
--------------------------------------------------------------------------------
/images/headings/21.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/21.jpg
--------------------------------------------------------------------------------
/images/headings/21_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/21_wide.jpg
--------------------------------------------------------------------------------
/images/headings/22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/22.jpg
--------------------------------------------------------------------------------
/images/headings/22_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/22_wide.jpg
--------------------------------------------------------------------------------
/images/headings/23.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/23.jpg
--------------------------------------------------------------------------------
/images/headings/23_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/23_wide.jpg
--------------------------------------------------------------------------------
/images/headings/24.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/24.jpg
--------------------------------------------------------------------------------
/images/headings/24_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/24_wide.jpg
--------------------------------------------------------------------------------
/images/headings/25.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/25.jpg
--------------------------------------------------------------------------------
/images/headings/25_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/25_wide.jpg
--------------------------------------------------------------------------------
/images/headings/26.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/26.jpg
--------------------------------------------------------------------------------
/images/headings/26_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/26_wide.jpg
--------------------------------------------------------------------------------
/images/headings/27.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/27.jpg
--------------------------------------------------------------------------------
/images/headings/27_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/27_wide.jpg
--------------------------------------------------------------------------------
/images/headings/28.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/28.jpg
--------------------------------------------------------------------------------
/images/headings/28_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/28_wide.jpg
--------------------------------------------------------------------------------
/images/headings/29.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/29.jpg
--------------------------------------------------------------------------------
/images/headings/29_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/29_wide.jpg
--------------------------------------------------------------------------------
/images/headings/2_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/2_wide.jpg
--------------------------------------------------------------------------------
/images/headings/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/3.jpg
--------------------------------------------------------------------------------
/images/headings/30.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/30.jpg
--------------------------------------------------------------------------------
/images/headings/30_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/30_wide.jpg
--------------------------------------------------------------------------------
/images/headings/3_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/3_wide.jpg
--------------------------------------------------------------------------------
/images/headings/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/4.jpg
--------------------------------------------------------------------------------
/images/headings/4_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/4_wide.jpg
--------------------------------------------------------------------------------
/images/headings/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/5.jpg
--------------------------------------------------------------------------------
/images/headings/5_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/5_wide.jpg
--------------------------------------------------------------------------------
/images/headings/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/6.jpg
--------------------------------------------------------------------------------
/images/headings/6_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/6_wide.jpg
--------------------------------------------------------------------------------
/images/headings/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/7.jpg
--------------------------------------------------------------------------------
/images/headings/7_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/7_wide.jpg
--------------------------------------------------------------------------------
/images/headings/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/8.jpg
--------------------------------------------------------------------------------
/images/headings/8_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/8_wide.jpg
--------------------------------------------------------------------------------
/images/headings/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/9.jpg
--------------------------------------------------------------------------------
/images/headings/9_wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/headings/9_wide.jpg
--------------------------------------------------------------------------------
/images/readme/30-days-of-react-book-cover-2-as-book-220.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/readme/30-days-of-react-book-cover-2-as-book-220.png
--------------------------------------------------------------------------------
/images/readme/download-the-pdf-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/readme/download-the-pdf-button.png
--------------------------------------------------------------------------------
/images/readme/fullstack-react-hero-book.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fullstackreact/30-days-of-react/91579483d2b69a33e7a727b49e24ae61a1ef6882/images/readme/fullstack-react-hero-book.png
--------------------------------------------------------------------------------
/internal/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "thirty-days-of-react-internal",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "bluebird": "^3.5.1",
13 | "glob": "^7.1.3",
14 | "gray-matter": "^4.0.1",
15 | "lodash": "^4.17.10",
16 | "sharp": "^0.20.7",
17 | "yargs": "^12.0.1"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------