Skip to content

Conversation

@KausarShangareeva
Copy link

@KausarShangareeva KausarShangareeva commented Dec 5, 2025

Hi there! πŸ‘‹
I built Happy Thoughts as part of my Technigo JavaScript Bootcamp 2025 journey. This interactive app lets users read, post, and like positive thoughts in a friendly, dynamic, and responsive interface.

You can check out the live website here: Happy Thoughts

Key Features:

  • Post and display happy thoughts dynamically from a backend API
  • Interactive Like Button with animated heart jump effect
  • Posts show how long ago they were added (seconds, minutes, hours, days)
  • Friendly messages for users based on the number of likes
  • Fully responsive design for desktop, tablet, and mobile
  • Styled-components for dynamic styling and animations
  • Reusable React components for buttons, lists, and forms

This project helped me practice React, API data fetching, state management, responsive design, and creating interactive UI components. Hope you enjoy exploring it! 🌟

- Implemented Form component to submit new quotes
- Each quote stored as an object with text, time, and likes
- Added QuoteBox to display quotes with dynamic like button
- Displayed time since submission using getTimeAgo function
- Likes are tracked individually for each quote
- Styled components applied for layout, buttons, and quote cards
@KausarShangareeva KausarShangareeva changed the title feat: add quote submission with individual likes and time ago display Happy Thoughts – Technigo Bootcamp Project 2025 Dec 11, 2025
const [thoughts, setThoughts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [likedpost, setLikedPosts] = useState(function () {
Copy link

@Npahlfer Npahlfer Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work with using localStorage for the liked thoughts!
One thing threw me off a bit and that is how the variable likedpost is named here. When I read it without looking at the rest I thought it was a singular value. But then when I saw the implementation it was an array. likedPosts would have been the correct name.
(Same for the localStorage item name)

A tiny thing, but these things in bigger projects where you kind of gaze over the entirety tend to cause more thinking than it has too :)

} else {
setShowError(false);
const res = await fetch(
"https://happy-thoughts-api-4ful.onrender.com/thoughts",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saving the API url in one place, as a constant (in another file and export it from there) in one place makes it easier when you have to change it. Then you only have to change it in one place :)

onChange={handleChange}
></StyledInput>
<p>
140 /
Copy link

@Npahlfer Npahlfer Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saving numbers like 140 (that is used 3 times here and then in the components RichedLimit and TooLong), in a variable makes it easier to do updates when it has to be changed.

export function RichedLimit({ charCount }) {
return (
<RichedLimitStyled>
You have riched the limit (- {charCount - 140})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

140 should have been a prop, so that this component can be more flexible :)

return (
<TooLongStyled>
Sorr, but your message is <strong>too Long</strong>, plece delete -
{charCount - 140}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

@Npahlfer
Copy link

Really good work Kausar! There were some things about repetition and stuff that should have been props, but other than that I think you did a good job!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants