@@ -795,6 +795,8 @@ function RiskAssessmentsTable({
795795} ) {
796796 const [ showDropdown , setShowDropdown ] = useState < string | null > ( null ) ;
797797 const dropdownRef = useRef < HTMLDivElement > ( null ) ;
798+ const [ selectedAssessment , setSelectedAssessment ] = useState < any > ( null ) ;
799+ const [ showDetailsModal , setShowDetailsModal ] = useState ( false ) ;
798800
799801 // Close dropdown when clicking outside
800802 useEffect ( ( ) => {
@@ -826,6 +828,13 @@ function RiskAssessmentsTable({
826828
827829 const isExpired = ( expiresAt : string ) => isPast ( new Date ( expiresAt ) ) ;
828830
831+ // Handle click on view details
832+ const handleViewDetails = ( assessment : any ) => {
833+ setSelectedAssessment ( assessment ) ;
834+ setShowDetailsModal ( true ) ;
835+ setShowDropdown ( null ) ;
836+ } ;
837+
829838 return (
830839 < div className = "space-y-4" >
831840 < div className = "rounded-xl border border-[#ECEFEC] bg-white overflow-hidden" >
@@ -978,10 +987,7 @@ function RiskAssessmentsTable({
978987 >
979988 < button
980989 className = "w-full text-left px-4 py-2 text-sm hover:bg-[rgba(2,42,2,0.03)]"
981- onClick = { ( ) => {
982- // View or edit functionality can be added here
983- setShowDropdown ( null ) ;
984- } }
990+ onClick = { ( ) => handleViewDetails ( assessment ) }
985991 >
986992 View details
987993 </ button >
@@ -1017,6 +1023,132 @@ function RiskAssessmentsTable({
10171023 Create a new risk assessment for this vendor
10181024 </ p >
10191025 </ div >
1026+
1027+ { /* Risk Assessment Details Modal */ }
1028+ { showDetailsModal && selectedAssessment && (
1029+ < RiskAssessmentDetailsModal
1030+ assessment = { selectedAssessment }
1031+ onClose = { ( ) => setShowDetailsModal ( false ) }
1032+ />
1033+ ) }
1034+ </ div >
1035+ ) ;
1036+ }
1037+
1038+ function RiskAssessmentDetailsModal ( {
1039+ assessment,
1040+ onClose,
1041+ } : {
1042+ assessment : any ;
1043+ onClose : ( ) => void ;
1044+ } ) {
1045+ // Format date for display
1046+ const formatDate = ( dateString : string ) => {
1047+ const date = new Date ( dateString ) ;
1048+ return format ( date , "MMMM d, yyyy" ) ;
1049+ } ;
1050+
1051+ // Data sensitivity descriptions
1052+ const dataSensitivityDescriptions : Record < string , string > = {
1053+ NONE : "No sensitive data" ,
1054+ LOW : "Public or non-sensitive data" ,
1055+ MEDIUM : "Internal/restricted data" ,
1056+ HIGH : "Confidential data" ,
1057+ CRITICAL : "Regulated/PII/financial data" ,
1058+ } ;
1059+
1060+ // Business impact descriptions
1061+ const businessImpactDescriptions : Record < string , string > = {
1062+ LOW : "Minimal impact on business" ,
1063+ MEDIUM : "Moderate impact on business" ,
1064+ HIGH : "Significant business impact" ,
1065+ CRITICAL : "Critical to business operations" ,
1066+ } ;
1067+
1068+ return (
1069+ < div className = "fixed inset-0 bg-black/50 flex items-center justify-center z-50" >
1070+ < div className = "bg-white rounded-xl p-6 w-full max-w-2xl max-h-[90vh] overflow-y-auto" >
1071+ < div className = "flex justify-between items-center mb-4" >
1072+ < h3 className = "text-lg font-medium" > Risk Assessment Details</ h3 >
1073+ < Button
1074+ variant = "ghost"
1075+ size = "icon"
1076+ onClick = { onClose }
1077+ className = "h-8 w-8 rounded-full"
1078+ >
1079+ < X className = "h-4 w-4" />
1080+ </ Button >
1081+ </ div >
1082+
1083+ < div className = "space-y-6" >
1084+ < div className = "grid grid-cols-1 md:grid-cols-2 gap-4" >
1085+ < div >
1086+ < h4 className = "text-sm font-medium text-[#6B716A] mb-1" > Assessed By</ h4 >
1087+ < div className = "flex items-center space-x-2" >
1088+ < User className = "h-5 w-5 text-[#6B716A]" />
1089+ < p className = "text-sm font-medium" > { assessment . assessedBy ?. fullName || "N/A" } </ p >
1090+ </ div >
1091+ < p className = "text-xs text-[#818780] mt-1" >
1092+ { formatDate ( assessment . assessedAt || "" ) }
1093+ </ p >
1094+ </ div >
1095+
1096+ < div >
1097+ < h4 className = "text-sm font-medium text-[#6B716A] mb-1" > Valid Until</ h4 >
1098+ < p className = "text-sm font-medium" >
1099+ { formatDate ( assessment . expiresAt || "" ) }
1100+ </ p >
1101+ { isPast ( new Date ( assessment . expiresAt || "" ) ) && (
1102+ < p className = "text-xs text-red-500 mt-1" >
1103+ Assessment has expired
1104+ </ p >
1105+ ) }
1106+ </ div >
1107+ </ div >
1108+
1109+ < div >
1110+ < h4 className = "text-sm font-medium text-[#6B716A] mb-2" > Data Sensitivity</ h4 >
1111+ < div className = "p-3 bg-[rgba(5,77,5,0.03)] rounded-md" >
1112+ < p className = "text-sm font-medium text-[#141E12]" >
1113+ { assessment . dataSensitivity . charAt ( 0 ) + assessment . dataSensitivity . slice ( 1 ) . toLowerCase ( ) }
1114+ </ p >
1115+ < p className = "text-sm text-[#6B716A] mt-1" >
1116+ { dataSensitivityDescriptions [ assessment . dataSensitivity ] || "" }
1117+ </ p >
1118+ </ div >
1119+ </ div >
1120+
1121+ < div >
1122+ < h4 className = "text-sm font-medium text-[#6B716A] mb-2" > Business Impact</ h4 >
1123+ < div className = "p-3 bg-[rgba(5,77,5,0.03)] rounded-md" >
1124+ < p className = "text-sm font-medium text-[#141E12]" >
1125+ { assessment . businessImpact . charAt ( 0 ) + assessment . businessImpact . slice ( 1 ) . toLowerCase ( ) }
1126+ </ p >
1127+ < p className = "text-sm text-[#6B716A] mt-1" >
1128+ { businessImpactDescriptions [ assessment . businessImpact ] || "" }
1129+ </ p >
1130+ </ div >
1131+ </ div >
1132+
1133+ { assessment . notes && (
1134+ < div >
1135+ < h4 className = "text-sm font-medium text-[#6B716A] mb-2" > Notes</ h4 >
1136+ < div className = "p-3 bg-[rgba(5,77,5,0.03)] rounded-md" >
1137+ < p className = "text-sm text-[#141E12] whitespace-pre-wrap" > { assessment . notes } </ p >
1138+ </ div >
1139+ </ div >
1140+ ) }
1141+
1142+ < div className = "flex justify-end mt-4" >
1143+ < Button
1144+ onClick = { onClose }
1145+ className = "bg-[#054D05] text-white hover:bg-[#054D05]/90"
1146+ >
1147+ Close
1148+ </ Button >
1149+ </ div >
1150+ </ div >
1151+ </ div >
10201152 </ div >
10211153 ) ;
10221154}
0 commit comments