Files
Your NamebaishaliHolocron b9ac5ae0b2 first commit
2026-06-15 12:57:03 +05:30

154 lines
4.4 KiB
TypeScript

"use client";
import { Badge } from "ikoncomponents";
import { Calendar, User, Building2, Hash, Clock, Activity } from "lucide-react";
import { Project } from "../../../types/project";
import Workflow from "../workflow";
import { calculateDurationInDays } from "@/app/utils/function/projectDuration";
import { useMemo } from "react";
import { useAppCache } from "@/app/utils/context/AppCacheContext";
import ProjectWorkflow from "../../components/projectWorkflow";
type Props = {
project: Project;
};
export default function SummaryTab({ project }: Props) {
const { userNameMap } = useAppCache();
const duration = calculateDurationInDays(
project.contractedStartDate,
project.contractedEndDate,
);
const teamNames = useMemo(
() =>
(project.projectTeam ?? []).map(
(id) => userNameMap.get(id) || "Unknown User",
),
[project.projectTeam, userNameMap],
);
return (
<div className="grid gap-6">
{/* ================= WORKFLOW ================= */}
<ProjectWorkflow projectId ={project.projectIdentifier}/>
<div className="w-full flex gap-6">
<div className="xl:col-span-2 bg-card border rounded-xl p-6 w-2/3">
<h2 className="text-lg font-semibold">Project Details</h2>
<p className="text-muted-foreground mt-2 mb-4">
{project.projectDescription || "No description provided for this project."}
</p>
<div className="border-t border-border my-4" />
<div className="flex w-full">
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-10 gap-y-6 w-1/2">
<InfoItem
icon={<Building2 size={18} />}
label="Source"
value={project.source || "Manual"}
/>
<InfoItem
icon={<User size={18} />}
label="Project Manager"
value={
userNameMap.get(project.projectManager) ||
project.projectManager ||
"—"
}
/>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-10 gap-y-6 w-1/2">
<InfoItem
icon={<Activity size={18} />}
label="Status"
value={project.projectStatus}
/>
<InfoItem
icon={<Calendar size={18} />}
label="Start Date"
value={project.contractedStartDate}
/>
<InfoItem
icon={<Calendar size={18} />}
label="End Date"
value={project.contractedEndDate}
/>
<InfoItem
icon={<Clock size={18} />}
label="Duration"
value={duration ? duration : "-"}
/>
</div>
</div>
</div>
<div className="bg-card border rounded-xl p-6 w-1/3">
<h2 className="text-lg font-semibold mb-4">Team Members</h2>
<div className="space-y-4">
{(teamNames || []).map((name: string, index: number) => {
const initials = name
.split(" ")
.map((n) => n[0])
.join("")
.slice(0, 2)
.toUpperCase();
return (
<div key={index} className="flex items-center gap-3">
<div className="h-9 w-9 rounded-full bg-muted flex items-center justify-center text-xs font-semibold uppercase">
{initials}
</div>
<div>
<div className="font-medium">{name}</div>
</div>
</div>
);
})}
{(!teamNames || teamNames.length === 0) && (
<div className="text-sm text-muted-foreground">
No team members assigned
</div>
)}
</div>
</div>
</div>
</div>
);
}
/* ================= SMALL COMPONENT ================= */
function InfoItem({
icon,
label,
value,
}: {
icon: React.ReactNode;
label: string;
value?: string | number | null;
}) {
return (
<div className="flex items-center gap-3">
<div className="text-muted-foreground">{icon}</div>
<div>
<div className="text-sm text-muted-foreground">{label}</div>
<div className="font-medium">{value || "—"}</div>
</div>
</div>
);
}