import React, { useEffect, useState } from "react"; import { useNavigate, useParams, Link } from "react-router-dom"; import { tasksApi, Task } from "@/services/tasksApi"; import { employeeApi } from "@/services/employeeApi"; import { toast } from "sonner"; import { ChevronRight, Home, Calendar, Clock, Edit, FileText, AlertCircle, CheckCircle, RefreshCw, Bug, Code, CheckSquare, XCircle, AlertTriangle, GitBranch, Link as LinkIcon, Monitor, Info, Paperclip, MessageSquare, History } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { format } from "date-fns"; import Layout from "../components/layout/layout"; import { useQuery } from "@tanstack/react-query"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Separator } from "@/components/ui/separator"; import TaskTimeLogCard from "@/components/tasks/TaskTimeLogCard"; import TaskCommentSection from "@/components/tasks/TaskCommentSection"; import TaskAttachmentsSection from "@/components/tasks/TaskAttachmentsSection"; const BugDetailPage = () => { const navigate = useNavigate(); const { id } = useParams(); const [bug, setBug] = useState(); const [isLoading, setIsLoading] = useState(false); const [activeTab, setActiveTab] = useState("details"); // Fetch employees data const { data: employees = [], isLoading: isLoadingEmployees } = useQuery({ queryKey: ["employees"], queryFn: () => employeeApi.getAll(), }); useEffect(() => { if (id) { fetchBug(); } }, [id]); const fetchBug = async () => { try { setIsLoading(true); const bugData = await tasksApi.getById(Number(id)); // Check if this is actually a bug type if (bugData && bugData.type === "Bug") { setBug(bugData); } else { toast.error("The requested item is not a bug"); navigate("/bugs"); } } catch (error) { console.error("Error fetching bug:", error); toast.error("Failed to load bug data"); } finally { setIsLoading(false); } }; const handleEdit = () => { navigate(`/bugs/${id}/edit`); }; const handleBack = () => { navigate(-1); }; // Get assignee information const getAssigneeInfo = (userId: number | null) => { if (!userId) return { initials: "NA", name: "Unassigned" }; const userIdString = userId.toString(); const employee = employees.find(emp => emp.id.toString() === userIdString); if (employee) { const initials = `${employee.firstName.charAt(0)}${employee.lastName.charAt(0)}`.toUpperCase(); return { initials, name: `${employee.firstName} ${employee.lastName}` }; } return { initials: "US", name: `User ${userId}` }; }; // Helper to get status badge const getStatusBadge = (status: string) => { switch (status) { case "Completed": case "Closed": return ( {status} ); case "In Progress": return ( {status} ); case "In Review": return ( {status} ); case "New": default: return ( {status || "New"} ); } }; // Helper to get severity badge const getSeverityBadge = (severity: string) => { switch (severity?.toLowerCase()) { case "blocker": return ( {severity} ); case "critical": return ( {severity} ); case "major": return ( {severity} ); case "minor": return ( {severity} ); case "trivial": return ( {severity} ); default: return ( {severity || "Not Set"} ); } }; // Helper to get priority badge const getPriorityBadge = (priority: string) => { switch (priority?.toLowerCase()) { case "critical": return ( {priority} ); case "high": return ( {priority} ); case "medium": return ( {priority} ); case "low": return ( {priority} ); default: return ( {priority || "Not Set"} ); } }; // Helper to get bug type badge const getBugTypeBadge = (type: string) => { switch (type?.toLowerCase()) { case "bug": return ( {type} ); case "feature": return ( {type} ); case "enhancement": return ( {type} ); case "task": return ( {type} ); default: return ( {type || "Unknown"} ); } }; // Format date for display const formatDate = (dateString: string | null) => { if (!dateString) return "Not set"; try { return format(new Date(dateString), "MMM dd, yyyy"); } catch (error) { return "Invalid date"; } }; if (isLoading || isLoadingEmployees) { return (

Loading bug details...

); } if (!bug) { return (

Bug Not Found

The bug you're looking for doesn't exist or has been removed.

); } // Get assignee details const { initials: assigneeInitials, name: assigneeName } = getAssigneeInfo(bug.assignedTo); return (
{/* Breadcrumb Navigation */}
{/* Header Section with background */}

{bug.title}

{getStatusBadge(bug.status)} {getBugTypeBadge(bug.type)} {bug.priority && getPriorityBadge(bug.priority)} {bug.severity && getSeverityBadge(bug.severity)} {bug.taskCode || `BUG-${bug.id}`}
{assigneeInitials}

Assigned To

{assigneeName}

Created

{formatDate(bug.createdAt || "")}

Version

{bug.version || "Not specified"}

Environment

{bug.environment || "Not specified"}

{/* Tab Content Section */} Details Steps Resolution Files Time Logs Discussion Bug Description
{bug.description ? (
{bug.description}
) : (

No description provided.

)}
{bug.url && ( Related URL {bug.url} )} {bug.inputs && ( Test Data / Inputs
{bug.inputs}
)}
Steps to Reproduce {bug.stepsToReproduce ? (
{bug.stepsToReproduce}
) : (

No reproduction steps provided.

)}
Expected Behavior {bug.expectedBehavior ? (
{bug.expectedBehavior}
) : (

No expected behavior specified.

)}
Actual Behavior {bug.actualBehavior ? (
{bug.actualBehavior}
) : (

No actual behavior specified.

)}
Root Cause {bug.rootCause ? (
{bug.rootCause}
) : (

Root cause analysis not provided yet.

)}
Resolution {bug.resolution ? (
{bug.resolution}
) : (

Resolution details not provided yet.

)}
); }; export default BugDetailPage;