109 lines
3.5 KiB
TypeScript
109 lines
3.5 KiB
TypeScript
"use client";
|
|
|
|
import { getAllSchedulesApi } from "@/app/utils/api/projectApi";
|
|
import { Card } from "ikoncomponents";
|
|
import { useEffect, useState, useMemo } from "react";
|
|
|
|
interface Task {
|
|
id: number;
|
|
taskName: string;
|
|
taskDescription: string;
|
|
taskStart: string;
|
|
taskEnd: string;
|
|
milestoneTask: boolean;
|
|
}
|
|
|
|
export default function CurrentMonthMilestones() {
|
|
const [apiTasks, setApiTasks] = useState<Task[]>([]);
|
|
|
|
useEffect(() => {
|
|
const fetchScheduleData = async () => {
|
|
try {
|
|
const response = await getAllSchedulesApi();
|
|
// Flatten all nested task arrays across every project in the response
|
|
const allTasks = response.flatMap((project: any) => project.task || []);
|
|
setApiTasks(allTasks);
|
|
} catch (error) {
|
|
console.error("Error fetching schedule data:", error);
|
|
}
|
|
};
|
|
|
|
fetchScheduleData();
|
|
}, []);
|
|
|
|
const visibleMilestones = useMemo(() => {
|
|
const today = new Date();
|
|
today.setHours(0, 0, 0, 0);
|
|
|
|
return (
|
|
apiTasks
|
|
.filter((task) => {
|
|
// 1. Must be a milestone task
|
|
const isMilestone = task.milestoneTask === true;
|
|
|
|
// 2. Must be today or a future date
|
|
const taskStartDate = new Date(task.taskStart);
|
|
taskStartDate.setHours(0, 0, 0, 0);
|
|
const isTodayOrFuture = taskStartDate >= today;
|
|
|
|
return isMilestone && isTodayOrFuture;
|
|
})
|
|
// 3. Keep exactly the top 3 items
|
|
.slice(0, 3)
|
|
);
|
|
}, [apiTasks]);
|
|
|
|
return (
|
|
<Card className="p-4 h-127">
|
|
<div className="max-w-3xl rounded-2xl p-3 shadow-sm h-full flex flex-col">
|
|
<h1 className="mb-4 text-xl font-bold flex-shrink-0">
|
|
Current Month Milestones
|
|
</h1>
|
|
|
|
<div className="space-y-4 flex-grow flex flex-col justify-center items-center">
|
|
{visibleMilestones.length === 0 ? (
|
|
<p className="text-sm text-muted-foreground italic p-4 text-center">
|
|
No milestone tasks scheduled for this period.
|
|
</p>
|
|
) : (
|
|
<div className="w-full space-y-4 flex-grow justify-start">
|
|
{visibleMilestones.map((task, index) => (
|
|
<div
|
|
key={task.id}
|
|
className="rounded-xl border border-border bg-card p-4 shadow-sm"
|
|
>
|
|
{/* Index and Task Name */}
|
|
<h2 className="text-lg font-semibold flex items-center gap-2">
|
|
<span className="text-muted-foreground">{index + 1}.</span>
|
|
{task.taskName}
|
|
</h2>
|
|
|
|
{/* Description Block */}
|
|
<p className="mt-1 text-sm text-muted-foreground">
|
|
{task.taskDescription || "No description provided."}
|
|
</p>
|
|
|
|
{/* Dates in a Separate Line Below */}
|
|
<div className="mt-3 pt-3 border-t border-border/50 flex items-center gap-6 text-xs text-muted-foreground">
|
|
<div>
|
|
<span className="font-medium text-foreground">
|
|
Start:
|
|
</span>{" "}
|
|
{task.taskStart}
|
|
</div>
|
|
|
|
<div>
|
|
<span className="font-medium text-foreground">End:</span>{" "}
|
|
{task.taskEnd}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
);
|
|
}
|