From 8aa2d4eb50a9d93a7b2541f46b1cc4578457b32e Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Tue, 6 Jul 2021 16:09:10 -0500 Subject: [PATCH 01/21] Add docker-compose & add_dependancies.sh to run app locally with docker See README.md for details --- add_dependancies.sh | 27 +++++++++++++++++++++++++++ docker-compose.yml | 14 ++++++++++++++ 2 files changed, 41 insertions(+) create mode 100755 add_dependancies.sh create mode 100644 docker-compose.yml diff --git a/add_dependancies.sh b/add_dependancies.sh new file mode 100755 index 00000000..9dea923f --- /dev/null +++ b/add_dependancies.sh @@ -0,0 +1,27 @@ +# !/bin/bash + +# any parmeter I want to add in, use dollar sign +# eg $1 == first param, $2 == second, etc +# can name param whatever you want + +dependency=$1 +container_name="reactnd-chirper-app_app_1" + +if [ -z "$dependency" ] +then + echo "please call script with dependecy you would like to add" + echo "./add_dependancies.sh {dependecy}" +else + echo "installing $dependecy" + echo "running: yarn add $dependecy, in docker container $container_name" + docker exec $container_name yarn add $dependency +fi + + + + +#yarn add prop-types +#yarn add escape-string-regexp +#yarn add sort-by +#yarn add react-router-dom +#yarn add prop-types diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..724770e4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.8" + +services: + app: + image: node:12-alpine + command: sh -c "yarn install && yarn start" + #command: sh -c "yarn create react-app udacity-goals-todos && cd udacity-goals-todos && yarn add prop-types" + ports: + - 3000:3000 + working_dir: /reactnd-chirper-app + volumes: + - ./:/reactnd-chirper-app:consistent + stdin_open: true + From d19becf14858e1040b1c75a3a4ebc4fa9d019187 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Tue, 6 Jul 2021 16:32:38 -0500 Subject: [PATCH 02/21] Update README.md & .gitignore Readme now has instructions to run locallly using docker, gitignore now ignores .swp files --- .gitignore | 3 +++ README.md | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index d30f40ef..604bb952 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +#personal addings +*.swp diff --git a/README.md b/README.md index d6331967..e84c875d 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,42 @@ This repo is a code-along with the first project in the [React Nanodegree progra Most of the commits in this repository correspond to videos in the program. -## Project Setup +## How to run this My Reads project locally -* clone the Project - `git@github.com:udacity/reactnd-chirper-app.git` -* install the dependencies - `npm install` +First clone the project from desired repo +To see current state: +* clone from MarinEstrada page `git@github.com:MarinEstrada/reactnd-chirper-app.git` +To see original starter state +* clone the Project from original Udacity page - `git@github.com:udacity/reactnd-chirper-app.git` + +This project runs locally on "localhost:3000/" using +* npm (Node Package Manager) +* Docker + +### Using npm +* install all project dependencies with: +`npm install` +* start the development server with: +`npm start` + +### Using Docker +To start the app locally run: +`docker-compose up -d` + +To download extra needed dependencies run: +`bash add_dependencies.sh {dependency_name}` + +To take a look at the logs: +`docker-compose logs -f` + +To tear the containers down +`docker-compose down` ## Contributing -Because this is a code-along project and the commits correspond to specific videos in the program, we will not be accepting pull requests. +Because this is a code-along project and the commits correspond to specific videos in the program, Udacity will not be accepting pull requests. -If you feel like there's a major problem, please open an issue to discuss the problem and potential resolution. +If you feel like there's a major problem, please open an issue on the Udacity repo to discuss the problem and potential resolution. ## License From 483edd468402f5820eaa3e409e00b057265f5497 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Wed, 7 Jul 2021 00:32:53 -0500 Subject: [PATCH 03/21] Add first Actions --- src/actions/authedUser.js | 8 ++++++++ src/actions/shared.js | 18 ++++++++++++++++++ src/actions/tweets.js | 8 ++++++++ src/actions/users.js | 8 ++++++++ 4 files changed, 42 insertions(+) create mode 100644 src/actions/authedUser.js create mode 100644 src/actions/shared.js create mode 100644 src/actions/tweets.js create mode 100644 src/actions/users.js diff --git a/src/actions/authedUser.js b/src/actions/authedUser.js new file mode 100644 index 00000000..39db9ade --- /dev/null +++ b/src/actions/authedUser.js @@ -0,0 +1,8 @@ +export const SET_AUTHED_USER = 'SET_AUTHED_USER' + +export function setAuthedUser(id) { + return { + type: SET_AUTHED_USER, + id, + } +} diff --git a/src/actions/shared.js b/src/actions/shared.js new file mode 100644 index 00000000..9dfb6f03 --- /dev/null +++ b/src/actions/shared.js @@ -0,0 +1,18 @@ +import { getInitalData } from '../utils/api' +import { receiveUsers } from './users' +import { receiveTweets } from './tweets' +import { setAuthedUser } from './authedUser' + +//user currently 'logged in' +const AUTHED_ID = 'tylermcginnis' + +export function handleInitalData() { + return (dispatch) => { + return getInitalData() + .then(({ users, tweets }) => { + dispatch(receiveUsers(users)) + dispatch(receiveTweets(tweets)) + dispatch(setAuthedUser(AUTHED_ID)) + }) + } +} diff --git a/src/actions/tweets.js b/src/actions/tweets.js new file mode 100644 index 00000000..5cabed15 --- /dev/null +++ b/src/actions/tweets.js @@ -0,0 +1,8 @@ +export const RECEIVE_TWEETS = 'RECEIVE_TWEETS' + +export function receiveTweets(tweets) { + return { + type: RECEIVE_TWEETS, + tweets, + } +} diff --git a/src/actions/users.js b/src/actions/users.js new file mode 100644 index 00000000..bd00beac --- /dev/null +++ b/src/actions/users.js @@ -0,0 +1,8 @@ +export const RECEIVE_USERS = 'RECEIVE_USERS' + +export function receiveUsers(users) { + return { + type: RECEIVE_USERS, + users, + } +} From ebbfcc60abf8e889c30091ab530309a79e4f1176 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Thu, 8 Jul 2021 22:25:11 -0500 Subject: [PATCH 04/21] Add reducers --- src/reducers/authedUser.js | 10 ++++++++++ src/reducers/index.js | 12 ++++++++++++ src/reducers/tweets.js | 13 +++++++++++++ src/reducers/users.js | 13 +++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 src/reducers/authedUser.js create mode 100644 src/reducers/index.js create mode 100644 src/reducers/tweets.js create mode 100644 src/reducers/users.js diff --git a/src/reducers/authedUser.js b/src/reducers/authedUser.js new file mode 100644 index 00000000..a6ee3d81 --- /dev/null +++ b/src/reducers/authedUser.js @@ -0,0 +1,10 @@ +import { SET_AUTHED_USER } from '../actions/authedUser' + +export default function authedUser(state = null, action) { + switch (action.type) { + case SET_AUTHED_USER: + return action.id + default: + return state + } +} diff --git a/src/reducers/index.js b/src/reducers/index.js new file mode 100644 index 00000000..e31c57ba --- /dev/null +++ b/src/reducers/index.js @@ -0,0 +1,12 @@ +import { combineReducers } from 'redux' +import { authedUser } from './authedUser' +import { tweets } from './tweets' +import { users } from './users' + +//Use Redux combineReducers by passing it an object containing +//all your reducers +export default function combineReducers({ + authedUser, + tweets, + users, +}) diff --git a/src/reducers/tweets.js b/src/reducers/tweets.js new file mode 100644 index 00000000..051effb2 --- /dev/null +++ b/src/reducers/tweets.js @@ -0,0 +1,13 @@ +import { RECEIVE_TWEETS } from '../actions/tweets' + +export default function tweets(state = {}, action) { + switch (action.type) { + case RECEIVE_TWEETS: + return { + ...state, + ...actions.tweets + } + default: + return state + } +} diff --git a/src/reducers/users.js b/src/reducers/users.js new file mode 100644 index 00000000..6cde98d9 --- /dev/null +++ b/src/reducers/users.js @@ -0,0 +1,13 @@ +import { RECEIVE_USERS } from '../actions/users' + +export default function users(state = {}, action) { + switch (action.type) { + case RECEIVE_USERS: + return { + ...state, + ...actions.users + } + default: + return state + } +} From 757d2d29862c0866b4deb79adcb251cc857a4cbc Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Thu, 8 Jul 2021 22:13:10 -0500 Subject: [PATCH 05/21] Install 'react-redux' & 'redux' packages --- package.json | 4 +- yarn.lock | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 27798f4d..78c75c50 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "dependencies": { "react": "^16.2.0", "react-dom": "^16.2.0", - "react-scripts": "1.1.1" + "react-redux": "^7.2.4", + "react-scripts": "1.1.1", + "redux": "^4.1.0" }, "scripts": { "start": "react-scripts start", diff --git a/yarn.lock b/yarn.lock index bd36e402..d24609ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,50 @@ # yarn lockfile v1 +"@babel/runtime@^7.12.1", "@babel/runtime@^7.9.2": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== + dependencies: + regenerator-runtime "^0.13.4" + +"@types/hoist-non-react-statics@^3.3.0": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + +"@types/prop-types@*": + version "15.7.4" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" + integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== + +"@types/react-redux@^7.1.16": + version "7.1.18" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.18.tgz#2bf8fd56ebaae679a90ebffe48ff73717c438e04" + integrity sha512-9iwAsPyJ9DLTRH+OFeIrm9cAbIj1i2ANL3sKQFATqnPWRbg+jEFXyZOKHiQK/N86pNRXbb4HRxAxo0SIX1XwzQ== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + +"@types/react@*": + version "17.0.14" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.14.tgz#f0629761ca02945c4e8fea99b8177f4c5c61fb0f" + integrity sha512-0WwKHUbWuQWOce61UexYuWTGuGY/8JvtUe/dtQ6lR4sZ3UiylHotJeWpf3ArP9+DSGUoLY3wbU59VyMrJps5VQ== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.2" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" + integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== + abab@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" @@ -1725,6 +1769,11 @@ cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": dependencies: cssom "0.3.x" +csstype@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" + integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -2951,6 +3000,13 @@ hoek@4.x.x: version "4.2.1" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -3708,6 +3764,11 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + js-yaml@^3.4.3, js-yaml@^3.7.0, js-yaml@^3.9.1: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" @@ -3981,6 +4042,13 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: dependencies: js-tokens "^3.0.0" +loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" @@ -4998,6 +5066,15 @@ prop-types@^15.5.10, prop-types@^15.6.0: loose-envify "^1.3.1" object-assign "^4.1.1" +prop-types@^15.7.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + proxy-addr@~2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" @@ -5150,6 +5227,23 @@ react-error-overlay@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.0.tgz#d198408a85b4070937a98667f500c832f86bd5d4" +react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-redux@^7.2.4: + version "7.2.4" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.4.tgz#1ebb474032b72d806de2e0519cd07761e222e225" + integrity sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA== + dependencies: + "@babel/runtime" "^7.12.1" + "@types/react-redux" "^7.1.16" + hoist-non-react-statics "^3.3.2" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-is "^16.13.1" + react-scripts@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-1.1.1.tgz#279d449f7311fed910506987a1ade014027788a8" @@ -5290,6 +5384,13 @@ reduce-function-call@^1.0.1: dependencies: balanced-match "^0.4.2" +redux@^4.0.0, redux@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4" + integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g== + dependencies: + "@babel/runtime" "^7.9.2" + regenerate@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" @@ -5298,6 +5399,11 @@ regenerator-runtime@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" From 0a716767f71fca4fc2b8749a34a2e8809428dfe0 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Thu, 8 Jul 2021 22:51:57 -0500 Subject: [PATCH 06/21] fix: Fix typos In src/actions/shared.js fix getInitialData typo (missing 'i') In src/reducers/index.js remove 'function' from 'export default function' when functions called as default, do not need to surround with '{}' In src/reducers/users.js In src/reducers/tweets.js actions -> action on ln8 --- src/actions/shared.js | 5 +++-- src/reducers/index.js | 8 ++++---- src/reducers/tweets.js | 2 +- src/reducers/users.js | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/actions/shared.js b/src/actions/shared.js index 9dfb6f03..02993b49 100644 --- a/src/actions/shared.js +++ b/src/actions/shared.js @@ -1,4 +1,4 @@ -import { getInitalData } from '../utils/api' +import { getInitialData } from '../utils/api' import { receiveUsers } from './users' import { receiveTweets } from './tweets' import { setAuthedUser } from './authedUser' @@ -7,8 +7,9 @@ import { setAuthedUser } from './authedUser' const AUTHED_ID = 'tylermcginnis' export function handleInitalData() { + //using redux thunk pattern return (dispatch) => { - return getInitalData() + return getInitialData() .then(({ users, tweets }) => { dispatch(receiveUsers(users)) dispatch(receiveTweets(tweets)) diff --git a/src/reducers/index.js b/src/reducers/index.js index e31c57ba..bc9d4f06 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,11 +1,11 @@ import { combineReducers } from 'redux' -import { authedUser } from './authedUser' -import { tweets } from './tweets' -import { users } from './users' +import authedUser from './authedUser' +import tweets from './tweets' +import users from './users' //Use Redux combineReducers by passing it an object containing //all your reducers -export default function combineReducers({ +export default combineReducers({ authedUser, tweets, users, diff --git a/src/reducers/tweets.js b/src/reducers/tweets.js index 051effb2..c837fc00 100644 --- a/src/reducers/tweets.js +++ b/src/reducers/tweets.js @@ -5,7 +5,7 @@ export default function tweets(state = {}, action) { case RECEIVE_TWEETS: return { ...state, - ...actions.tweets + ...action.tweets } default: return state diff --git a/src/reducers/users.js b/src/reducers/users.js index 6cde98d9..c75b892d 100644 --- a/src/reducers/users.js +++ b/src/reducers/users.js @@ -5,7 +5,7 @@ export default function users(state = {}, action) { case RECEIVE_USERS: return { ...state, - ...actions.users + ...action.users } default: return state From 40e440b2459e2b157f33485ba51de3d3aa628bc9 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Thu, 8 Jul 2021 23:03:52 -0500 Subject: [PATCH 07/21] func: Create store and wrap app in Context.Provider --- src/index.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 67b4ea1e..ec015766 100644 --- a/src/index.js +++ b/src/index.js @@ -2,5 +2,14 @@ import React from 'react' import ReactDOM from 'react-dom' import './index.css' import App from './components/App' +import { createStore } from 'redux' +import { Provider } from 'react-redux' +import reducer from './reducers' -ReactDOM.render(, document.getElementById('root')) \ No newline at end of file +const store = createStore(reducer) + +ReactDOM.render( + + + , +document.getElementById('root')) From 1b9fcb4c1a8d1076f95aaad6870bc3a24425d8ee Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Fri, 9 Jul 2021 03:20:32 -0500 Subject: [PATCH 08/21] Add redux-thunk package --- package.json | 3 ++- yarn.lock | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 78c75c50..fbb39b02 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "react-dom": "^16.2.0", "react-redux": "^7.2.4", "react-scripts": "1.1.1", - "redux": "^4.1.0" + "redux": "^4.1.0", + "redux-thunk": "^2.3.0" }, "scripts": { "start": "react-scripts start", diff --git a/yarn.lock b/yarn.lock index d24609ca..c3f52b46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5384,6 +5384,11 @@ reduce-function-call@^1.0.1: dependencies: balanced-match "^0.4.2" +redux-thunk@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" + integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== + redux@^4.0.0, redux@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4" From 8bb91e6339b05f466a65087ef7bc3e6296d40153 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Fri, 9 Jul 2021 05:04:41 -0500 Subject: [PATCH 09/21] fix: Update react & react-dom for compatability with react-redux 7.2.4 --- package.json | 4 ++-- yarn.lock | 29 ++++++++++++++++++----------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index fbb39b02..8badddfe 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "version": "0.1.0", "private": true, "dependencies": { - "react": "^16.2.0", - "react-dom": "^16.2.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", "react-redux": "^7.2.4", "react-scripts": "1.1.1", "redux": "^4.1.0", diff --git a/yarn.lock b/yarn.lock index c3f52b46..faa91283 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5058,7 +5058,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.5.10, prop-types@^15.6.0: +prop-types@^15.5.10: version "15.6.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca" dependencies: @@ -5214,14 +5214,14 @@ react-dev-utils@^5.0.0: strip-ansi "3.0.1" text-table "0.2.0" -react-dom@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044" +react-dom@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== dependencies: - fbjs "^0.8.16" loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.0" + scheduler "^0.20.2" react-error-overlay@^4.0.0: version "4.0.0" @@ -5288,14 +5288,13 @@ react-scripts@1.1.1: optionalDependencies: fsevents "^1.1.3" -react@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba" +react@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== dependencies: - fbjs "^0.8.16" loose-envify "^1.1.0" object-assign "^4.1.1" - prop-types "^15.6.0" read-pkg-up@^1.0.1: version "1.0.1" @@ -5664,6 +5663,14 @@ sax@^1.2.1, sax@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" +scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + schema-utils@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" From 02cf77bd4c8054e01da0202f79236ebdbbf50b38 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Fri, 9 Jul 2021 05:13:17 -0500 Subject: [PATCH 10/21] func: Add logger Middleware --- src/index.js | 3 ++- src/middleware/index.js | 8 ++++++++ src/middleware/logger.js | 11 +++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/middleware/index.js create mode 100644 src/middleware/logger.js diff --git a/src/index.js b/src/index.js index ec015766..9313e0af 100644 --- a/src/index.js +++ b/src/index.js @@ -5,8 +5,9 @@ import App from './components/App' import { createStore } from 'redux' import { Provider } from 'react-redux' import reducer from './reducers' +import middleware from './middleware' -const store = createStore(reducer) +const store = createStore(reducer, middleware) ReactDOM.render( diff --git a/src/middleware/index.js b/src/middleware/index.js new file mode 100644 index 00000000..aa1cf17a --- /dev/null +++ b/src/middleware/index.js @@ -0,0 +1,8 @@ +import thunk from 'redux-thunk' +import logger from './logger' +import { applyMiddleware } from 'redux' + +export default applyMiddleware( + thunk, + logger, +) diff --git a/src/middleware/logger.js b/src/middleware/logger.js new file mode 100644 index 00000000..a1873e1b --- /dev/null +++ b/src/middleware/logger.js @@ -0,0 +1,11 @@ +//middleware to log changes to state on console +const logger = (store) => (next) => (action) => { + console.group(action.type) + console.log('The action: ', action) + const returnValue = next(action) + console.log('The new state: ', store.getState()) + console.groupEnd() + return returnValue +} + +export default logger From 1fd70f5dca57c3e1891662e02d819ac5abe37ac8 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Fri, 9 Jul 2021 19:34:12 -0500 Subject: [PATCH 11/21] func: Add call to dispatch handleInitialData in App.js also fix typo it 'initial'in src/actions/shared.js --- src/actions/shared.js | 2 +- src/components/App.js | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/actions/shared.js b/src/actions/shared.js index 02993b49..907e6af9 100644 --- a/src/actions/shared.js +++ b/src/actions/shared.js @@ -6,7 +6,7 @@ import { setAuthedUser } from './authedUser' //user currently 'logged in' const AUTHED_ID = 'tylermcginnis' -export function handleInitalData() { +export function handleInitialData() { //using redux thunk pattern return (dispatch) => { return getInitialData() diff --git a/src/components/App.js b/src/components/App.js index 4859a621..99934887 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,13 +1,20 @@ import React, { Component } from 'react' +import { connect } from 'react-redux' +import { handleInitialData } from '../actions/shared' class App extends Component { - render() { - return ( -
- Starter Code -
- ) - } + componentDidMount() { + this.props.dispatch(handleInitialData()) + } + render() { + return ( +
+ Starter Code +
+ ) + } } -export default App \ No newline at end of file +//We don't need anything from state, so leave +//first invocation blank +export default connect()(App) From 3db9a714974356e0df60f17c5bc08fea99f2bc08 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Fri, 9 Jul 2021 23:43:00 -0500 Subject: [PATCH 12/21] func: Set up Dashboard render a list of tweet id's to render when page is fully loaded later these tweet ids will be exchanged for tweet containers --- src/components/App.js | 13 +++++++++++-- src/components/Dashboard.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/components/Dashboard.js diff --git a/src/components/App.js b/src/components/App.js index 99934887..58dba73d 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,6 +1,7 @@ import React, { Component } from 'react' import { connect } from 'react-redux' import { handleInitialData } from '../actions/shared' +import Dashboard from './Dashboard' class App extends Component { componentDidMount() { @@ -9,12 +10,20 @@ class App extends Component { render() { return (
- Starter Code + {this.props.loading === true + ? null + : }
) } } +function mapStateToProps({ authedUser }) { + return{ + loading: authedUser === null + } +} + //We don't need anything from state, so leave //first invocation blank -export default connect()(App) +export default connect(mapStateToProps)(App) diff --git a/src/components/Dashboard.js b/src/components/Dashboard.js new file mode 100644 index 00000000..7dd2db0b --- /dev/null +++ b/src/components/Dashboard.js @@ -0,0 +1,30 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' + +class Dashboard extends Component { + render() { + return( +
+

Your Timeline

+
    + {this.props.tweetIds.map((id) => ( +
  • +
    TWEET ID: {id}
    +
  • + ))} +
+
+ ) + } +} + +//takes in state of store, +//specifically only portion it needs (tweets) +function mapStateToProps ({ tweets }) { + return{ + tweetIds: Object.keys(tweets) + .sort((a,b) => tweets[b].timestamp - tweets[a].timestamp) + } +} + +export default connect(mapStateToProps)(Dashboard) From c41fb26dd11732426ce12ed5e5d02fb5aa64e851 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Sun, 11 Jul 2021 03:58:18 -0500 Subject: [PATCH 13/21] func: Install react-icons package --- package.json | 1 + yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/package.json b/package.json index 8badddfe..e2f3d257 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "dependencies": { "react": "^17.0.2", "react-dom": "^17.0.2", + "react-icons": "^4.2.0", "react-redux": "^7.2.4", "react-scripts": "1.1.1", "redux": "^4.1.0", diff --git a/yarn.lock b/yarn.lock index faa91283..6522db75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5227,6 +5227,11 @@ react-error-overlay@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.0.tgz#d198408a85b4070937a98667f500c832f86bd5d4" +react-icons@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.2.0.tgz#6dda80c8a8f338ff96a1851424d63083282630d0" + integrity sha512-rmzEDFt+AVXRzD7zDE21gcxyBizD/3NqjbX6cmViAgdqfJ2UiLer8927/QhhrXQV7dEj/1EGuOTPp7JnLYVJKQ== + react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" From 6484a1cc53f78f9e2e127a0e0a795e828ac78edd Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Sun, 11 Jul 2021 03:59:01 -0500 Subject: [PATCH 14/21] WIP: Add logic to handle tweet component --- src/components/App.js | 1 + src/components/Dashboard.js | 3 ++- src/components/Tweet.js | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/components/Tweet.js diff --git a/src/components/App.js b/src/components/App.js index 58dba73d..2bbf562c 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -26,4 +26,5 @@ function mapStateToProps({ authedUser }) { //We don't need anything from state, so leave //first invocation blank +//second invocation is where we will render (eg, App) export default connect(mapStateToProps)(App) diff --git a/src/components/Dashboard.js b/src/components/Dashboard.js index 7dd2db0b..0ba5476c 100644 --- a/src/components/Dashboard.js +++ b/src/components/Dashboard.js @@ -1,5 +1,6 @@ import React, { Component } from 'react' import { connect } from 'react-redux' +import Tweet from './Tweet' class Dashboard extends Component { render() { @@ -9,7 +10,7 @@ class Dashboard extends Component {
    {this.props.tweetIds.map((id) => (
  • -
    TWEET ID: {id}
    +
  • ))}
