import { useParams } from "react-router-dom"; import { AppLayout } from "@/components/layout/AppLayout"; import { useTraceabilityData } from "@/hooks/useTraceabilityData"; import { WorkPackageCard } from "@/components/traceability/WorkPackageCard"; import { Card, CardContent } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { useState, useMemo } from "react"; import { Target, CheckSquare, FileText, TestTube, Layers, Bug, AlertTriangle, Calendar, Milestone, FolderKanban, Search, } from "lucide-react"; import { WorkPackageType } from "@/types/traceability"; const typeConfig: Record< string, { title: string; icon: React.ReactNode; description: string } > = { feature: { title: "Features", icon: , description: "System features and capabilities", }, requirements: { title: "System Requirements", icon: , description: "High-level system requirements (SR-*)", }, swreq: { title: "Software Requirements", icon: , description: "Detailed software requirements (SWR-*)", }, "test-case": { title: "Test Cases", icon: , description: "Verification and validation test cases", }, epic: { title: "Epics", icon: , description: "Large feature containers", }, "user-story": { title: "User Stories", icon: , description: "User-focused requirements", }, task: { title: "Tasks", icon: , description: "Implementation tasks", }, bug: { title: "Bugs", icon: , description: "Defects and issues", }, risk: { title: "Risks", icon: , description: "Identified project risks", }, milestone: { title: "Milestones", icon: , description: "Project milestones", }, phase: { title: "Phases", icon: , description: "Project phases", }, "summary-task": { title: "Summary Tasks", icon: , description: "Task containers", }, }; export default function ALMTypePage() { const { type } = useParams<{ type: string }>(); const { data, loading, lastUpdated, refresh, groupedByType } = useTraceabilityData(); const [searchQuery, setSearchQuery] = useState(""); const [statusFilter, setStatusFilter] = useState("all"); // Convert URL param to actual type (e.g., "test-case" -> "test case") const actualType = type?.replace("-", " ") as WorkPackageType; const items = groupedByType[actualType] || []; const config = typeConfig[type || ""] || { title: type || "Unknown", icon: , description: "", }; // Get unique statuses const statuses = useMemo(() => { const statusSet = new Set(); items.forEach((item) => statusSet.add(item.status)); return Array.from(statusSet).sort(); }, [items]); // Filter items const filteredItems = useMemo(() => { return items.filter((item) => { const matchesSearch = searchQuery === "" || item.title.toLowerCase().includes(searchQuery.toLowerCase()) || item.description.toLowerCase().includes(searchQuery.toLowerCase()) || item.id.toString().includes(searchQuery); const matchesStatus = statusFilter === "all" || item.status === statusFilter; return matchesSearch && matchesStatus; }); }, [items, searchQuery, statusFilter]); return (
{/* Header */}
{config.icon}

{config.title}

{config.description}

{items.length} items
{/* Filters */}
setSearchQuery(e.target.value)} className="pl-9" />
{/* Results */}
{loading ? (
Loading...
) : filteredItems.length === 0 ? ( {items.length === 0 ? `No ${config.title.toLowerCase()} found in the traceability data.` : "No items match your search criteria."} ) : ( filteredItems.map((item) => ( )) )}
{/* Summary */} {filteredItems.length > 0 && filteredItems.length !== items.length && (

Showing {filteredItems.length} of {items.length} items

)}
); }