mirror of
https://github.com/TurTaskProject/TurTaskWeb.git
synced 2025-12-19 22:14:07 +01:00
Refactor code to handle NaN and infinite values in
KpiCard and ProgressCircleChart components
This commit is contained in:
parent
779e45aa89
commit
75f194386f
@ -1,4 +1,11 @@
|
||||
import { BadgeDelta, Card, Flex, Metric, ProgressBar, Text } from "@tremor/react";
|
||||
import {
|
||||
BadgeDelta,
|
||||
Card,
|
||||
Flex,
|
||||
Metric,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from "@tremor/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { axiosInstance } from "src/api/AxiosConfig";
|
||||
|
||||
@ -46,10 +53,16 @@ export function KpiCard() {
|
||||
<div>
|
||||
<Metric>{kpiCardData.completedThisWeek}</Metric>
|
||||
</div>
|
||||
<BadgeDelta deltaType={kpiCardData.incOrdec}>{kpiCardData.percentage.toFixed(0)}%</BadgeDelta>
|
||||
<BadgeDelta deltaType={kpiCardData.incOrdec}>
|
||||
{isNaN(kpiCardData.percentage) || !isFinite(kpiCardData.percentage)
|
||||
? "0%"
|
||||
: `${kpiCardData.percentage.toFixed(0)}%`}
|
||||
</BadgeDelta>
|
||||
</Flex>
|
||||
<Flex className="mt-4">
|
||||
<Text className="truncate">vs. {kpiCardData.completedLastWeek} (last week)</Text>
|
||||
<Text className="truncate">
|
||||
vs. {kpiCardData.completedLastWeek} (last week)
|
||||
</Text>
|
||||
</Flex>
|
||||
<ProgressBar value={kpiCardData.percentage} className="mt-2" />
|
||||
</Card>
|
||||
|
||||
@ -33,9 +33,18 @@ export function ProgressCircleChart() {
|
||||
return (
|
||||
<Card className="max-w-lg mx-auto">
|
||||
<Flex className="flex-col items-center">
|
||||
<ProgressCircle className="mt-6" value={progressData} size={200} strokeWidth={10} radius={60} color="indigo">
|
||||
<ProgressCircle
|
||||
className="mt-6"
|
||||
value={progressData}
|
||||
size={200}
|
||||
strokeWidth={10}
|
||||
radius={60}
|
||||
color="indigo"
|
||||
>
|
||||
<span className="h-12 w-12 rounded-full bg-indigo-100 flex items-center justify-center text-sm text-indigo-500 font-medium">
|
||||
{progressData.toFixed(0)} %
|
||||
{isNaN(progressData) || !isFinite(progressData)
|
||||
? "0%"
|
||||
: `${progressData.toFixed(0)}%`}
|
||||
</span>
|
||||
</ProgressCircle>
|
||||
</Flex>
|
||||
|
||||
@ -154,7 +154,9 @@ export function Dashboard() {
|
||||
color="rose"
|
||||
>
|
||||
<span className="h-12 w-12 rounded-full bg-rose-100 flex items-center justify-center text-sm text-rose-500 font-medium">
|
||||
{progressData.toFixed(0)} %
|
||||
{isNaN(progressData) || !isFinite(progressData)
|
||||
? "0%"
|
||||
: `${progressData.toFixed(0)}%`}
|
||||
</span>
|
||||
</ProgressCircle>
|
||||
<br></br>
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
import { useMemo, useState, useEffect } from "react";
|
||||
import { ColumnContainerCard } from "./columnContainerWrapper";
|
||||
import { DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from "@dnd-kit/core";
|
||||
import {
|
||||
DndContext,
|
||||
DragOverlay,
|
||||
PointerSensor,
|
||||
useSensor,
|
||||
useSensors,
|
||||
} from "@dnd-kit/core";
|
||||
import { SortableContext, arrayMove } from "@dnd-kit/sortable";
|
||||
import { createPortal } from "react-dom";
|
||||
import { TaskCard } from "./taskCard";
|
||||
@ -26,7 +32,9 @@ export function KanbanBoard() {
|
||||
|
||||
// ---------------- Task Handlers ----------------
|
||||
const handleTaskUpdate = (tasks, updatedTask) => {
|
||||
const updatedTasks = tasks.map((task) => (task.id === updatedTask.id ? updatedTask : task));
|
||||
const updatedTasks = tasks.map((task) =>
|
||||
task.id === updatedTask.id ? updatedTask : task
|
||||
);
|
||||
setTasks(updatedTasks);
|
||||
};
|
||||
|
||||
@ -168,8 +176,14 @@ export function KanbanBoard() {
|
||||
justify-center
|
||||
overflow-x-auto
|
||||
overflow-y-hidden
|
||||
">
|
||||
<DndContext sensors={sensors} onDragStart={onDragStart} onDragEnd={onDragEnd} onDragOver={onDragOver}>
|
||||
"
|
||||
>
|
||||
<DndContext
|
||||
sensors={sensors}
|
||||
onDragStart={onDragStart}
|
||||
onDragEnd={onDragEnd}
|
||||
onDragOver={onDragOver}
|
||||
>
|
||||
<div className="flex gap-4">
|
||||
<div className="flex gap-4">
|
||||
{!isLoading ? (
|
||||
@ -181,7 +195,9 @@ export function KanbanBoard() {
|
||||
createTask={createTask}
|
||||
deleteTask={deleteTask}
|
||||
updateTask={updateTask}
|
||||
tasks={(tasks || []).filter((task) => task.columnId === col.id)}
|
||||
tasks={(tasks || []).filter(
|
||||
(task) => task.columnId === col.id
|
||||
)}
|
||||
/>
|
||||
))}{" "}
|
||||
</SortableContext>
|
||||
@ -194,7 +210,11 @@ export function KanbanBoard() {
|
||||
{createPortal(
|
||||
<DragOverlay className="bg-white" dropAnimation={null} zIndex={20}>
|
||||
{/* Render the active task as a draggable overlay */}
|
||||
<TaskCard task={activeTask} deleteTask={deleteTask} updateTask={updateTask} />
|
||||
<TaskCard
|
||||
task={activeTask}
|
||||
deleteTask={deleteTask}
|
||||
updateTask={updateTask}
|
||||
/>
|
||||
</DragOverlay>,
|
||||
document.body
|
||||
)}
|
||||
@ -302,7 +322,11 @@ export function KanbanBoard() {
|
||||
|
||||
const isOverAColumn = over.data.current?.type === "Column";
|
||||
// Move the Task to a different column and update columnId
|
||||
if (isActiveATask && isOverAColumn && tasks.some((task) => task.columnId !== overId)) {
|
||||
if (
|
||||
isActiveATask &&
|
||||
isOverAColumn &&
|
||||
tasks.some((task) => task.columnId !== overId)
|
||||
) {
|
||||
setTasks((tasks) => {
|
||||
const activeIndex = tasks.findIndex((t) => t.id === activeId);
|
||||
axiosInstance
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { useState } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { BsFillTrashFill } from "react-icons/bs";
|
||||
import { useSortable } from "@dnd-kit/sortable";
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
@ -6,6 +7,9 @@ import { TaskDetailModal } from "./taskDetailModal";
|
||||
|
||||
export function TaskCard({ task, deleteTask, updateTask }) {
|
||||
const [mouseIsOver, setMouseIsOver] = useState(false);
|
||||
// console.log(task.challenge);
|
||||
// console.log(task.importance);
|
||||
// console.log(task.difficulty);
|
||||
|
||||
const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({
|
||||
id: task.id,
|
||||
@ -14,12 +18,13 @@ export function TaskCard({ task, deleteTask, updateTask }) {
|
||||
task,
|
||||
},
|
||||
});
|
||||
|
||||
const style = {
|
||||
transition,
|
||||
transform: CSS.Transform.toString(transform),
|
||||
};
|
||||
|
||||
|
||||
|
||||
{
|
||||
/* If card is dragged */
|
||||
}
|
||||
@ -60,7 +65,7 @@ export function TaskCard({ task, deleteTask, updateTask }) {
|
||||
setMouseIsOver(false);
|
||||
}}>
|
||||
<p
|
||||
className="p-2.5 my-auto w-full overflow-y-auto overflow-x-hidden whitespace-pre-wrap rounded-xl shadow bg-white"
|
||||
className={`p-2.5 my-auto w-full overflow-y-auto overflow-x-hidden whitespace-pre-wrap rounded-xl shadow bg-white`}
|
||||
onClick={() => document.getElementById(`task_detail_modal_${task.id}`).showModal()}>
|
||||
{task.content}
|
||||
</p>
|
||||
|
||||
@ -7,6 +7,9 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
||||
const [isChallengeChecked, setChallengeChecked] = useState(challenge);
|
||||
const [isImportantChecked, setImportantChecked] = useState(importance);
|
||||
const [currentDifficulty, setCurrentDifficulty] = useState(difficulty);
|
||||
// console.log(currentDifficulty);
|
||||
// console.log(isChallengeChecked);
|
||||
// console.log(isImportantChecked);
|
||||
|
||||
const handleChallengeChange = () => {
|
||||
setChallengeChecked(!isChallengeChecked);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user