From d52d163ee3d8e0f6fbe6b0a40133af3d80ad3f0f Mon Sep 17 00:00:00 2001 From: Bryan Zhong Date: Mon, 30 Jun 2025 18:25:41 -0400 Subject: [PATCH] Implemented routes, links in navbar and TaskCard, and TaskDetails to view a single task and its user --- package-lock.json | 4 +-- src/App.jsx | 43 +++++++++++++++++++++++-- src/components/AddTask.jsx | 4 +++ src/components/NavBar.jsx | 9 ++++-- src/components/TaskCard.jsx | 7 ++++- src/components/TaskDetails.jsx | 57 ++++++++++++++++++++++++++++++++++ 6 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 src/components/TaskDetails.jsx diff --git a/package-lock.json b/package-lock.json index 16f6f39..ea74e9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "ttp-react-forms", + "name": "ttp-client-side-routing", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "ttp-react-forms", + "name": "ttp-client-side-routing", "version": "1.0.0", "license": "ISC", "dependencies": { diff --git a/src/App.jsx b/src/App.jsx index 14763f7..3a3f17c 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -5,10 +5,32 @@ import "./AppStyles.css"; import TaskList from "./components/TaskList"; import AddTask from "./components/AddTask"; import NavBar from "./components/NavBar"; -import { BrowserRouter as Router, Routes } from "react-router"; +import TaskDetails from "./components/TaskDetails" +import { BrowserRouter as Router, Routes, Route } from "react-router"; + +// const initialTasks = [ +// { +// title: "Get eight hours of sleep", +// description: "Sleepy time tea is a must", +// completed: false, +// }, +// { +// title: "EOD survey", +// description: "The EOD survey is always linked in the Discord", +// completed: true, +// }, +// { +// title: "Install PostgreSQL", +// description: "Don't forget your PostgreSQL password!", +// completed: true, +// }, +// ]; const App = () => { const [tasks, setTasks] = useState([]); + const [users, setUsers] = useState([]); + const complete = tasks.filter(task => task.completed === true); + const incomplete = tasks.filter(task => task.completed === false); async function fetchAllTasks() { try { @@ -19,19 +41,34 @@ const App = () => { } } + async function fetchAllUsers() { + try { + const response = await axios.get("http://localhost:8080/api/users"); + setUsers(response.data); + } catch (error) { + console.error("Error fetching users:", error); + } + } + useEffect(() => { fetchAllTasks(); + fetchAllUsers(); }, []); return (
- - + {/* + */} {/* Currently, we don't have any routes defined. And you can see above that we're rendering the TaskList and AddTask components directly, no matter what our URL looks like. Let's fix that! */} + } /> + } /> + } /> + } /> + } />
); diff --git a/src/components/AddTask.jsx b/src/components/AddTask.jsx index 3673cf1..0a1abff 100644 --- a/src/components/AddTask.jsx +++ b/src/components/AddTask.jsx @@ -1,11 +1,14 @@ import React, { useState } from "react"; import axios from "axios"; import "./AddTaskStyles.css"; +import { useNavigate } from "react-router"; const AddTask = ({ fetchAllTasks }) => { const [title, setTitle] = useState(""); const [description, setDescription] = useState(""); + let navigate = useNavigate(); + const handleSubmit = async (event) => { event.preventDefault(); try { @@ -16,6 +19,7 @@ const AddTask = ({ fetchAllTasks }) => { // After we submit the form, it'd be great if we could navigate back to the home page. // Is there a way to programmatically navigate to the home page? 🤔 fetchAllTasks(); + navigate("/"); } catch (error) { console.error("Error adding task:", error); } diff --git a/src/components/NavBar.jsx b/src/components/NavBar.jsx index 9e63901..07da398 100644 --- a/src/components/NavBar.jsx +++ b/src/components/NavBar.jsx @@ -1,5 +1,6 @@ import React from "react"; import "./NavBarStyles.css"; +import { NavLink } from "react-router"; const NavBar = () => { return ( @@ -8,10 +9,14 @@ const NavBar = () => { This means that every time we click on a link, the page will reload. Let's fix that! */} - All Tasks + {/* All Tasks Completed Tasks Incomplete Tasks - Add Task + Add Task */} + All Tasks + Completed Tasks + Incomplete Tasks + Add Task ); }; diff --git a/src/components/TaskCard.jsx b/src/components/TaskCard.jsx index 82258d9..e5460ee 100644 --- a/src/components/TaskCard.jsx +++ b/src/components/TaskCard.jsx @@ -1,6 +1,7 @@ import React from "react"; import axios from "axios"; import "./TaskCardStyles.css"; +import { Link } from "react-router"; const TaskCard = ({ task, fetchAllTasks }) => { const handleCompleteTask = async () => { @@ -26,7 +27,11 @@ const TaskCard = ({ task, fetchAllTasks }) => { return (
-

{task.title}

+

+ + {task.title} + +

{task.completed ? (

🔄

diff --git a/src/components/TaskDetails.jsx b/src/components/TaskDetails.jsx new file mode 100644 index 0000000..c442326 --- /dev/null +++ b/src/components/TaskDetails.jsx @@ -0,0 +1,57 @@ +import React, { useEffect } from "react"; +import { useParams } from "react-router"; +import axios from "axios"; +import "./TaskCardStyles.css"; + +const TaskDetails = ({ tasks, users, fetchAllTasks }) => { + const params = useParams(); + const id = Number(params.id); + + // useEffect(() => { + // // Fetch the ducks here + // }, []); + + const selectedTask = tasks.find((task) => task.id === id); + const selectedTaskUser = users.find((user) => user.id === selectedTask.userId); + const selectedTaskUserName = selectedTaskUser.name; + + const handleCompleteSelectedTask = async () => { + try { + await axios.patch(`http://localhost:8080/api/tasks/${selectedTask.id}`, { + completed: !selectedTask.completed, + }); + fetchAllTasks(); + } catch (error) { + console.error("Error completing task:", error); + } + }; + + const handleDeleteSelectedTask = async () => { + try { + await axios.delete(`http://localhost:8080/api/tasks/${selectedTask.id}`); + fetchAllTasks(); + } catch (error) { + console.error("Error deleting task:", error); + } + }; + + return ( +
+
+

{selectedTask.title}

+
+ {selectedTask.completed ? ( +

🔄

+ ) : ( +

+ )} +

🗑️

+
+
+

{selectedTask.description}

+

User: {selectedTaskUserName}

+
+ ); +}; + +export default TaskDetails; \ No newline at end of file