Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 16 additions & 3 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ 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 Users from "./components/Users";
import UserTasks from "./components/UserTask";

import { BrowserRouter as Router, Routes, Route } from "react-router";


const App = () => {
const [tasks, setTasks] = useState([]);
Expand All @@ -26,12 +31,20 @@ const App = () => {
return (
<div>
<NavBar />
<TaskList tasks={tasks} fetchAllTasks={fetchAllTasks} />
<AddTask fetchAllTasks={fetchAllTasks} />
{/* <TaskList tasks={tasks} fetchAllTasks={fetchAllTasks} /> */}
{/* <AddTask fetchAllTasks={fetchAllTasks} /> */}
<Routes>
{/* 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! */}

<Route path="/" element={<TaskList tasks={tasks} fetchAllTasks={fetchAllTasks} />} />
<Route path="/completed" element={<TaskList tasks={tasks.filter((task) => task.completed)} fetchAllTasks={fetchAllTasks} />} />
<Route path="/incomplete" element={<TaskList tasks={tasks.filter((task) => !task.completed)} fetchAllTasks={fetchAllTasks} />} />
<Route path="/add-task" element={<AddTask fetchAllTasks={fetchAllTasks} />} />
<Route path="/tasks/:id" element={<TaskDetails tasks={tasks} />} />
<Route path="/users" element={<Users />} />
<Route path="/users/:id" element={<UserTasks />} />
</Routes>
</div>
);
Expand Down
4 changes: 3 additions & 1 deletion src/components/AddTask.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
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("");
const navigate = useNavigate();

const handleSubmit = async (event) => {
event.preventDefault();
Expand All @@ -16,6 +17,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);
}
Expand Down
1 change: 1 addition & 0 deletions src/components/NavBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const NavBar = () => {
<a href="/completed">Completed Tasks</a>
<a href="/incomplete">Incomplete Tasks</a>
<a href="/add-task">Add Task</a>
<a href="/users">Users</a>
</nav>
);
};
Expand Down
9 changes: 8 additions & 1 deletion src/components/TaskCard.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import React from "react";
import axios from "axios";
import "./TaskCardStyles.css";
import { Link } from "react-router";


const TaskCard = ({ task, fetchAllTasks }) => {



const handleCompleteTask = async () => {
try {
await axios.patch(`http://localhost:8080/api/tasks/${task.id}`, {
completed: !task.completed,
});
fetchAllTasks();

console.log(task.id);
} catch (error) {
console.error("Error completing task:", error);
}
Expand All @@ -26,7 +33,7 @@ const TaskCard = ({ task, fetchAllTasks }) => {
return (
<div className={`task-card ${task.completed ? "completed" : "incomplete"}`}>
<div className="task-card-header">
<h2>{task.title}</h2>
<Link to={`/tasks/${task.id}`}>{task.title}</Link>
<div className="task-card-header-buttons">
{task.completed ? (
<p onClick={handleCompleteTask}>🔄</p>
Expand Down
42 changes: 42 additions & 0 deletions src/components/TaskDetails.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { useState, useEffect } from "react";
import { useParams } from "react-router";
import axios from "axios";

const TaskDetails = ({ tasks }) => {
const { id } = useParams();
const taskId = Number(id);

const [task, setTask] = useState(null);

useEffect(() => {
if (tasks && tasks.length > 0) {
const localTask = tasks.find((t) => t.id === taskId);
if (localTask) {
setTask(localTask);
}
} else {
axios.get(`/api/tasks/${taskId}`)
.then((res) => setTask(res.data))
.catch((err) => console.error("Error fetching task:", err));
}
}, [tasks, taskId]);


if (!task) return <p>Loading task...</p>;

return (
<div className="task-card">
<div className="task-card-header">
<h1>{task.title}</h1>
<p>{task.description}</p>
<p>{task.completed ? "✅ Completed" : "❌ Incomplete"}</p>
<p>Assigned to: {task.user?.name || "Unknown"}</p>
</div>
</div>
)



}

export default TaskDetails;
1 change: 1 addition & 0 deletions src/components/TaskList.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import TaskCard from "./TaskCard";


const TaskList = ({ tasks, fetchAllTasks }) => {
return (
<div>
Expand Down
39 changes: 39 additions & 0 deletions src/components/UserTask.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { useEffect, useState } from "react";
import { useParams } from "react-router";
import axios from "axios";

const UserTasks = () => {
const { id } = useParams(); // Get user id from URL params
const [tasks, setTasks] = useState([]);

useEffect(() => {
async function fetchUserTasks() {
try {
const response = await axios.get(`http://localhost:8080/api/users/${id}/tasks`);
setTasks(response.data);
} catch (error) {
console.error("Failed to fetch tasks:", error);
}
}
fetchUserTasks();
}, [id]);

return (
<div>
<h2>User {id}'s Tasks</h2>
{tasks.length === 0 ? (
<p>No tasks found for this user.</p>
) : (
<ul>
{tasks.map(task => (
<li key={task.id}>
<strong>{task.title}</strong>: {task.description} [{task.completed ? "Done" : "Pending"}]
</li>
))}
</ul>
)}
</div>
);
};

export default UserTasks;
39 changes: 39 additions & 0 deletions src/components/Users.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react'
import { useState, useEffect } from 'react';
import axios from 'axios';
import { Link } from 'react-router';

const Users = () => {
const [users, setUsers] = useState([]);

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(() => {
fetchAllUsers();
}, []);




return (
<div className="task-card">
<div className="task-card-header">
<h1>Users List</h1>
{users.map((user) => (
<div key={user.id}>
<Link to={`/users/${users.id}`}>{user.name}</Link>
</div>
))}
</div>
</div>
)
}

export default Users