diff --git a/README.md b/README.md index 41ebece2..775bfdda 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # Happy Thoughts + +Netlify link: https://happy-thoughts-25.netlify.app/ \ No newline at end of file diff --git a/index.html b/index.html index d4492e94..a8465b8b 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,10 @@ - + + + + Happy Thoughts diff --git a/package.json b/package.json index 2f66d295..c82846a1 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,10 @@ "preview": "vite preview" }, "dependencies": { + "dayjs": "^1.11.19", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "styled-components": "^6.1.19" }, "devDependencies": { "@eslint/js": "^9.21.0", diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 00000000..4ba09560 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/vite.svg b/public/vite.svg deleted file mode 100644 index e7b8dfb1..00000000 --- a/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index 07f2cbdf..f3a88b38 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,5 +1,219 @@ +import { useState, useEffect, useRef } from "react" +import styled from "styled-components" + +import { ThemeProvider } from "styled-components" +import { GlobalStyles } from "./styling/globalStyles.js" +import { theme } from "./styling/theme.js" +import { Header } from "./components/layout/Header.js" +import { Hero } from "./components/layout/Hero.js" +import { Footer } from "./components/layout/Footer.js" +import { InputCard } from "./components/input/InputCard.jsx" +import { MessageList } from "./components/messages/MessageList.jsx" +import { HeartLoader } from "./styling/LoadingAnime.jsx" + export const App = () => { + + const scrollRef = useRef(null) + + const [messages, setMessages] = useState([]) + const [loading, setLoading] = useState(true) + const [error, setError] = useState(null) + const [scroll, setScroll] = useState(false) + + // State to track liked posts in local storage + const [likedPosts, setLikedPosts] = useState(() => { + const saved = localStorage.getItem("likedPosts") + return saved ? JSON.parse(saved) : [] + }) + + // fetch messages from API + interval polling + useEffect(() => { + const fetchMessages = () => { + fetch("https://happy-thoughts-api-4ful.onrender.com/thoughts") + .then(res => { + if (!res.ok) { + throw new Error(`Failed to fetch: ${res.status}`) + } + return res.json() + }) + .then(data => { + setMessages(data) + setLoading(false) + setError(null) + }) + .catch(error => { + console.error("Error fetching messages:", error) + setError("Something went wrong. Please try again ❤️") + setLoading(false) + }) + } + + fetchMessages() // Initial fetch + + // Set interval to fetch messages every 30 seconds + const intervalID = setInterval(fetchMessages, 30000) + + // Cleanup interval on component unmount + return () => clearInterval(intervalID) + },[]) + + // Update local storage when likedPosts changes + useEffect(() => { + localStorage.setItem("likedPosts", JSON.stringify(likedPosts)) + }, [likedPosts]) + + // Post new message to API + const addMessage = async (newText) => { + try { + const response = await fetch("https://happy-thoughts-api-4ful.onrender.com/thoughts", + { + method: "POST", + headers: {"Content-Type": "application/json"}, + body: JSON.stringify({ message: newText}) + }) + + if (!response.ok) { + throw new Error("Failed to post your message 💔") + } + + const data = await response.json() + setMessages(prev => [data, ...prev]) + setScroll(true) + + } catch (error) { + console.error("Error posting message:", error) + setError("Something went wrong. Please try again ❤️") + } + } + + useEffect(() => { + if (scroll && scrollRef.current) { + scrollRef.current.scrollTo({ + top: 0, + behavior: "smooth" + }) + setScroll(false) + } + },[messages, scroll]) + + // Send like to API + const increaseHeart = async (id) => { + const message = messages.find(msg => msg._id === id) + + try { + const response = await fetch(`https://happy-thoughts-api-4ful.onrender.com/thoughts/${message._id}/like`, + { method: "POST"} + ) + + if (!response.ok) { + throw new Error("Failed to send like 💔") + } + + const updated = messages.map(msg => + msg._id === id + ? { ...msg, hearts: msg.hearts + 1 } + : msg + ) + setMessages(updated) + + // Update likedPosts state + setLikedPosts(prev => + prev.includes(id) ? prev : [...prev, id] + ) + + } catch (error) { + console.error("Error liking message:", error) + setError("Failed to send like ❤️‍🩹 Try again!") + } + } + return ( -

Happy Thoughts

+ <> + + + + +
+ + + + + + + + {error && {error}} + + {loading ? ( + + +

Loading Happy Thoughts...

+
+ ) : ( + + + + + + )} + +