diff --git a/src/components/Tweet.js b/src/components/Tweet.js new file mode 100644 index 00000000..05de7eb5 --- /dev/null +++ b/src/components/Tweet.js @@ -0,0 +1,35 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' +import { formatTweet } from '../utils/helpers' + +class Tweet extends Component { + render() { + const { tweet } = this.props + + if (tweet === null) { + return

This Tweet doesn't exit

+ } + + console.log(this.props) + return( +
+ +
+ ) + } +} + +//note how second argument is component we are going to render +function mapStateToProps({ authedUser, users, tweets }, { id }) { + const tweet = tweets[id] + const parentTweet = tweet ? tweets[tweet.replyingTo] : null + + return { + authedUser, + tweet: tweet + ? formatTweet(tweet, users[tweet.author], authedUser, parentTweet) + : null + } +} + +export default connect(mapStateToProps)(Tweet) From b7cc8e5b7787828364161dd2916983cf057f6972 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Sun, 11 Jul 2021 05:03:47 -0500 Subject: [PATCH 15/21] func: Add Tweet UI --- src/components/Tweet.js | 62 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/src/components/Tweet.js b/src/components/Tweet.js index 05de7eb5..9f038950 100644 --- a/src/components/Tweet.js +++ b/src/components/Tweet.js @@ -1,8 +1,24 @@ import React, { Component } from 'react' import { connect } from 'react-redux' -import { formatTweet } from '../utils/helpers' +import { formatTweet, formatDate } from '../utils/helpers' +import { TiArrowBackOutline } from 'react-icons/ti' +import { TiHeartOutline } from 'react-icons/ti' +import { TiHeartFullOutline } from 'react-icons/ti' class Tweet extends Component { + + //helper function for like button + handleLike = (e) => { + e.preventDefault() + // todo: Handle like tweet + } + + // helper function for reply button + toParent = (e, id) => { + e.preventDefault() + // todo: Redirect to parent tweet + } + render() { const { tweet } = this.props @@ -10,10 +26,50 @@ class Tweet extends Component { return

