diff --git a/README.md b/README.md
index 6fc6d095..1e41cdd3 100644
--- a/README.md
+++ b/README.md
@@ -6,27 +6,15 @@
# Happy thoughts Project
-In this week's project, you'll be able to practice your React state skills by fetching and posting data to an API.
+The goal of this project was to build a positive social feed for sharing "happy thoughts" by utilizing React’s state management capabilities to fetch, display, and post data to an API. I started by analyzing the structure and requirements, breaking it down into three key areas: fetching recent thoughts, posting new ones, and implementing a "like" feature. Planning involved deciding on the component structure and defining the necessary state for each component to ensure smooth interactions and an intuitive user experience.
-## Getting Started with the Project
+For the build, I used React to manage component state and effects, enabling efficient data fetching and updating. useEffect was used to load initial data from the API upon component mounting, and useState to handle form submissions and like counts. For an improved user experience, I implemented an optimistic UI update, where new thoughts appear instantly in the feed before the API has confirmed the post. This approach provided fast feedback for users, especially for mobile responsiveness and handling slow network connections.
-### Dependency Installation & Startup Development Server
-
-Once cloned, navigate to the project's root directory and this project uses npm (Node Package Manager) to manage its dependencies.
-
-The command below is a combination of installing dependencies, opening up the project on VS Code and it will run a development server on your terminal.
-
-```bash
-npm i && code . && npm run dev
-```
-
-### 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?
+If I had more time, I would focus on refining accessibility by improving screen reader support, adding animations for new thoughts, and implementing a loading spinner to indicate the fetching process. Adding validation feedback and character counting would further enhance the app's interactivity and user experience.
### 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://happy-thoughts-project-technigo.netlify.app/
## Instructions
diff --git a/package.json b/package.json
index 74245b0c..7bef2983 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
+ "date-fns": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
diff --git a/src/AddPost/AddPost.jsx b/src/AddPost/AddPost.jsx
new file mode 100644
index 00000000..d5ef8f31
--- /dev/null
+++ b/src/AddPost/AddPost.jsx
@@ -0,0 +1,13 @@
+// AddPost.jsx
+
+import { PostForm } from "./AddPostComponents/PostForm";
+
+export const AddPost = ({ addNewThought, url }) => {
+ return (
+
;
-};
+ // Hooks
+ const [recentThoughts, setRecentThoughts] = useState([]);
+ const [loading, setLoading] = useState(true);
+ // URL for GET and POST thoughts to API
+ const URL_THOUGHTS = "https://project-happy-thoughts-api-ek.onrender.com/thoughts";
+ // OLD API
+ // const URL_THOUGHTS = "https://happy-thoughts-ux7hkzgmwa-uc.a.run.app/thoughts";
+
+ // Function to fetch recent thoughts
+ const fetchRecentThoughts = async () => {
+ setLoading(true); // Show Loading message
+ try {
+ const response = await fetch(URL_THOUGHTS);
+ if (response.ok) {
+ const data = await response.json();
+ setRecentThoughts(data);
+ } else {
+ console.error("Failed to fetch thoughts");
+ }
+ } catch (error) {
+ console.error("Error fetching data:", error);
+ } finally {
+ setLoading(false); // Do not show loading message
+ }
+ };
+
+ // useEffect hook and call for fetchRecentThought function. ending with empty array to only make the API call once.
+ useEffect(() => {
+ fetchRecentThoughts();
+ }, []);
+
+ // Function that adds a new thought
+ const addNewThought = (newThought) => {
+ setRecentThoughts([newThought, ...recentThoughts]); // Update UI in the web browser before API, to make it more user firendly
+ };
+
+ return (
+ // Send addNewThought function as a prop to AddPost
+
+
+
+
+
+ {/* If thoughts are loading, show loading message */}
+ {loading ?
+
+ )}
+
+ );
+};
\ No newline at end of file
diff --git a/src/Post/Post.jsx b/src/Post/Post.jsx
new file mode 100644
index 00000000..eb4f2444
--- /dev/null
+++ b/src/Post/Post.jsx
@@ -0,0 +1,22 @@
+// Post.jsx
+
+import { PostMessage } from "./PostComponents/PostMessage";
+import { PostLikes } from "./PostComponents/PostLikes";
+import { PostDate } from "./PostComponents/PostDate";
+
+export const Post = ({ recentThought }) => {
+ return (
+
+ {/* Recent thought message from the API is sent as a prop to PostMessage */}
+
+
+
+ {/* Number of hearts in the API on each thought, and the ID of each thought is sent as a prop to PostLikes */}
+
+
+ {/* Recent thought created date from the API is sent as a prop to PostDate */}
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src/Post/PostComponents/PostDate.jsx b/src/Post/PostComponents/PostDate.jsx
new file mode 100644
index 00000000..9969db71
--- /dev/null
+++ b/src/Post/PostComponents/PostDate.jsx
@@ -0,0 +1,16 @@
+// PostDate.jsx
+
+// Downloaded in terminal and then imported here to make dates look pretty
+import { formatDistanceToNow } from "date-fns";
+
+export const PostDate = ({ recentThoughtDate }) => {
+ const date = new Date(recentThoughtDate);
+ const timeAgo = formatDistanceToNow(date, { addSuffix: true });
+
+ return (
+
+
{timeAgo}
+
+ );
+};
+
diff --git a/src/Post/PostComponents/PostLikes.jsx b/src/Post/PostComponents/PostLikes.jsx
new file mode 100644
index 00000000..05cd0525
--- /dev/null
+++ b/src/Post/PostComponents/PostLikes.jsx
@@ -0,0 +1,45 @@
+// PostLikes.jsx
+
+import { useState } from "react";
+
+export const PostLikes = ({ recentThoughtLikes, thoughtId }) => {
+ // Hooks
+ const [newLike, setNewLike] = useState(recentThoughtLikes);
+ // API for POST number of hearts, thoughtID keeps track of witch thought that should have a like
+ const URL_LIKES = `https://project-happy-thoughts-api-ek.onrender.com/thoughts/${thoughtId}/like`;
+ // OLD API
+ //const URL_LIKES = `https://happy-thoughts-ux7hkzgmwa-uc.a.run.app/thoughts/${thoughtId}/like`;
+
+ // Update button class to change color depending on likes
+ const buttonClass = newLike > 0 ? "post-btn liked" : "post-btn";
+
+ // Function that POST +1 likes to the API
+ const handleLikeClick = async () => {
+ try {
+ const response = await fetch(URL_LIKES, {
+ method: "POST",
+ });
+ if (response.ok) {
+ setNewLike(newLike + 1); // Uppdate in web browser/lokally number of likes (before API)
+ } else {
+ console.error("Failed to like the thought");
+ }
+ } catch (error) {
+ console.error("Error during like:", error);
+ }
+ };
+
+ return (
+
+
+
+ {/* Shows number of likes */}
+
x {newLike}
+
+ );
+};
\ No newline at end of file
diff --git a/src/Post/PostComponents/PostMessage.jsx b/src/Post/PostComponents/PostMessage.jsx
new file mode 100644
index 00000000..224f3cff
--- /dev/null
+++ b/src/Post/PostComponents/PostMessage.jsx
@@ -0,0 +1,9 @@
+// PostMessage.jsx
+
+export const PostMessage = ({ recentThoughtMessage }) => {
+ return (
+