diff --git a/.env b/.env
new file mode 100644
index 00000000..07904587
--- /dev/null
+++ b/.env
@@ -0,0 +1,2 @@
+VITE_API_URL=http://localhost:5000
+
diff --git a/App.jsx b/App.jsx
new file mode 100644
index 00000000..1ac87632
--- /dev/null
+++ b/App.jsx
@@ -0,0 +1,61 @@
+// src/App.jsx
+import React, { useState, useEffect } from 'react';
+import ThoughtForm from './thoughtForm.jsx';
+import ThoughtList from './ThoughtList.jsx';
+import HappyIcon from './HappyIcon.jsx';
+
+function App() {
+ const [thoughts, setThoughts] = useState([]);
+ const [loading, setLoading] = useState(false);
+
+ // Fetch initial data function//Fetch inicial de pensamientos
+ useEffect(() => {
+ setLoading(true);
+ fetch('https://happy-thoughts-ux7hkzgmwa-uc.a.run.app/thoughts')
+ .then((res) => res.json())
+ .then((data) => {
+ setThoughts(data);
+ setLoading(false);
+ })
+ .catch((error) => {
+ console.error('Error fetching thoughts:', error);
+ setLoading(false);
+ });
+ }, []);
+
+ // Add thought function//Función para agregar un nuevo pensamiento
+ const addThought = (newThought) => {
+ setThoughts((prevThoughts) => [newThought, ...prevThoughts]);
+ };
+
+ // Handle likes function//Función para manejar el "like"
+ const handleLike = (id) => {
+ fetch(`https://happy-thoughts-ux7hkzgmwa-uc.a.run.app/thoughts/${id}/like`, {
+ method: 'POST',
+ })
+ .then((res) => res.json())
+ .then(() => {
+ setThoughts((prevThoughts) =>
+ prevThoughts.map((thought) =>
+ thought._id === id ? { ...thought, hearts: thought.hearts + 1 } : thought
+ )
+ );
+ })
+ .catch((error) => console.error('Error updating likes:', error));
+ };
+
+ return (
+
+
Happy Thoughts
+
{/* Muestra el SVG */}
+
+ {loading ? (
+
Loading thoughts...
+ ) : (
+
+ )}
+
+ );
+}
+
+export default App;
diff --git a/HappyIcon.jsx b/HappyIcon.jsx
new file mode 100644
index 00000000..0f25a3ad
--- /dev/null
+++ b/HappyIcon.jsx
@@ -0,0 +1,11 @@
+// src/components/HappyIcon.jsx
+import React from 'react';
+import happySVG from './assets/happy-thoughts.svg';
+
+const HappyIcon = () => {
+ return (
+
+ );
+};
+
+export default HappyIcon;
diff --git a/Maryyy_ux-project-happy-thoughts-vite b/Maryyy_ux-project-happy-thoughts-vite
new file mode 160000
index 00000000..864c5b27
--- /dev/null
+++ b/Maryyy_ux-project-happy-thoughts-vite
@@ -0,0 +1 @@
+Subproject commit 864c5b2717e67287d4209223634c3c2dfdf3a687
diff --git a/Maryyy_ux-project-happy-thoughts-vite - copia.code-workspace b/Maryyy_ux-project-happy-thoughts-vite - copia.code-workspace
new file mode 100644
index 00000000..d2078eaa
--- /dev/null
+++ b/Maryyy_ux-project-happy-thoughts-vite - copia.code-workspace
@@ -0,0 +1,11 @@
+{
+ "folders": [
+ {
+ "path": "."
+ },
+ {
+ "path": "../project-happy-thoughts-api"
+ }
+ ],
+ "settings": {}
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 6fc6d095..59fc0239 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,8 @@
-
# 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.
+Weeks 11 project: fetching and posting data to an API.
+Netlify link: https://671e98a974664db913b722e6--ubiquitous-tiramisu-a45993.netlify.app/
## Getting Started with the Project
@@ -24,9 +20,7 @@ npm i && code . && npm run dev
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?
-### 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.
## Instructions
diff --git a/ThoughtItem.jsx b/ThoughtItem.jsx
new file mode 100644
index 00000000..6de2a836
--- /dev/null
+++ b/ThoughtItem.jsx
@@ -0,0 +1,31 @@
+import React, { useState, useEffect } from 'react';
+
+function ThoughtItem({ thought, onLike }) {
+ const [isNew, setIsNew] = useState(true);
+
+ useEffect(() => {
+ const timer = setTimeout(() => setIsNew(false), 60000);
+ return () => clearTimeout(timer);
+ }, []);
+
+ // Display only hours and minutes//Ajuste para mostrar solo horas y minutos
+ const formatDate = (date) => {
+ const d = new Date(date);
+ return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
+ };
+
+ return (
+
+
{thought.message}
+
+
{formatDate(thought.createdAt)}
+
+ onLike(thought._id)}>❤️
+ {thought.hearts}
+
+
+
+ );
+}
+
+export default ThoughtItem;
diff --git a/ThoughtList.jsx b/ThoughtList.jsx
new file mode 100644
index 00000000..4ffeb184
--- /dev/null
+++ b/ThoughtList.jsx
@@ -0,0 +1,19 @@
+import React from 'react';
+import ThoughtItem from './ThoughtItem.jsx';
+
+function ThoughtList({ thoughts, onLike }) {
+ // Only up to last 4 thoughts and by date priority//Limitar a los últimos 4 pensamientos y ordenar por fecha
+ const limitedThoughts = thoughts
+ .sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)) // By date priority//Ordenar por fecha
+ .slice(0, 4); // Only last 4 thoughts//Limitar a los últimos 4 pensamientos
+
+ return (
+
+ {limitedThoughts.map((thought) => (
+
+ ))}
+
+ );
+}
+
+export default ThoughtList;
diff --git a/index.css b/index.css
new file mode 100644
index 00000000..852f2009
--- /dev/null
+++ b/index.css
@@ -0,0 +1,217 @@
+:root {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
+ "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
+ sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+code {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
+ monospace;
+}
+
+body {
+ font-family: Arial, sans-serif;
+
+}
+
+.App {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 30px;
+}
+
+form,
+.thought-list {
+ width: 100%;
+ max-width: 500px;
+ margin: 20px 0;
+}
+
+textarea {
+ width: 100%;
+ padding: 40px;
+ font-size: 1.2em;
+ margin-bottom: 10px;
+}
+
+.character-counter {
+ font-size: 0.9em;
+ text-align: right;
+ color: #555;
+ margin-top: -10px;
+ margin-bottom: 10px;
+}
+
+/* Botón de "Send Happy Thought" */
+.button-send {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 10px 20px;
+ font-size: 1em;
+ background-color: #ff7675;
+ color: #fff;
+ border: none;
+ cursor: pointer;
+ border-radius: 30px;
+ gap: 8px;
+}
+
+
+button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 10px;
+ font-size: 1em;
+ background-color: #ff7675;
+ color: #fff;
+ border: none;
+ cursor: pointer;
+ border-radius: 30px;
+ gap: 4px;
+}
+
+/* Contenedor de cada pensamiento */
+.thought-item {
+ padding: 15px;
+ border: 1px solid #b3afaf;
+ margin-bottom: 10px;
+ border-radius: 5px;
+ box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.2);
+ max-width: 100%;
+}
+
+/* Fondo gris en el pensamiento más reciente */
+.thought-item.new-thought {
+ background-color: #f0f0f0;
+ animation: fadeOutBg 60s forwards;
+ /* Cambia a blanco tras 1 min */
+}
+
+@keyframes fadeOutBg {
+ 0% {
+ background-color: #f0f0f0;
+ }
+
+ 100% {
+ background-color: #ffffff;
+ }
+}
+
+/* Footer de cada pensamiento */
+.thought-footer {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-direction: row-reverse;
+ font-size: 0.8em;
+}
+
+.thought-footer .like-counter {
+ margin-right: 10px;
+ margin: 5px 0;
+ font-size: 0.8em;
+}
+
+.date-time {
+ margin-left: auto;
+}
+
+.error {
+ color: red;
+ font-size: 0.8em;
+}
+
+/* Estilos para el logo de la página */
+.logo {
+ width: 100%;
+ height: auto;
+ max-height: 30px;
+}
+
+/* Contraste mejorado */
+textarea,
+button,
+.thought-item {
+ color: #333;
+}
+
+/* Asegurar que los contadores de likes estén afuera del botón */
+.like-button {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ /* Espacio entre botón y contador */
+}
+
+@media (max-width: 768px) {
+ .App {
+ padding: 10px;
+ /* Más ajuste en tablets y móviles */
+ max-width: 100%;
+ }
+
+ .form-container,
+ .thought-item {
+ max-width: 100%;
+ padding: 8px;
+ }
+
+ textarea {
+ padding: 8px;
+ font-size: 0.95em;
+ }
+
+ .button-send {
+ font-size: 0.9em;
+ padding: 6px 12px;
+ }
+}
+
+@media (max-width: 400px) {
+ :root {
+ font-size: 14px;
+ /* Ajuste base para pantallas pequeñas */
+ }
+
+ .App {
+ padding: 5px;
+ }
+
+ form,
+ .thought-list,
+ .form-container {
+ max-width: 320px;
+ /* Ancho para adaptarse a pantallas pequeñas */
+ padding: 5px;
+ }
+
+ .logo {
+ max-height: 35px;
+ margin-bottom: 5px;
+ }
+
+ textarea {
+ padding: 10px;
+ font-size: 0.9em;
+ }
+
+ .button-send {
+ padding: 8px 12px;
+ font-size: 0.9em;
+ }
+
+ .thought-item {
+ padding: 10px;
+ margin-bottom: 8px;
+ }
+
+ .thought-footer {
+ font-size: 0.75em;
+ }
+}
\ No newline at end of file
diff --git a/index.html b/index.html
index 21cce4e0..a08698b0 100644
--- a/index.html
+++ b/index.html
@@ -1,13 +1,16 @@
-
-
-
-
- Happy Thought - Project - Week 7
-
-
-
-
-
-
+
+
+
+
+
+ Happy Thought - Project - Week 11
+
+
+
+
+
+
+
+