feat: Update task status from 'Backlog' to 'To Do', adjust image source paths, and enhance task rendering in various components

This commit is contained in:
2024-11-06 17:32:12 +02:00
parent 55e81899ea
commit a06a190574
13 changed files with 120 additions and 46 deletions

View File

@@ -13,7 +13,7 @@ const ModalNewTask = ({ isOpen, onClose, id = null }: Props) => {
const [createTask, { isLoading }] = useCreateTaskMutation();
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const [status, setStatus] = useState<Status>(Status.Backlog);
const [status, setStatus] = useState<Status>(Status.ToDo);
const [priority, setPriority] = useState<Priority>(Priority.Backlog);
const [tags, setTags] = useState("");
const [startDate, setStartDate] = useState("");
@@ -87,7 +87,7 @@ const ModalNewTask = ({ isOpen, onClose, id = null }: Props) => {
}
>
<option value="">Select Status</option>
<option value={Status.Backlog}>Backlog</option>
<option value={Status.ToDo}>Backlog</option>
<option value={Status.InProgress}>In Progress</option>
<option value={Status.TestReview}>Test/Review</option>
<option value={Status.Done}>Done</option>

View File

@@ -25,11 +25,13 @@ import { usePathname } from "next/navigation";
import { setIsSidebarCollapsed } from "@/state";
import { useAppDispatch, useAppSelector } from "@/app/redux";
import Link from "next/link";
import { useGetProjectsQuery } from "@/state/api";
const Sidebar = () => {
const [showProjects, setShowProjects] = React.useState(true);
const [showPriority, setShowPriority] = React.useState(true);
const { data: projects } = useGetProjectsQuery();
const dispatch = useAppDispatch();
const isSidebarCollapsed = useAppSelector(
(state) => state.global.isSidebarCollapsed,
@@ -77,7 +79,12 @@ const Sidebar = () => {
</nav>
<button
onClick={() => setShowProjects((prev) => !prev)}
onClick={() =>
setShowProjects((prev) => {
console.log(prev);
return !prev;
})
}
className="flex w-full items-center justify-between px-8 py-3 text-gray-500"
>
<span className="">Projects</span>
@@ -87,6 +94,15 @@ const Sidebar = () => {
<ChevronUpCircleIcon className="h-5 w-5" />
)}
</button>
{showProjects &&
projects?.map((project) => (
<SidebarLink
key={project.id}
icon={Briefcase}
label={project.name}
href={`/projects/${project.id}`}
/>
))}
<button
onClick={() => setShowPriority((prev) => !prev)}

View File

@@ -16,7 +16,7 @@ const TaskCard = ({ task }: Props) => {
<div className="flex flex-wrap">
{task.attachments && task.attachments.length > 0 && (
<Image
src={`${task.attachments[0].fileURL}`}
src={`/${task.attachments[0].fileURL}`}
alt={task.attachments[0].fileName}
width={400}
height={200}

View File

@@ -11,7 +11,7 @@ const UserCard = ({ user }: Props) => {
<div className="flex items-center rounded border p-4 shadow">
{user.profilePictureUrl && (
<Image
src={`${user.profilePictureUrl}`}
src={`/${user.profilePictureUrl}`}
alt="profile picture"
width={32}
height={32}

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
"use client";
import {
@@ -5,7 +6,7 @@ import {
Project,
Task,
useGetProjectsQuery,
useGetTasksQuery,
useGetTasksByUserQuery,
} from "@/state/api";
import React from "react";
import { useAppSelector } from "../redux";
@@ -28,19 +29,62 @@ import { dataGridSxStyles } from "@/lib/utils";
const taskColumns: GridColDef[] = [
{ field: "title", headerName: "Title", width: 200 },
{ field: "status", headerName: "Status", width: 150 },
{ field: "priority", headerName: "Priority", width: 150 },
{
field: "status",
headerName: "Status",
width: 150,
renderCell: (params) => (
<span
className={`inline-flex rounded-full px-2 text-xs font-semibold leading-5 ${
params.value === "In Progress"
? "bg-green-200 text-green-600"
: params.value === "Test/Review"
? "bg-green-200 text-green-600"
: params.value === "Done"
? "bg-green-400 text-green-800"
: "bg-gray-400 text-gray-800"
}`}
>
{params.value}
</span>
),
},
{
field: "priority",
headerName: "Priority",
width: 150,
renderCell: (params) => (
<span
className={`inline-flex rounded-full px-2 text-xs font-semibold leading-5 ${
params.value === "Urgent"
? "bg-red-200 text-red-700"
: params.value === "High"
? "bg-yellow-200 text-yellow-700"
: params.value === "Medium"
? "bg-green-200 text-green-700"
: params.value === "Low"
? "bg-blue-200 text-blue-700"
: "bg-gray-200 text-gray-700"
}`}
>
{params.value}
</span>
),
},
{ field: "dueDate", headerName: "Due Date", width: 150 },
];
const statusColors = ["#0088FE", "#00C49F", "#FFBB28", "#FF8042"];
const HomePage = () => {
const userId = 1;
const {
data: tasks,
isLoading: tasksLoading,
isError: tasksError,
} = useGetTasksQuery({ projectId: parseInt("1") });
} = useGetTasksByUserQuery(userId || 0, {
skip: userId === null,
});
const { data: projects, isLoading: isProjectsLoading } =
useGetProjectsQuery();

View File

@@ -83,6 +83,8 @@ const ReusablePriorityPage = ({ priority }: Props) => {
skip: userId === null,
});
console.log(tasks);
const isDarkMode = useAppSelector((state) => state.global.isDarkMode);
const filteredTasks = tasks?.filter(

View File

@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import React from "react";
import { useGetTasksQuery, useUpdateTaskStatusMutation } from "@/state/api";
import React from "react";
import { DndProvider, useDrag, useDrop } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { Task as TaskType } from "@/state/api";
@@ -13,28 +13,27 @@ type BoardProps = {
setIsModalNewTaskOpen: (isOpen: boolean) => void;
};
const taskStatuses = ["Backlog", "In Progress", "Test/Review", "Done"];
const taskStatus = ["To Do", "In Progress", "Test/Review", "Done"];
function BoardView({ id, setIsModalNewTaskOpen }: BoardProps) {
const BoardView = ({ id, setIsModalNewTaskOpen }: BoardProps) => {
const {
data: tasks,
isLoading,
error,
} = useGetTasksQuery({ projectId: Number(id) });
const [updateTaskStatus] = useUpdateTaskStatusMutation();
const moveTask = (taskId: number, status: string) => {
updateTaskStatus({ taskId, status });
const moveTask = (taskId: number, toStatus: string) => {
updateTaskStatus({ taskId, status: toStatus });
};
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error fetching tasks</div>;
if (error) return <div>An error occurred while fetching tasks</div>;
return (
<DndProvider backend={HTML5Backend}>
<div className="grid grid-cols-1 gap-4 p-4 md:grid-cols-2 xl:grid-cols-4">
{taskStatuses.map((status) => (
{taskStatus.map((status) => (
<TaskColumn
key={status}
status={status}
@@ -46,7 +45,7 @@ function BoardView({ id, setIsModalNewTaskOpen }: BoardProps) {
</div>
</DndProvider>
);
}
};
type TaskColumnProps = {
status: string;
@@ -63,10 +62,8 @@ const TaskColumn = ({
}: TaskColumnProps) => {
const [{ isOver }, drop] = useDrop(() => ({
accept: "task",
drop: (item: { id: number }) => {
moveTask(item.id, status);
},
collect: (monitor) => ({
drop: (item: { id: number }) => moveTask(item.id, status),
collect: (monitor: any) => ({
isOver: !!monitor.isOver(),
}),
}));
@@ -74,7 +71,7 @@ const TaskColumn = ({
const tasksCount = tasks.filter((task) => task.status === status).length;
const statusColors: any = {
Backlog: "#800000",
"To Do": "#800000",
"In Progress": "#efcc00",
"Test/Review": "#00008b",
Done: "#006400",
@@ -178,7 +175,7 @@ const Task = ({ task }: TaskProps) => {
>
{task.attachments && task.attachments.length > 0 && (
<Image
src={`${task.attachments[0].fileURL}`}
src={`/${task.attachments[0].fileURL}`}
alt={task.attachments[0].fileName}
width={400}
height={200}
@@ -230,7 +227,7 @@ const Task = ({ task }: TaskProps) => {
{task.assignee && (
<Image
key={task.assignee.userId}
src={`${task.assignee.profilePictureUrl!}`}
src={`/${task.assignee.profilePictureUrl!}`}
alt={task.assignee.username}
width={30}
height={30}
@@ -240,7 +237,7 @@ const Task = ({ task }: TaskProps) => {
{task.author && (
<Image
key={task.author.userId}
src={`${task.author.profilePictureUrl!}`}
src={`/${task.author.profilePictureUrl!}`}
alt={task.author.username}
width={30}
height={30}

View File

@@ -11,13 +11,6 @@ type Props = {
setIsModalNewTaskOpen: (isOpen: boolean) => void;
};
const statusClasses: any = {
Backlog: "bg-red-400 text-red-800",
"In Progress": "bg-yellow-400 text-yellow-800",
"Test/Review": "bg-blue-400 text-blue-800",
Done: "bg-green-400 text-green-800",
};
const columns: GridColDef[] = [
{
field: "title",
@@ -33,10 +26,17 @@ const columns: GridColDef[] = [
field: "status",
headerName: "Status",
width: 130,
// Render a colored badge in className based on the status
renderCell: (params) => (
<span
className={`inline-flex rounded-full px-2 text-xs font-semibold leading-5 ${statusClasses[params.value] || "bg-gray-400 text-gray-800"}`}
className={`inline-flex rounded-full px-2 text-xs font-semibold leading-5 ${
params.value === "In Progress"
? "bg-green-200 text-green-600"
: params.value === "Test/Review"
? "bg-green-200 text-green-600"
: params.value === "Done"
? "bg-green-400 text-green-800"
: "bg-gray-400 text-gray-800"
}`}
>
{params.value}
</span>
@@ -46,6 +46,23 @@ const columns: GridColDef[] = [
field: "priority",
headerName: "Priority",
width: 75,
renderCell: (params) => (
<span
className={`inline-flex rounded-full px-2 text-xs font-semibold leading-5 ${
params.value === "Urgent"
? "bg-red-200 text-red-700"
: params.value === "High"
? "bg-yellow-200 text-yellow-700"
: params.value === "Medium"
? "bg-green-200 text-green-700"
: params.value === "Low"
? "bg-blue-200 text-blue-700"
: "bg-gray-200 text-gray-700"
}`}
>
{params.value}
</span>
),
},
{
field: "tags",

View File

@@ -1,19 +1,19 @@
"use client";
import React, { useState } from "react";
import React, { use, useState } from "react";
import ProjectHeader from "@/app/projects/ProjectHeader";
import Board from "@/app/projects/BoardView";
import List from "@/app/projects/ListView";
import Timeline from "@/app/projects/TimelineView";
import Table from "@/app/projects/TableView";
import Board from "../BoardView";
import List from "../ListView";
import Timeline from "../TimelineView";
import Table from "../TableView";
import ModalNewTask from "@/app/components/ModalNewTask";
type Props = {
params: { id: string };
params: Promise<{ id: string }>;
};
const Project = ({ params }: Props) => {
const { id } = params;
const { id } = use(params);
const [activeTab, setActiveTab] = useState("Board");
const [isModalNewTaskOpen, setIsModalNewTaskOpen] = useState(false);
@@ -25,7 +25,6 @@ const Project = ({ params }: Props) => {
id={id}
/>
<ProjectHeader activeTab={activeTab} setActiveTab={setActiveTab} />
{activeTab === "Board" && (
<Board id={id} setIsModalNewTaskOpen={setIsModalNewTaskOpen} />
)}

View File

@@ -8,7 +8,6 @@ const Settings = () => {
teamName: "mockteam",
roleName: "mockrole",
};
const labelStyles = "block text-sm font-medium dark:text-white";
const textStyles =
"mt-1 block w-full border border-gray-300 rounded-md shadow-sm p-2 dark:text-white";

View File

@@ -31,7 +31,7 @@ const columns: GridColDef[] = [
<div className="flex h-full w-full items-center justify-center">
<div className="h-9 w-9">
<Image
src={`${params.value}`}
src={`/${params.value}`}
alt={params.row.username}
width={100}
height={50}

View File

@@ -17,7 +17,7 @@ export enum Priority {
}
export enum Status {
Backlog = "Backlog",
ToDo = "To Do",
InProgress = "In Progress",
TestReview = "Test/Review",
Done = "Done",