larxius commited on
Commit
3d8aa06
·
verified ·
1 Parent(s): 0fa6ba8

Update frontend/src/pages/LogsAndThreats.jsx

Browse files
Files changed (1) hide show
  1. frontend/src/pages/LogsAndThreats.jsx +80 -110
frontend/src/pages/LogsAndThreats.jsx CHANGED
@@ -466,190 +466,160 @@ const LogsAndThreats = () => {
466
  if (!selectedThreat) return null;
467
 
468
  const severityColorMap = {
469
- critical: {
470
- border: 'border-l-red-500',
471
- banner: 'from-red-500/15 via-surface-container to-surface-container-lowest',
472
- badge: 'bg-red-500/10 text-red-500 border-red-500/30',
473
- glow: 'shadow-red-500/10',
474
- },
475
- high: {
476
- border: 'border-l-orange-500',
477
- banner: 'from-orange-500/15 via-surface-container to-surface-container-lowest',
478
- badge: 'bg-orange-500/10 text-orange-500 border-orange-500/30',
479
- glow: 'shadow-orange-500/10',
480
- },
481
- medium: {
482
- border: 'border-l-amber-500',
483
- banner: 'from-amber-500/15 via-surface-container to-surface-container-lowest',
484
- badge: 'bg-amber-500/10 text-amber-500 border-amber-500/30',
485
- glow: 'shadow-amber-500/10',
486
- },
487
- low: {
488
- border: 'border-l-blue-500',
489
- banner: 'from-blue-500/15 via-surface-container to-surface-container-lowest',
490
- badge: 'bg-blue-500/10 text-blue-500 border-blue-500/30',
491
- glow: 'shadow-blue-500/10',
492
- },
493
  };
494
 
495
  const sevKey = (selectedThreat.severity || 'medium').toLowerCase();
496
  const activeSev = severityColorMap[sevKey] || severityColorMap.medium;
497
 
498
  return (
499
- <div className="fixed inset-0 bg-slate-950/80 backdrop-blur-xl flex items-center justify-center p-4 pt-12 sm:pt-16 z-[9999] animate-fade-in overflow-y-auto">
500
- <div className={`bg-surface border border-outline-variant/80 rounded-3xl max-w-3xl w-full shadow-2xl relative my-auto overflow-hidden flex flex-col max-h-[90vh] transition-all duration-300 transform animate-in fade-in zoom-in-95 border-t-4 ${activeSev.border}`}>
501
 
502
- {/* Header Banner with Premium Gradient Accent */}
503
- <div className={`bg-gradient-to-r ${activeSev.banner} p-6 sm:p-7 border-b border-outline-variant/70 relative`}>
504
  <button
505
  onClick={() => setSelectedThreat(null)}
506
- className="absolute top-5 right-5 text-on-surface-variant hover:text-on-surface bg-surface-container-high/80 hover:bg-surface-container-highest p-2 rounded-full transition-all cursor-pointer border border-outline-variant/60 shadow-2xs hover:scale-105"
507
- title="Close Diagnostic Window"
508
  >
509
- <X className="w-5 h-5" />
510
  </button>
511
 
512
- <div className="flex items-center gap-2.5 flex-wrap mb-3.5 pr-12">
513
- <span className={`px-3.5 py-1 rounded-full text-[11px] font-black uppercase tracking-wider border shadow-2xs flex items-center gap-1.5 ${getSeverityBadgeClass(selectedThreat.severity)}`}>
514
- <ShieldAlert className="w-3.5 h-3.5 animate-pulse" />
515
- {selectedThreat.severity} SEVERITY
516
  </span>
517
- <span className="bg-cyan-500/10 text-cyan-600 dark:text-cyan-400 text-[11px] font-black px-3.5 py-1 rounded-full border border-cyan-500/30 shadow-2xs font-mono">
518
  CVSS {selectedThreat.cvss}
519
  </span>
520
- <span className="bg-red-500/10 text-red-600 dark:text-red-400 text-[11px] font-black px-3.5 py-1 rounded-full border border-red-500/30 shadow-2xs flex items-center gap-1.5">
521
- <span className="w-2 h-2 rounded-full bg-red-500 animate-ping"></span>
522
- {selectedThreat.count} Detections Recorded
523
  </span>
524
  </div>
525
 
526
- <h2 className="text-[22px] sm:text-[24px] font-extrabold text-on-surface tracking-tight leading-snug font-display">
527
  {selectedThreat.title}
528
  </h2>
529
  </div>
530
 
531
- {/* Modal Body Scroll Container */}
532
- <div className="p-6 sm:p-7 space-y-6 overflow-y-auto text-[13.5px] bg-surface">
533
 
534
- {/* Category & OWASP Specifications Cards */}
535
- <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
536
- <div className="bg-surface-container-lowest p-4.5 rounded-2xl border border-outline-variant/70 shadow-2xs flex items-start gap-3">
537
- <div className="p-2.5 rounded-xl bg-primary/10 text-primary border border-primary/20 shrink-0">
538
- <Layers className="w-5 h-5" />
539
- </div>
540
- <div>
541
- <span className="text-[11px] font-bold text-on-surface-variant uppercase tracking-wider block mb-0.5">
542
- Vulnerability Category
543
- </span>
544
- <span className="font-extrabold text-on-surface text-[15px]">{selectedThreat.category}</span>
545
  </div>
546
  </div>
547
 
548
- <div className="bg-surface-container-lowest p-4.5 rounded-2xl border border-outline-variant/70 shadow-2xs flex items-start gap-3">
549
- <div className="p-2.5 rounded-xl bg-indigo-500/10 text-indigo-500 border border-indigo-500/20 shrink-0">
550
- <Shield className="w-5 h-5" />
551
- </div>
552
- <div>
553
- <span className="text-[11px] font-bold text-on-surface-variant uppercase tracking-wider block mb-0.5">
554
- OWASP Standard Compliance
555
- </span>
556
- <span className="font-extrabold text-indigo-500 text-[14.5px]">{selectedThreat.owasp}</span>
557
  </div>
558
  </div>
559
  </div>
560
 
561
- {/* Threat Overview Card */}
562
- <div className="bg-surface-container-lowest p-5 rounded-2xl border-l-4 border-l-primary border border-outline-variant/70 shadow-2xs">
563
- <h3 className="font-bold text-on-surface text-[14.5px] mb-2 flex items-center gap-2">
564
- <Shield className="w-4.5 h-4.5 text-primary" /> Vulnerability Overview & Technical Details
565
- </h3>
566
- <p className="text-on-surface-variant leading-relaxed text-[14px]">
567
- {selectedThreat.description}
568
- </p>
569
- </div>
 
570
 
571
- {/* Security Impact Card */}
572
- <div className="bg-surface-container-lowest p-5 rounded-2xl border-l-4 border-l-amber-500 border border-outline-variant/70 shadow-2xs">
573
- <h3 className="font-bold text-amber-600 dark:text-amber-400 text-[14.5px] mb-2 flex items-center gap-2">
574
- <AlertTriangle className="w-4.5 h-4.5" /> Exploitation & Impact Risk Analysis
575
- </h3>
576
- <p className="text-on-surface-variant leading-relaxed text-[14px]">
577
- {selectedThreat.impact}
578
- </p>
579
  </div>
580
 
581
- {/* Code Remediation Terminal Box (IDE Style) */}
582
- <div className="bg-surface-container-lowest rounded-2xl border border-outline-variant/70 shadow-2xs overflow-hidden">
583
- <div className="bg-surface-container-high/80 px-4 py-3 border-b border-outline-variant/60 flex items-center justify-between">
584
- <div className="flex items-center gap-2">
585
- <div className="flex items-center gap-1.5 mr-2">
586
- <span className="w-3 h-3 rounded-full bg-red-500/80 inline-block"></span>
587
- <span className="w-3 h-3 rounded-full bg-amber-500/80 inline-block"></span>
588
- <span className="w-3 h-3 rounded-full bg-green-500/80 inline-block"></span>
589
- </div>
590
- <h3 className="font-bold text-on-surface text-[13px] flex items-center gap-2 font-mono">
591
- <Terminal className="w-4 h-4 text-green-500" /> Recommended Security Fix
592
- </h3>
593
- </div>
594
 
595
  <button
596
  onClick={() => copyToClipboard(selectedThreat.remediation)}
597
- className="flex items-center gap-1.5 px-3 py-1.5 bg-surface-container hover:bg-surface-container-highest text-on-surface rounded-lg text-[12px] font-bold border border-outline-variant/80 cursor-pointer transition-all active:scale-95 shadow-2xs"
598
  >
599
- {copiedCode ? <Check className="w-4 h-4 text-green-500" /> : <Copy className="w-4 h-4 text-primary" />}
600
- {copiedCode ? 'Copied to Clipboard' : 'Copy Code Snippet'}
601
  </button>
602
  </div>
603
 
604
- <div className="bg-[#0a0f1d] text-[#38bdf8] font-mono text-[13px] p-4.5 leading-relaxed overflow-x-auto whitespace-pre-wrap selection:bg-primary/30 selection:text-white">
605
  {selectedThreat.remediation}
606
  </div>
607
  </div>
608
 
609
  {/* Affected Target Endpoints */}
610
  {selectedThreat.affected_targets && selectedThreat.affected_targets.length > 0 && (
611
- <div className="bg-surface-container-lowest p-5 rounded-2xl border border-outline-variant/70 shadow-2xs">
612
- <h3 className="font-bold text-on-surface text-[14.5px] mb-3 flex items-center gap-2">
613
- <ExternalLink className="w-4.5 h-4.5 text-primary" /> Affected Target Endpoints ({selectedThreat.affected_targets.length})
614
  </h3>
615
- <div className="flex flex-wrap gap-2.5">
616
- {selectedThreat.affected_targets.map((url, idx) => (
617
  <a
618
  key={idx}
619
  href={url}
620
  target="_blank"
621
  rel="noopener noreferrer"
622
- className="bg-surface-container border border-outline-variant/80 hover:border-primary/50 text-on-surface font-mono text-[12px] px-3.5 py-2 rounded-xl flex items-center gap-2 font-medium transition-all hover:scale-[1.01]"
623
  >
624
- <span className="w-2 h-2 rounded-full bg-red-500 animate-pulse"></span>
625
  {url}
626
- <ExternalLink className="w-3.5 h-3.5 opacity-50 ml-1" />
627
  </a>
628
  ))}
 
 
 
 
 
629
  </div>
630
  </div>
631
  )}
632
  </div>
633
 
634
- {/* Modal Actions Footer */}
635
- <div className="p-5 bg-surface-container-lowest border-t border-outline-variant/80 flex items-center justify-between flex-wrap gap-3">
636
  <button
637
  onClick={() => {
638
  const query = selectedThreat.title;
639
  setSelectedThreat(null);
640
  openFullLogsView(query);
641
  }}
642
- className="px-5 py-3 bg-primary/10 hover:bg-primary/20 text-primary border border-primary/30 rounded-xl font-bold text-[13.5px] flex items-center gap-2 cursor-pointer transition-all active:scale-95 shadow-2xs"
643
  >
644
- <Search className="w-4.5 h-4.5" />
645
  Filter Audit Logs for this Threat
646
  </button>
647
 
648
  <button
649
  onClick={() => setSelectedThreat(null)}
650
- className="px-7 py-3 bg-primary text-white hover:brightness-110 rounded-xl font-bold text-[13.5px] cursor-pointer border-0 shadow-lg shadow-primary/25 transition-all active:scale-95"
651
  >
652
- Close Diagnostic Window
653
  </button>
654
  </div>
655
  </div>
 
466
  if (!selectedThreat) return null;
467
 
468
  const severityColorMap = {
469
+ critical: { border: 'border-t-red-500', badge: 'bg-red-500/10 text-red-500 border-red-500/30' },
470
+ high: { border: 'border-t-orange-500', badge: 'bg-orange-500/10 text-orange-500 border-orange-500/30' },
471
+ medium: { border: 'border-t-amber-500', badge: 'bg-amber-500/10 text-amber-500 border-amber-500/30' },
472
+ low: { border: 'border-t-blue-500', badge: 'bg-blue-500/10 text-blue-500 border-blue-500/30' },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
473
  };
474
 
475
  const sevKey = (selectedThreat.severity || 'medium').toLowerCase();
476
  const activeSev = severityColorMap[sevKey] || severityColorMap.medium;
477
 
478
  return (
479
+ <div className="fixed inset-0 bg-slate-950/80 backdrop-blur-md flex items-center justify-center p-3 sm:p-4 z-[9999] animate-fade-in">
480
+ <div className={`bg-surface border border-outline-variant/80 rounded-2xl max-w-2xl w-full shadow-2xl relative my-auto overflow-hidden flex flex-col transition-all duration-200 transform animate-in fade-in zoom-in-95 border-t-4 ${activeSev.border}`}>
481
 
482
+ {/* Header Banner */}
483
+ <div className="bg-surface-container-low p-4 sm:p-5 border-b border-outline-variant/70 relative">
484
  <button
485
  onClick={() => setSelectedThreat(null)}
486
+ className="absolute top-4 right-4 text-on-surface-variant hover:text-on-surface bg-surface-container-high p-1.5 rounded-full transition-all cursor-pointer border border-outline-variant/60 hover:scale-105"
487
+ title="Close"
488
  >
489
+ <X className="w-4 h-4" />
490
  </button>
491
 
492
+ <div className="flex items-center gap-2 flex-wrap mb-2 pr-10">
493
+ <span className={`px-2.5 py-0.5 rounded-md text-[10px] font-black uppercase tracking-wider border flex items-center gap-1 ${getSeverityBadgeClass(selectedThreat.severity)}`}>
494
+ <ShieldAlert className="w-3 h-3" />
495
+ {selectedThreat.severity}
496
  </span>
497
+ <span className="bg-cyan-500/10 text-cyan-600 dark:text-cyan-400 text-[10px] font-black px-2.5 py-0.5 rounded-md border border-cyan-500/30 font-mono">
498
  CVSS {selectedThreat.cvss}
499
  </span>
500
+ <span className="bg-red-500/10 text-red-600 dark:text-red-400 text-[10px] font-black px-2.5 py-0.5 rounded-md border border-red-500/30 flex items-center gap-1">
501
+ <span className="w-1.5 h-1.5 rounded-full bg-red-500 animate-pulse"></span>
502
+ {selectedThreat.count} Detections
503
  </span>
504
  </div>
505
 
506
+ <h2 className="text-[18px] sm:text-[20px] font-bold text-on-surface tracking-tight leading-snug font-display">
507
  {selectedThreat.title}
508
  </h2>
509
  </div>
510
 
511
+ {/* Modal Body: Compact Executive 2-Column Layout (No Scroll Required) */}
512
+ <div className="p-4 sm:p-5 space-y-3.5 text-[12.5px] bg-surface">
513
 
514
+ {/* Top Row: Category & OWASP Compact Badges */}
515
+ <div className="grid grid-cols-2 gap-3">
516
+ <div className="bg-surface-container-lowest p-2.5 px-3 rounded-xl border border-outline-variant/60 flex items-center gap-2.5">
517
+ <Layers className="w-4 h-4 text-primary shrink-0" />
518
+ <div className="truncate">
519
+ <span className="text-[10px] font-bold text-on-surface-variant uppercase tracking-wider block leading-none mb-0.5">Category</span>
520
+ <span className="font-bold text-on-surface text-[12.5px] truncate block">{selectedThreat.category}</span>
 
 
 
 
521
  </div>
522
  </div>
523
 
524
+ <div className="bg-surface-container-lowest p-2.5 px-3 rounded-xl border border-outline-variant/60 flex items-center gap-2.5">
525
+ <Shield className="w-4 h-4 text-indigo-500 shrink-0" />
526
+ <div className="truncate">
527
+ <span className="text-[10px] font-bold text-on-surface-variant uppercase tracking-wider block leading-none mb-0.5">OWASP Standard</span>
528
+ <span className="font-bold text-indigo-500 text-[12.5px] truncate block">{selectedThreat.owasp}</span>
 
 
 
 
529
  </div>
530
  </div>
531
  </div>
532
 
533
+ {/* Middle Grid: Overview & Impact */}
534
+ <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
535
+ <div className="bg-surface-container-lowest p-3 rounded-xl border-l-3 border-l-primary border border-outline-variant/60">
536
+ <h3 className="font-bold text-on-surface text-[12px] mb-1 flex items-center gap-1.5">
537
+ <Shield className="w-3.5 h-3.5 text-primary" /> Threat Overview
538
+ </h3>
539
+ <p className="text-on-surface-variant leading-relaxed text-[12px] line-clamp-4">
540
+ {selectedThreat.description}
541
+ </p>
542
+ </div>
543
 
544
+ <div className="bg-surface-container-lowest p-3 rounded-xl border-l-3 border-l-amber-500 border border-outline-variant/60">
545
+ <h3 className="font-bold text-amber-600 dark:text-amber-400 text-[12px] mb-1 flex items-center gap-1.5">
546
+ <AlertTriangle className="w-3.5 h-3.5" /> Exploitation & Impact Risk
547
+ </h3>
548
+ <p className="text-on-surface-variant leading-relaxed text-[12px] line-clamp-4">
549
+ {selectedThreat.impact}
550
+ </p>
551
+ </div>
552
  </div>
553
 
554
+ {/* Code Remediation Terminal Box */}
555
+ <div className="bg-surface-container-lowest rounded-xl border border-outline-variant/60 overflow-hidden">
556
+ <div className="bg-surface-container-high/60 px-3 py-1.5 border-b border-outline-variant/60 flex items-center justify-between">
557
+ <h3 className="font-bold text-on-surface text-[11.5px] flex items-center gap-1.5 font-mono">
558
+ <Terminal className="w-3.5 h-3.5 text-green-500" /> Recommended Remediation
559
+ </h3>
 
 
 
 
 
 
 
560
 
561
  <button
562
  onClick={() => copyToClipboard(selectedThreat.remediation)}
563
+ className="flex items-center gap-1 px-2 py-0.5 bg-surface-container hover:bg-surface-container-highest text-on-surface rounded text-[11px] font-bold border border-outline-variant/70 cursor-pointer transition-all active:scale-95"
564
  >
565
+ {copiedCode ? <Check className="w-3 h-3 text-green-500" /> : <Copy className="w-3 h-3 text-primary" />}
566
+ {copiedCode ? 'Copied' : 'Copy'}
567
  </button>
568
  </div>
569
 
570
+ <div className="bg-[#090d16] text-[#38bdf8] font-mono text-[11.5px] p-2.5 leading-snug overflow-x-auto whitespace-pre-wrap max-h-24">
571
  {selectedThreat.remediation}
572
  </div>
573
  </div>
574
 
575
  {/* Affected Target Endpoints */}
576
  {selectedThreat.affected_targets && selectedThreat.affected_targets.length > 0 && (
577
+ <div className="bg-surface-container-lowest p-2.5 rounded-xl border border-outline-variant/60">
578
+ <h3 className="font-bold text-on-surface text-[11.5px] mb-1.5 flex items-center gap-1.5">
579
+ <ExternalLink className="w-3.5 h-3.5 text-primary" /> Affected Targets ({selectedThreat.affected_targets.length})
580
  </h3>
581
+ <div className="flex flex-wrap gap-1.5">
582
+ {selectedThreat.affected_targets.slice(0, 3).map((url, idx) => (
583
  <a
584
  key={idx}
585
  href={url}
586
  target="_blank"
587
  rel="noopener noreferrer"
588
+ className="bg-surface-container border border-outline-variant/70 hover:border-primary/50 text-on-surface font-mono text-[11px] px-2 py-0.5 rounded-md flex items-center gap-1 transition-all"
589
  >
590
+ <span className="w-1.5 h-1.5 rounded-full bg-red-500"></span>
591
  {url}
 
592
  </a>
593
  ))}
594
+ {selectedThreat.affected_targets.length > 3 && (
595
+ <span className="bg-surface-container text-on-surface-variant font-mono text-[11px] px-2 py-0.5 rounded-md font-bold">
596
+ +{selectedThreat.affected_targets.length - 3} more
597
+ </span>
598
+ )}
599
  </div>
600
  </div>
601
  )}
602
  </div>
603
 
604
+ {/* Compact Actions Footer */}
605
+ <div className="p-3 px-4 bg-surface-container-lowest border-t border-outline-variant/70 flex items-center justify-between flex-wrap gap-2">
606
  <button
607
  onClick={() => {
608
  const query = selectedThreat.title;
609
  setSelectedThreat(null);
610
  openFullLogsView(query);
611
  }}
612
+ className="px-3.5 py-2 bg-primary/10 hover:bg-primary/20 text-primary border border-primary/30 rounded-lg font-bold text-[12px] flex items-center gap-1.5 cursor-pointer transition-all active:scale-95"
613
  >
614
+ <Search className="w-3.5 h-3.5" />
615
  Filter Audit Logs for this Threat
616
  </button>
617
 
618
  <button
619
  onClick={() => setSelectedThreat(null)}
620
+ className="px-5 py-2 bg-primary text-white hover:brightness-110 rounded-lg font-bold text-[12px] cursor-pointer border-0 shadow-md shadow-primary/20 transition-all active:scale-95"
621
  >
622
+ Close
623
  </button>
624
  </div>
625
  </div>