-
Notifications
You must be signed in to change notification settings - Fork 431
Project happy thoughts #449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
ae24ac1
fc3e795
b42822a
94ad92a
ee7e1a5
0a92b37
c2537c6
c1bdcb1
1441fdc
55e06fb
533be9d
7ee0d11
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,13 @@ | ||
| # 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 project done in React, with the purpose of displaying API:s in both GET and POST. | ||
|
|
||
| ## 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? | ||
| I struggled a lot with this project. I had a hard time structuring the code in a way that felt logical to me. After consulting chat-GPT and viewing a few other students projects I finally found my way. | ||
| If I had more time I would find a way to align the timer better. It frustrates me that it's not properly justified to the right, the alignment shifts depending on the length of the sentence. | ||
| I would also implement a window alert. I chose not to use one now, since I didn't have time to figure out how to only show it if the user tries to submit with the wrong length, it kept showing on every keystroke from 1-4. | ||
|
|
||
| ## 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://sunnyhappythoughts.netlify.app/ |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,68 @@ | ||
| import React from 'react'; | ||
| /* eslint-disable no-underscore-dangle */ | ||
| /* eslint-disable no-unused-vars */ | ||
| import React, { useState, useEffect } from 'react'; | ||
| import { SubmitThoughts } from 'components/SubmitThoughts'; | ||
| import { ListThoughts } from 'components/ListThoughts'; | ||
|
|
||
| export const App = () => { | ||
| const [thoughtsList, setThoughtsList] = useState([]) | ||
| const [submitThoughts, setSubmitThoughts] = useState('') | ||
| const [loading, setLoading] = useState(false) | ||
|
|
||
| const fetchThoughts = () => { | ||
| setLoading(true) | ||
| fetch('https://project-happy-thoughts-api-l8j3.onrender.com/thoughts') | ||
| .then((response) => response.json()) | ||
| .then((data) => setThoughtsList(data.response)) | ||
| .catch((error) => console.log(error)) | ||
| .finally(() => { setLoading(false) }) | ||
| } | ||
|
|
||
| useEffect(() => { | ||
| fetchThoughts() | ||
| }, []) | ||
|
|
||
| const handleThoughtChange = (event) => { | ||
| setSubmitThoughts(event.target.value) | ||
| } | ||
|
|
||
| const handleFormSubmit = (event) => { | ||
| event.preventDefault() | ||
| setLoading(true) | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the "handleFormSubmit" handles the submission of a new thought it could be moved into your component "submitThoughts.js" instead if we want to continue on "cleaning" the app.js a bit. |
||
| const options = { | ||
| method: 'POST', | ||
| body: JSON.stringify({ message: submitThoughts }), | ||
| headers: { 'Content-Type': 'application/json' } | ||
| } | ||
| fetch('https://project-happy-thoughts-api-l8j3.onrender.com/thoughts', options) | ||
| .then((response) => response.json()) | ||
| .then((data) => { setThoughtsList([data.response, ...thoughtsList]) }) | ||
| .catch((error) => console.log(error)) | ||
| .finally(() => { setLoading(false); setSubmitThoughts('') }) | ||
| } | ||
|
|
||
| const handleLikeChange = (thoughtId) => { | ||
| const options = { | ||
| method: 'POST', | ||
| headers: { 'Content-Type': 'application/json' } | ||
| } | ||
| fetch(`https://project-happy-thoughts-api-l8j3.onrender.com/thoughts/${thoughtId}/like`, options) | ||
| .then((response) => response.json()) | ||
| .catch((error) => console.log(error)) | ||
| .finally(() => fetchThoughts('')) | ||
| } | ||
|
|
||
| return ( | ||
| <div> | ||
| Find me in src/app.js! | ||
| </div> | ||
| <section className="mainBody"> | ||
| <SubmitThoughts | ||
| submitThoughts={submitThoughts} | ||
| handleThoughtChange={handleThoughtChange} | ||
| handleFormSubmit={handleFormSubmit} /> | ||
| <ListThoughts | ||
| loading={loading} | ||
| thoughtsList={thoughtsList} | ||
| handleLikeChange={handleLikeChange} /> | ||
| </section> | ||
| ); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| /* eslint-disable no-underscore-dangle */ | ||
| import React from 'react' | ||
| import moment from 'moment' | ||
|
|
||
| export const ListThoughts = ({ loading, thoughtsList, handleLikeChange }) => { | ||
| if (loading) { | ||
| return <h2>Loading...</h2> | ||
| } | ||
| const getTimeAgo = (createdAt) => { | ||
| const timeAgo = moment(createdAt).fromNow(); | ||
| return timeAgo; | ||
| } | ||
| return ( | ||
| <section className="listSection"> | ||
| {thoughtsList.map((thought) => { | ||
| return ( | ||
| <div className="listBox"> | ||
| <p className="thought" key={thought._id}>{thought.message}</p> | ||
| <div className="list"> | ||
| <button | ||
| className={thought.hearts === 0 ? 'heartBtn' : 'likedBtn'} | ||
| type="submit" | ||
| onClick={() => handleLikeChange(thought._id)}> | ||
| 💛 | ||
| </button> | ||
| <p>x {thought.hearts}</p> | ||
| <div> | ||
| <p className="time">{getTimeAgo(thought.createdAt)}</p> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ) | ||
| })} | ||
| </section> | ||
|
Comment on lines
+13
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very nice and tidy indentation, pretty code! |
||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| /* eslint-disable react/no-unescaped-entities */ | ||
| import React, { useState } from 'react' | ||
|
|
||
| export const SubmitThoughts = ({ handleFormSubmit, submitThoughts, handleThoughtChange }) => { | ||
| const turnCounterRed = submitThoughts.length > 140 ? 'counter-red' : 'counter'; | ||
| const [errorAlert, setErrorAlert] = useState('') | ||
| const handleLengthError = (event) => { | ||
| const textLength = event.target.value.length | ||
| if (textLength < 5) { | ||
| setErrorAlert('Your message needs to be at least 5 characters long. 😊') | ||
| } else if (textLength > 140) { | ||
| setErrorAlert('Whoa Nelly! Save the essay for your portfolio. 😄') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wish I tried writing a message that was to long, fuunny! 😂 |
||
| } else { | ||
| setErrorAlert('') | ||
| } | ||
| handleThoughtChange(event) | ||
| } | ||
| return ( | ||
| <section className="submitBox"> | ||
| <h1>What's making you happy right now?</h1> | ||
| <form onSubmit={handleFormSubmit}> | ||
| <textarea type="text" value={submitThoughts} onChange={handleLengthError} /> | ||
| <div> | ||
| <p className={turnCounterRed}>{submitThoughts.length} / 140</p> | ||
| </div> | ||
| <div className="errorAlert">{errorAlert}</div> | ||
| <button | ||
| type="submit"> | ||
| 💛 Send happy thought 💛 | ||
| </button> | ||
| </form> | ||
| </section> | ||
| ) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hook is to call the fetchThoughts function when the component is mounted so this should/could/would also be moved if so we were to change the structure for a "cleaner" App.js