diff --git a/README.md b/README.md index 9ea4e26b3..0282d60d1 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,27 @@ # Happy Thoughts -Replace this readme with your own information about your project. - -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. +A happy twitter-like wall for all you thoughts. Share what you are thinking about right now! ## The problem -Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? +### The challenge + + +In this week's project, you'll be able to practice your React state skills by fetching and posting data to an API. + +**What you need to do** + +✓ Your page should follow the design as closely as possible + +✓ You should list the most recent thoughts at the top and older thoughts at the bottom (sorted) + +✓ Your thoughts should show the content of the message and how many likes they've received + +✓ You should have a form to post new thoughts + +✓ You should implement the heart button to send likes on a thought ## View it live Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. +https://technigo-happy-thoughts-app.netlify.app/ diff --git a/code/.eslintrc.json b/code/.eslintrc.json index c9c0675c3..df5250df5 100644 --- a/code/.eslintrc.json +++ b/code/.eslintrc.json @@ -1,7 +1,5 @@ { - "extends": [ - "airbnb" - ], + "extends": ["airbnb"], "globals": { "document": true, "window": true, @@ -22,10 +20,9 @@ "modules": true } }, - "plugins": [ - "react-hooks" - ], + "plugins": ["react-hooks"], "rules": { + "linebreak-style": ["off", "unix"], "react/function-component-definition": [ 2, { @@ -42,10 +39,7 @@ "allowSingleLine": true } ], - "comma-dangle": [ - "error", - "never" - ], + "comma-dangle": ["error", "never"], "consistent-return": "off", "curly": "error", "eol-last": "off", diff --git a/code/package-lock.json b/code/package-lock.json index f7e97e1e9..e361ead57 100644 --- a/code/package-lock.json +++ b/code/package-lock.json @@ -15,6 +15,7 @@ "eslint-plugin-jsx-a11y": "^6.6.1", "eslint-plugin-react": "^7.30.1", "eslint-plugin-react-hooks": "^4.6.0", + "moment": "^2.29.4", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -12155,6 +12156,14 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -26401,6 +26410,11 @@ "minimist": "^1.2.6" } }, + "moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", diff --git a/code/package.json b/code/package.json index 68869f589..e22530d82 100644 --- a/code/package.json +++ b/code/package.json @@ -1,7 +1,7 @@ { "name": "technigo-react-starter", "version": "1.0.0", - "private": true, + "private": false, "dependencies": { "babel-eslint": "^10.1.0", "eslint": "^8.21.0", @@ -10,6 +10,7 @@ "eslint-plugin-jsx-a11y": "^6.6.1", "eslint-plugin-react": "^7.30.1", "eslint-plugin-react-hooks": "^4.6.0", + "moment": "^2.29.4", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/code/src/App.js b/code/src/App.js index f2007d229..5dbfb3360 100644 --- a/code/src/App.js +++ b/code/src/App.js @@ -1,9 +1,58 @@ -import React from 'react'; +/* eslint-disable react/jsx-closing-bracket-location */ +/* eslint-disable no-unused-vars */ +import React, { useEffect, useState } from 'react'; +import { List } from 'components/List'; +import { Input } from 'components/Input'; export const App = () => { + const [thoughts, setThoughts] = useState([]); + const [newPost, setNewPost] = useState(''); + const [loading, setLoading] = useState(true); + + const fetchThoughts = () => { + fetch('https://project-happy-thoughts-api-hgwjnnqcva-lz.a.run.app/thoughts') + .then((res) => res.json()) + .then((data) => { + setThoughts(data); + }) + .finally(() => setLoading(false)) + .catch((error) => console.log(error)); + }; + + useEffect(() => { + fetchThoughts(); + }, []); + + const handleLikeChange = (id) => { + const options = { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + } + }; + fetch( + `https://project-happy-thoughts-api-hgwjnnqcva-lz.a.run.app/thoughts/${id}/like`, + options + ) + .catch((error) => console.log(error)) + .finally(() => fetchThoughts()); + }; return ( -
- Find me in src/app.js! +
+ + {loading &&

Thoughts is loading...

} + {thoughts && ( + + )}
); -} +}; diff --git a/code/src/components/Input.css b/code/src/components/Input.css new file mode 100644 index 000000000..4ef284381 --- /dev/null +++ b/code/src/components/Input.css @@ -0,0 +1,55 @@ +.box { + background-color: rgb(250, 255, 253); + width: 80%; + display: flex; + flex-wrap: wrap; + border: 2px solid black; + box-shadow: 10px 10px 5px 0px rgba(0, 0, 0, 0.75); + -webkit-box-shadow: 10px 10px 5px 0px rgba(0, 0, 0, 0.75); + -moz-box-shadow: 10px 10px 5px 0px rgba(0, 0, 0, 0.75); + margin: 2rem; +} + +.input-box { + background-color: rgb(234, 233, 233); +} + +.input-box * { + padding: 0 1rem 0 1rem; +} + +label { + width: 100%; + font-size: 1.2rem; + font-weight: 700; + margin: 1rem 0 0 0; +} + +textarea { + width: 100%; + margin: 0.5rem 0 0 0; + border: 1px solid gray; + background-color: rgb(254, 254, 254); +} + +.input-box button { + height: 3rem; + font-weight: 700; + background-color: rgba(229, 3, 3, 0.5); + border: none; + border-radius: 20px; + margin: 0.5rem 1rem 1rem; +} +button:hover { + cursor: pointer; +} + +.input-box button:focus { + border: 2px solid black; +} +button:disabled, +button[disabled] { + border: 1px solid #999999; + background-color: #cccccc; + color: #666666; +} diff --git a/code/src/components/Input.js b/code/src/components/Input.js new file mode 100644 index 000000000..185279042 --- /dev/null +++ b/code/src/components/Input.js @@ -0,0 +1,55 @@ +/* eslint-disable react/jsx-closing-bracket-location */ +/* eslint-disable no-unused-vars */ +import React from 'react'; +import './Input.css'; + +export const Input = ({ newPost, setNewPost, thoughts, setThoughts }) => { + const handleFormSubmit = (event) => { + event.preventDefault(); + const options = { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ message: newPost }) + }; + + fetch( + 'https://project-happy-thoughts-api-hgwjnnqcva-lz.a.run.app/thoughts', + options + ) + .then((res) => res.json()) + .then((newThought) => { + setThoughts((prevThoughts) => [newThought, ...prevThoughts]); + }) + .finally(() => { + setNewPost(''); + }) + .catch((error) => console.log(error)); + }; + return ( +
+
+