first commit
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
"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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user