This Tweet doesn't exit

} - console.log(this.props) + //deconstructing tweet + const { + name, + avatar, + timestamp, + text, + hasLiked, + likes, + replies, + parent } = tweet + return(
- + {`Avatar +
+
+ {name} +
{formatDate(timestamp)}
+ {parent && ( + + )} +

{text}

+
+
+ + {replies !== 0 && replies} + + {likes !== 0 && likes} +
+
) } From fef8e88eaa77b9d039460f1278f29c3a459d1396 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Tue, 13 Jul 2021 15:54:51 -0500 Subject: [PATCH 16/21] Install react-redux-loading package --- package.json | 1 + yarn.lock | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e2f3d257..d2d0d2d2 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "react-dom": "^17.0.2", "react-icons": "^4.2.0", "react-redux": "^7.2.4", + "react-redux-loading": "^4.6.1", "react-scripts": "1.1.1", "redux": "^4.1.0", "redux-thunk": "^2.3.0" diff --git a/yarn.lock b/yarn.lock index 6522db75..281585c8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5066,7 +5066,7 @@ prop-types@^15.5.10: loose-envify "^1.3.1" object-assign "^4.1.1" -prop-types@^15.7.2: +prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -5237,6 +5237,19 @@ react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-lifecycles-compat@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-redux-loading@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/react-redux-loading/-/react-redux-loading-4.6.1.tgz#29b3e3d90625b00cd795423fd9cdb1b4ca09438e" + integrity sha512-MrpabKX0LTwqVq/gQjffV44GvVN7F1nZD7Ur1g8twYt4D/Yoq3ezL2f3nQybcXkmlMuYH6YFXgalLKoDDmPIrg== + dependencies: + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.2" + react-redux@^7.2.4: version "7.2.4" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.4.tgz#1ebb474032b72d806de2e0519cd07761e222e225" From 16a9598eb0ab68fb00de21a13f555a0989c4b55f Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Tue, 13 Jul 2021 16:12:24 -0500 Subject: [PATCH 17/21] func: Add loading bar --- src/actions/shared.js | 3 +++ src/components/App.js | 2 ++ src/reducers/index.js | 2 ++ 3 files changed, 7 insertions(+) diff --git a/src/actions/shared.js b/src/actions/shared.js index 907e6af9..8edf3707 100644 --- a/src/actions/shared.js +++ b/src/actions/shared.js @@ -2,6 +2,7 @@ import { getInitialData } from '../utils/api' import { receiveUsers } from './users' import { receiveTweets } from './tweets' import { setAuthedUser } from './authedUser' +import { showLoading, hideLoading } from 'react-redux-loading' //user currently 'logged in' const AUTHED_ID = 'tylermcginnis' @@ -9,11 +10,13 @@ const AUTHED_ID = 'tylermcginnis' export function handleInitialData() { //using redux thunk pattern return (dispatch) => { + dispatch(showLoading()) return getInitialData() .then(({ users, tweets }) => { dispatch(receiveUsers(users)) dispatch(receiveTweets(tweets)) dispatch(setAuthedUser(AUTHED_ID)) + dispatch(hideLoading()) }) } } diff --git a/src/components/App.js b/src/components/App.js index 2bbf562c..4b92d438 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -2,6 +2,7 @@ import React, { Component } from 'react' import { connect } from 'react-redux' import { handleInitialData } from '../actions/shared' import Dashboard from './Dashboard' +import LoadingBar from 'react-redux-loading' class App extends Component { componentDidMount() { @@ -10,6 +11,7 @@ class App extends Component { render() { return (
+ {this.props.loading === true ? null : } diff --git a/src/reducers/index.js b/src/reducers/index.js index bc9d4f06..b615c5fe 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -2,6 +2,7 @@ import { combineReducers } from 'redux' import authedUser from './authedUser' import tweets from './tweets' import users from './users' +import { loadingBarReducer } from 'react-redux-loading' //Use Redux combineReducers by passing it an object containing //all your reducers @@ -9,4 +10,5 @@ export default combineReducers({ authedUser, tweets, users, + loadingBar: loadingBarReducer, }) From efb6644ac184ce19c716ea09ff93d6983cbddc4e Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Tue, 13 Jul 2021 17:45:42 -0500 Subject: [PATCH 18/21] func: Add like tweet functionality --- src/actions/tweets.js | 25 +++++++++++++++++++++++++ src/components/Tweet.js | 10 +++++++++- src/reducers/tweets.js | 12 +++++++++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/actions/tweets.js b/src/actions/tweets.js index 5cabed15..b8f3f03b 100644 --- a/src/actions/tweets.js +++ b/src/actions/tweets.js @@ -1,4 +1,7 @@ +import { saveLikeToggle } from '../utils/api' + export const RECEIVE_TWEETS = 'RECEIVE_TWEETS' +export const TOGGLE_TWEET = 'TOGGLE_TWEET' export function receiveTweets(tweets) { return { @@ -6,3 +9,25 @@ export function receiveTweets(tweets) { tweets, } } + +export function toggleTweet({ id, authedUser, hasLiked }) { + return { + type: TOGGLE_TWEET, + id, + authedUser, + hasLiked, + } +} + +export function handleToggleTweet(info) { + return(dispatch) => { + dispatch(toggleTweet(info)) + + return saveLikeToggle(info) + .catch((e) => { + console.warn('Error in handleToggleTweet: ', e) + dispatch(toggleTweet(info)) + alert("Error: couldn't like tweet. Try again.") + }) + } +} diff --git a/src/components/Tweet.js b/src/components/Tweet.js index 9f038950..31369f08 100644 --- a/src/components/Tweet.js +++ b/src/components/Tweet.js @@ -4,13 +4,21 @@ import { formatTweet, formatDate } from '../utils/helpers' import { TiArrowBackOutline } from 'react-icons/ti' import { TiHeartOutline } from 'react-icons/ti' import { TiHeartFullOutline } from 'react-icons/ti' +import { handleToggleTweet } from '../actions/tweets' class Tweet extends Component { //helper function for like button handleLike = (e) => { e.preventDefault() - // todo: Handle like tweet + + const { dispatch, tweet, authedUser } = this.props + + dispatch(handleToggleTweet({ + id: tweet.id, + hasLiked: tweet.hasLiked, + authedUser, + })) } // helper function for reply button diff --git a/src/reducers/tweets.js b/src/reducers/tweets.js index c837fc00..7cd1489c 100644 --- a/src/reducers/tweets.js +++ b/src/reducers/tweets.js @@ -1,4 +1,4 @@ -import { RECEIVE_TWEETS } from '../actions/tweets' +import { RECEIVE_TWEETS, TOGGLE_TWEET } from '../actions/tweets' export default function tweets(state = {}, action) { switch (action.type) { @@ -7,6 +7,16 @@ export default function tweets(state = {}, action) { ...state, ...action.tweets } + case TOGGLE_TWEET: + return { + ...state, + [action.id]: { + ...state[action.id], + likes: action.hasLiked === true + ? state[action.id].likes.filter((userId) => userId !== action.authedUser) + : state[action.id].likes.concat([action.authedUser]) + } + } default: return state } From 03cb8972d02676fe16f817548c806e23682454c4 Mon Sep 17 00:00:00 2001 From: MarinEstrada Date: Tue, 13 Jul 2021 21:20:33 -0500 Subject: [PATCH 19/21] ui: Add new tweet UI Added unnder src/components/NewTweet.js --- src/components/App.js | 3 +- src/components/NewTweet.js | 62 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/components/NewTweet.js diff --git a/src/components/App.js b/src/components/App.js index 4b92d438..10bf350b 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -3,6 +3,7 @@ import { connect } from 'react-redux' import { handleInitialData } from '../actions/shared' import Dashboard from './Dashboard' import LoadingBar from 'react-redux-loading' +import NewTweet from './NewTweet' class App extends Component { componentDidMount() { @@ -14,7 +15,7 @@ class App extends Component { {this.props.loading === true ? null - : } + : }
) } diff --git a/src/components/NewTweet.js b/src/components/NewTweet.js new file mode 100644 index 00000000..62ae60f6 --- /dev/null +++ b/src/components/NewTweet.js @@ -0,0 +1,62 @@ +import React, { Component } from 'react' + +class NewTweet extends Component { + state = { + text: '', + } + + handleChange = (e) => { + const text = e.target.value + + this.setState(() => ({ text })) + } + + handleSubmit = (e) => { + e.preventDefault() + + const { text } = this.state + + // todo: Add tweet to store + + console.log('New Tweet: ', text) + + this.setState(() => ({ text: '' })) + + } + + render() { + + const { text } = this.state + + {/* todo: Redirect to '/' if submited */} + + const charsLeft = 280 - text.length + + return( +
+

Compose New Tweet

+
+