import React, { useState, useMemo } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card'; import { Badge } from './ui/badge'; import { Button } from './ui/button'; import { toast } from 'sonner@2.0.3'; import { Progress } from './ui/progress'; import { Avatar, AvatarFallback } from './ui/avatar'; import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs'; import { CUSTOM_REQUEST_DATABASE } from '../utils/customRequestDatabase'; import { ArrowLeft, Clock, User, FileText, MessageSquare, Users, CheckCircle, XCircle, Download, Eye, Flame, Target, TrendingUp, RefreshCw, Activity, Mail, Phone, Upload, UserPlus, Edit3, ClipboardList } from 'lucide-react'; interface RequestDetailProps { requestId: string; onBack?: () => void; onOpenModal?: (modal: string) => void; dynamicRequests?: any[]; } // Utility functions const getPriorityConfig = (priority: string) => { switch (priority) { case 'express': case 'urgent': return { color: 'bg-red-100 text-red-800 border-red-200', label: 'urgent priority' }; case 'standard': return { color: 'bg-blue-100 text-blue-800 border-blue-200', label: 'standard priority' }; default: return { color: 'bg-gray-100 text-gray-800 border-gray-200', label: 'normal priority' }; } }; const getStatusConfig = (status: string) => { switch (status) { case 'pending': return { color: 'bg-yellow-100 text-yellow-800 border-yellow-200', label: 'pending' }; case 'in-review': return { color: 'bg-blue-100 text-blue-800 border-blue-200', label: 'in-review' }; case 'approved': return { color: 'bg-green-100 text-green-800 border-green-200', label: 'approved' }; case 'rejected': return { color: 'bg-red-100 text-red-800 border-red-200', label: 'rejected' }; default: return { color: 'bg-gray-100 text-gray-800 border-gray-200', label: status }; } }; const getSLAConfig = (progress: number) => { if (progress >= 80) { return { bg: 'bg-red-50', color: 'bg-red-500', textColor: 'text-red-700' }; } else if (progress >= 60) { return { bg: 'bg-orange-50', color: 'bg-orange-500', textColor: 'text-orange-700' }; } else { return { bg: 'bg-green-50', color: 'bg-green-500', textColor: 'text-green-700' }; } }; const getStepIcon = (status: string) => { switch (status) { case 'approved': return ; case 'rejected': return ; case 'pending': case 'in-review': return ; default: return ; } }; const getActionTypeIcon = (type: string) => { switch (type) { case 'approval': case 'approved': return ; case 'rejection': case 'rejected': return ; case 'comment': return ; case 'status_change': case 'updated': return ; case 'assignment': return ; case 'created': return ; case 'reminder': return ; default: return ; } }; export function RequestDetail({ requestId, onBack, onOpenModal, dynamicRequests = [] }: RequestDetailProps) { const [activeTab, setActiveTab] = useState('overview'); // Get request from custom request database or dynamic requests const request = useMemo(() => { // First check static database const staticRequest = CUSTOM_REQUEST_DATABASE[requestId]; if (staticRequest) return staticRequest; // Then check dynamic requests const dynamicRequest = dynamicRequests.find((req: any) => req.id === requestId); if (dynamicRequest) return dynamicRequest; return null; }, [requestId, dynamicRequests]); if (!request) { return (

Request Not Found

The custom request you're looking for doesn't exist.

); } const priorityConfig = getPriorityConfig(request.priority); const statusConfig = getStatusConfig(request.status); const slaConfig = getSLAConfig(request.slaProgress); return (
{/* Header Section */}
{/* Top Header */}

{request.id}

{priorityConfig.label} {statusConfig.label}

{request.title}

{/* SLA Progress */}
SLA Progress
{request.slaRemaining}

Due: {request.slaEndDate} • {request.slaProgress}% elapsed

{/* Tabs */} Overview Workflow Documents Activity {/* Overview Tab */}
{/* Left Column - Main Content (2/3 width) */}
{/* Request Initiator */} Request Initiator
{request.initiator?.avatar || 'U'}

{request.initiator?.name || 'N/A'}

{request.initiator?.role || 'N/A'}

{request.initiator?.department || 'N/A'}

{request.initiator?.email || 'N/A'}
{request.initiator?.phone || 'N/A'}
{/* Request Details */} Request Details

{request.description}

{/* Additional Details */} {(request.category || request.subcategory) && (
{request.category && (

{request.category}

)} {request.subcategory && (

{request.subcategory}

)}
)} {request.amount && (

{request.amount}

)}

{request.createdAt}

{request.updatedAt}

{/* Right Column - Quick Actions Sidebar (1/3 width) */}
{/* Quick Actions */} Quick Actions
{/* Spectators */} {request.spectators && request.spectators.length > 0 && ( Spectators {request.spectators.map((spectator: any, index: number) => (
{spectator.avatar}

{spectator.name}

{spectator.role}

))}
)}
{/* Workflow Tab */}
Approval Workflow Track the approval progress through each step
{request.totalSteps && ( Step {request.currentStep} of {request.totalSteps} )}
{request.approvalFlow && request.approvalFlow.length > 0 ? (
{request.approvalFlow.map((step: any, index: number) => { const isActive = step.status === 'pending' || step.status === 'in-review'; const isCompleted = step.status === 'approved'; const isRejected = step.status === 'rejected'; return (
{getStepIcon(step.status)}

{step.step ? `Step ${step.step}: ` : ''}{step.role}

{step.status}

{step.approver}

{step.tatHours && (

TAT: {step.tatHours}h

)} {step.elapsedHours !== undefined && step.elapsedHours > 0 && (

Elapsed: {step.elapsedHours}h

)} {step.actualHours !== undefined && (

Completed in: {step.actualHours}h

)}
{step.comment && (

{step.comment}

)} {step.timestamp && (

{isCompleted ? 'Approved' : isRejected ? 'Rejected' : 'Actioned'} on {step.timestamp}

)}
); })}
) : (

No workflow steps defined

)}
{/* Documents Tab */}
Request Documents
{request.documents && request.documents.length > 0 ? (
{request.documents.map((doc: any, index: number) => (

{doc.name}

{doc.size} • Uploaded by {doc.uploadedBy} on {doc.uploadedAt}

))}
) : (

No documents uploaded yet

)}
{/* Activity Tab */} Activity Timeline Complete audit trail of all request activities
{request.auditTrail && request.auditTrail.length > 0 ? request.auditTrail.map((entry: any, index: number) => (
{getActionTypeIcon(entry.type)}

{entry.action}

{entry.details}

by {entry.user}

{entry.timestamp}
)) : (

No activity recorded yet

Actions and updates will appear here

)}
); }